summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2019-04-29 17:35:59 +0100
committerPeter Maydell <peter.maydell@linaro.org>2019-04-29 17:35:59 +0100
commit8859ba3c9625e7ceb5599f457a344bcd7c5e112b (patch)
tree0894e5074370823728247fdffb2f4257b961becf
parentd87513c0abcbcd856f8e1dee2f2d18903b2c3ea2 (diff)
downloadqemu-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.c26
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));