diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2019-04-29 17:35:59 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2019-04-29 17:35:59 +0100 |
commit | 8859ba3c9625e7ceb5599f457a344bcd7c5e112b (patch) | |
tree | 0894e5074370823728247fdffb2f4257b961becf | |
parent | d87513c0abcbcd856f8e1dee2f2d18903b2c3ea2 (diff) | |
download | qemu-8859ba3c9625e7ceb5599f457a344bcd7c5e112b.zip |
target/arm: Decode FP instructions for M profile
Correct the decode of the M-profile "coprocessor and
floating-point instructions" space:
* op0 == 0b11 is always unallocated
* if the CPU has an FPU then all insns with op1 == 0b101
are floating point and go to disas_vfp_insn()
For the moment we leave VLLDM and VLSTM as NOPs; in
a later commit we will fill in the proper implementation
for the case where an FPU is present.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20190416125744.27770-7-peter.maydell@linaro.org
-rw-r--r-- | target/arm/translate.c | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/target/arm/translate.c b/target/arm/translate.c index 6a11921d0b..0747f7847a 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -11728,10 +11728,19 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn) case 6: case 7: case 14: case 15: /* Coprocessor. */ if (arm_dc_feature(s, ARM_FEATURE_M)) { - /* We don't currently implement M profile FP support, - * so this entire space should give a NOCP fault, with - * the exception of the v8M VLLDM and VLSTM insns, which - * must be NOPs in Secure state and UNDEF in Nonsecure state. + /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */ + if (extract32(insn, 24, 2) == 3) { + goto illegal_op; /* op0 = 0b11 : unallocated */ + } + + /* + * Decode VLLDM and VLSTM first: these are nonstandard because: + * * if there is no FPU then these insns must NOP in + * Secure state and UNDEF in Nonsecure state + * * if there is an FPU then these insns do not have + * the usual behaviour that disas_vfp_insn() provides of + * being controlled by CPACR/NSACR enable bits or the + * lazy-stacking logic. */ if (arm_dc_feature(s, ARM_FEATURE_V8) && (insn & 0xffa00f00) == 0xec200a00) { @@ -11745,6 +11754,15 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn) /* Just NOP since FP support is not implemented */ break; } + if (arm_dc_feature(s, ARM_FEATURE_VFP) && + ((insn >> 8) & 0xe) == 10) { + /* FP, and the CPU supports it */ + if (disas_vfp_insn(s, insn)) { + goto illegal_op; + } + break; + } + /* All other insns: NOCP */ gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(), default_exception_el(s)); |