diff options
Diffstat (limited to 'target')
-rw-r--r-- | target/arm/translate-vfp.c | 20 |
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; } |