summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--target/arm/translate-vfp.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c
index 2e12c694ed..01e26a246d 100644
--- a/target/arm/translate-vfp.c
+++ b/target/arm/translate-vfp.c
@@ -143,11 +143,21 @@ static void gen_preserve_fp_state(DisasContext *s)
static bool full_vfp_access_check(DisasContext *s, bool ignore_vfp_enabled)
{
if (s->fp_excp_el) {
- /* M-profile handled this earlier, in disas_m_nocp() */
- assert (!arm_dc_feature(s, ARM_FEATURE_M));
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
- syn_fp_access_trap(1, 0xe, false),
- s->fp_excp_el);
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
+ /*
+ * M-profile mostly catches the "FPU disabled" case early, in
+ * disas_m_nocp(), but a few insns (eg LCTP, WLSTP, DLSTP)
+ * which do coprocessor-checks are outside the large ranges of
+ * the encoding space handled by the patterns in m-nocp.decode,
+ * and for them we may need to raise NOCP here.
+ */
+ gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
+ syn_uncategorized(), s->fp_excp_el);
+ } else {
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
+ syn_fp_access_trap(1, 0xe, false),
+ s->fp_excp_el);
+ }
return false;
}