@samitouri / QOSamiQemu / commits / cc04352a1f

target/arm: Add FPMR_EL to TBFLAGS

Prepare to perform access checks for direct and indirect uses of FPMR. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260522220306.235200-13-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Richard Henderson committed May 22, 2026 at 15:02 UTC cc04352a1f100c64d0a467bc678cae16713da4b8
4 files changed +46
target/arm/cpu.h
+1
@@ -2567,6 +2567,7 @@ FIELD(TBFLAG_A64, ZT0EXC_EL, 39, 2)
2567 FIELD(TBFLAG_A64, GCS_EN, 41, 1)
2568 FIELD(TBFLAG_A64, GCS_RVCEN, 42, 1)
2569 FIELD(TBFLAG_A64, GCSSTR_EL, 43, 2)
2570 +FIELD(TBFLAG_A64, FPMR_EL, 45, 2)
2571
2572 /*
2573 * Helpers for using the above. Note that only the A64 accessors use
target/arm/tcg/hflags.c
+42
@@ -237,6 +237,44 @@ static int zt0_exception_el(CPUARMState *env, int el)
237 return 0;
238 }
239
240 +/*
241 + * Return the exception level to which exceptions should be taken for FPMR.
242 + * Compare the EnFPM bits in the "Accessing FPMR" pseudocode. Note that
243 + * the floating-point enabled check will be handled separately.
244 + */
245 +static int fpmr_exception_el(CPUARMState *env, int el)
246 +{
247 + switch (el) {
248 + case 0:
249 + if (el_is_in_host(env, 0)) {
250 + if (!(env->cp15.sctlr_el[2] & SCTLR_EnFPM)) {
251 + return 2;
252 + }
253 + break;
254 + }
255 + if (!(env->cp15.sctlr_el[1] & SCTLR_EnFPM)) {
256 + return 1;
257 + }
258 + /* fall through */
259 + case 1:
260 + if (!(arm_hcrx_el2_eff(env) & HCRX_ENFPM)) {
261 + return 2;
262 + }
263 + break;
264 + case 2:
265 + break;
266 + case 3:
267 + return 0;
268 + default:
269 + g_assert_not_reached();
270 + }
271 + if (arm_feature(env, ARM_FEATURE_EL3)
272 + && !(env->cp15.scr_el3 & SCR_ENFPM)) {
273 + return 3;
274 + }
275 + return 0;
276 +}
277 +
278 static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
279 ARMMMUIdx mmu_idx)
280 {
@@ -500,6 +538,10 @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
538 }
539 }
540
541 + if (cpu_isar_feature(aa64_fpmr, env_archcpu(env))) {
542 + DP_TBFLAG_A64(flags, FPMR_EL, fpmr_exception_el(env, el));
543 + }
544 +
545 return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
546 }
547
target/arm/tcg/translate-a64.c
+1
@@ -10723,6 +10723,7 @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
10723 dc->gcs_en = EX_TBFLAG_A64(tb_flags, GCS_EN);
10724 dc->gcs_rvcen = EX_TBFLAG_A64(tb_flags, GCS_RVCEN);
10725 dc->gcsstr_el = EX_TBFLAG_A64(tb_flags, GCSSTR_EL);
10726 + dc->fpmr_el = EX_TBFLAG_A64(tb_flags, FPMR_EL);
10727 dc->vec_len = 0;
10728 dc->vec_stride = 0;
10729 dc->cp_regs = arm_cpu->cp_regs;
target/arm/tcg/translate.h
+2
@@ -199,6 +199,8 @@ typedef struct DisasContext {
199 uint8_t gm_blocksize;
200 /* True if the current insn_start has been updated. */
201 bool insn_start_updated;
202 + /* FPMR access exception EL or 0 if enabled. */
203 + uint8_t fpmr_el;
204 /* Offset from VNCR_EL2 when FEAT_NV2 redirects this reg to memory */
205 uint32_t nv2_redirect_offset;
206 } DisasContext;