@samitouri / QOSamiQemu / commits / 59970c372c

target/arm: Separate syndrome functions for A32 and A64

Currently we have one syn_fp_access_trap() which we use for fp traps from A64 and from VFP and Neon A32. This means that A64 has to specify arguments that are always fixed for it (coproc and is_16bit) and A32 can't specify arguments it needs to (TA). Split it up into syn_a64_fp_access_trap() and syn_a32_fp_access_trap(). This is a refactor with no behavioural change. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260702184019.3431139-3-peter.maydell@linaro.org

Peter Maydell committed Jul 2, 2026 at 19:40 UTC 59970c372c410d6d57d4b158f88e7bc56f170234
3 files changed +24 -8
target/arm/syndrome.h
+22 -6
@@ -345,21 +345,37 @@ static inline uint32_t syn_cp15_rrt_trap(int cv, int cond, int opc1, int crm,
345
346 /*
347 * ISS encoding for an exception from an access to a register of
348 - * instruction resulting from the FPEN or TFP traps.
348 + * instruction resulting from the FPEN or TFP traps. Note that
349 + * the TA and COPROC fields are only valid when an AArch32 insn
350 + * traps to AArch32 EL2; they are RES0 for traps to AArch64.
351 */
350 -FIELD(FP_ISS, COPROC, 0, 4) /* ARMv7 only */
352 +FIELD(FP_ISS, COPROC, 0, 4)
353 +FIELD(FP_ISS, TA, 5, 1)
354 FIELD(FP_ISS, COND, 20, 4)
355 FIELD(FP_ISS, CV, 24, 1)
356
354 -static inline uint32_t syn_fp_access_trap(int cv, int cond, bool is_16bit,
355 - int coproc)
357 +static inline uint32_t syn_a64_fp_access_trap(int cv, int cond)
358 {
357 - /* AArch32 FP trap or any AArch64 FP/SIMD trap: TA == 0 */
359 + /* AArch64 FP/SIMD trap: TA and coproc are RES0, insn is 64 bits */
360 uint32_t res = syn_set_ec(0, EC_ADVSIMDFPACCESSTRAP);
359 - res = FIELD_DP32(res, SYNDROME, IL, !is_16bit);
361 + res = FIELD_DP32(res, SYNDROME, IL, 1);
362 +
363 + res = FIELD_DP32(res, FP_ISS, CV, cv);
364 + res = FIELD_DP32(res, FP_ISS, COND, cond);
365 +
366 + return res;
367 +}
368 +
369 +static inline uint32_t syn_a32_fp_access_trap(int cv, int cond,
370 + int ta, int coproc)
371 +{
372 + /* AArch32 VFP or Neon trap: TA and coproc valid, insn is 64 bits */
373 + uint32_t res = syn_set_ec(0, EC_ADVSIMDFPACCESSTRAP);
374 + res = FIELD_DP32(res, SYNDROME, IL, 1);
375
376 res = FIELD_DP32(res, FP_ISS, CV, cv);
377 res = FIELD_DP32(res, FP_ISS, COND, cond);
378 + res = FIELD_DP32(res, FP_ISS, TA, ta);
379 res = FIELD_DP32(res, FP_ISS, COPROC, coproc);
380
381 return res;
target/arm/tcg/translate-a64.c
+1 -1
@@ -1439,7 +1439,7 @@ static bool fp_access_check_only(DisasContext *s)
1439 s->fp_access_checked = -1;
1440
1441 gen_exception_insn_el(s, 0, EXCP_UDEF,
1442 - syn_fp_access_trap(1, 0xe, false, 0),
1442 + syn_a64_fp_access_trap(1, 0xe),
1443 s->fp_excp_el);
1444 return false;
1445 }
target/arm/tcg/translate-vfp.c
+1 -1
@@ -228,7 +228,7 @@ static bool vfp_access_check_a(DisasContext *s, bool ignore_vfp_enabled)
228 * this field to 0xA.
229 */
230 int coproc = arm_dc_feature(s, ARM_FEATURE_V8) ? 0 : 0xa;
231 - uint32_t syn = syn_fp_access_trap(1, 0xe, false, coproc);
231 + uint32_t syn = syn_a32_fp_access_trap(1, 0xe, 0, coproc);
232
233 gen_exception_insn_el(s, 0, EXCP_UDEF, syn, s->fp_excp_el);
234 return false;