diff options
Diffstat (limited to 'target')
-rw-r--r-- | target/arm/tcg/translate-a64.c | 17 | ||||
-rw-r--r-- | target/arm/tcg/translate-a64.h | 2 | ||||
-rw-r--r-- | target/arm/tcg/translate.h | 10 |
3 files changed, 17 insertions, 12 deletions
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c index 8bef391..48e0ac7 100644 --- a/target/arm/tcg/translate-a64.c +++ b/target/arm/tcg/translate-a64.c @@ -1381,14 +1381,14 @@ static bool fp_access_check_only(DisasContext *s) { if (s->fp_excp_el) { assert(!s->fp_access_checked); - s->fp_access_checked = true; + s->fp_access_checked = -1; gen_exception_insn_el(s, 0, EXCP_UDEF, syn_fp_access_trap(1, 0xe, false, 0), s->fp_excp_el); return false; } - s->fp_access_checked = true; + s->fp_access_checked = 1; return true; } @@ -1465,13 +1465,13 @@ bool sve_access_check(DisasContext *s) syn_sve_access_trap(), s->sve_excp_el); goto fail_exit; } - s->sve_access_checked = true; + s->sve_access_checked = 1; return fp_access_check(s); fail_exit: /* Assert that we only raise one exception per instruction. */ assert(!s->sve_access_checked); - s->sve_access_checked = true; + s->sve_access_checked = -1; return false; } @@ -1500,8 +1500,9 @@ bool sme_enabled_check(DisasContext *s) * sme_excp_el by itself for cpregs access checks. */ if (!s->fp_excp_el || s->sme_excp_el < s->fp_excp_el) { - s->fp_access_checked = true; - return sme_access_check(s); + bool ret = sme_access_check(s); + s->fp_access_checked = (ret ? 1 : -1); + return ret; } return fp_access_check_only(s); } @@ -10257,8 +10258,8 @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) s->insn = insn; s->base.pc_next = pc + 4; - s->fp_access_checked = false; - s->sve_access_checked = false; + s->fp_access_checked = 0; + s->sve_access_checked = 0; if (s->pstate_il) { /* diff --git a/target/arm/tcg/translate-a64.h b/target/arm/tcg/translate-a64.h index 7d3b59c..b2420f5 100644 --- a/target/arm/tcg/translate-a64.h +++ b/target/arm/tcg/translate-a64.h @@ -65,7 +65,7 @@ TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write, static inline void assert_fp_access_checked(DisasContext *s) { #ifdef CONFIG_DEBUG_TCG - if (unlikely(!s->fp_access_checked || s->fp_excp_el)) { + if (unlikely(s->fp_access_checked <= 0)) { fprintf(stderr, "target-arm: FP access check missing for " "instruction 0x%08x\n", s->insn); abort(); diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h index f8dc2f0..53e485d 100644 --- a/target/arm/tcg/translate.h +++ b/target/arm/tcg/translate.h @@ -92,15 +92,19 @@ typedef struct DisasContext { bool aarch64; bool thumb; bool lse2; - /* Because unallocated encodings generate different exception syndrome + /* + * Because unallocated encodings generate different exception syndrome * information from traps due to FP being disabled, we can't do a single * "is fp access disabled" check at a high level in the decode tree. * To help in catching bugs where the access check was forgotten in some * code path, we set this flag when the access check is done, and assert * that it is set at the point where we actually touch the FP regs. + * 0: not checked, + * 1: checked, access ok + * -1: checked, access denied */ - bool fp_access_checked; - bool sve_access_checked; + int8_t fp_access_checked; + int8_t sve_access_checked; /* ARMv8 single-step state (this is distinct from the QEMU gdbstub * single-step support). */ |