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 <[email protected]> Reviewed-by: Richard Henderson <[email protected]> Message-id: [email protected] --- target/arm/syndrome.h | 28 ++++++++++++++++++++++------ target/arm/tcg/translate-a64.c | 2 +- target/arm/tcg/translate-vfp.c | 2 +- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h index 0eb54c15ce..2a6fa903f2 100644 --- a/target/arm/syndrome.h +++ b/target/arm/syndrome.h @@ -345,21 +345,37 @@ static inline uint32_t syn_cp15_rrt_trap(int cv, int cond, int opc1, int crm, /* * ISS encoding for an exception from an access to a register of - * instruction resulting from the FPEN or TFP traps. + * instruction resulting from the FPEN or TFP traps. Note that + * the TA and COPROC fields are only valid when an AArch32 insn + * traps to AArch32 EL2; they are RES0 for traps to AArch64. */ -FIELD(FP_ISS, COPROC, 0, 4) /* ARMv7 only */ +FIELD(FP_ISS, COPROC, 0, 4) +FIELD(FP_ISS, TA, 5, 1) FIELD(FP_ISS, COND, 20, 4) FIELD(FP_ISS, CV, 24, 1) -static inline uint32_t syn_fp_access_trap(int cv, int cond, bool is_16bit, - int coproc) +static inline uint32_t syn_a64_fp_access_trap(int cv, int cond) { - /* AArch32 FP trap or any AArch64 FP/SIMD trap: TA == 0 */ + /* AArch64 FP/SIMD trap: TA and coproc are RES0, insn is 64 bits */ uint32_t res = syn_set_ec(0, EC_ADVSIMDFPACCESSTRAP); - res = FIELD_DP32(res, SYNDROME, IL, !is_16bit); + res = FIELD_DP32(res, SYNDROME, IL, 1); res = FIELD_DP32(res, FP_ISS, CV, cv); res = FIELD_DP32(res, FP_ISS, COND, cond); + + return res; +} + +static inline uint32_t syn_a32_fp_access_trap(int cv, int cond, + int ta, int coproc) +{ + /* AArch32 VFP or Neon trap: TA and coproc valid, insn is 64 bits */ + uint32_t res = syn_set_ec(0, EC_ADVSIMDFPACCESSTRAP); + res = FIELD_DP32(res, SYNDROME, IL, 1); + + res = FIELD_DP32(res, FP_ISS, CV, cv); + res = FIELD_DP32(res, FP_ISS, COND, cond); + res = FIELD_DP32(res, FP_ISS, TA, ta); res = FIELD_DP32(res, FP_ISS, COPROC, coproc); return res; diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c index 69648ad94b..1780490065 100644 --- a/target/arm/tcg/translate-a64.c +++ b/target/arm/tcg/translate-a64.c @@ -1439,7 +1439,7 @@ static bool fp_access_check_only(DisasContext *s) s->fp_access_checked = -1; gen_exception_insn_el(s, 0, EXCP_UDEF, - syn_fp_access_trap(1, 0xe, false, 0), + syn_a64_fp_access_trap(1, 0xe), s->fp_excp_el); return false; } diff --git a/target/arm/tcg/translate-vfp.c b/target/arm/tcg/translate-vfp.c index 6f6b234c9a..7474973952 100644 --- a/target/arm/tcg/translate-vfp.c +++ b/target/arm/tcg/translate-vfp.c @@ -228,7 +228,7 @@ static bool vfp_access_check_a(DisasContext *s, bool ignore_vfp_enabled) * this field to 0xA. */ int coproc = arm_dc_feature(s, ARM_FEATURE_V8) ? 0 : 0xa; - uint32_t syn = syn_fp_access_trap(1, 0xe, false, coproc); + uint32_t syn = syn_a32_fp_access_trap(1, 0xe, 0, coproc); gen_exception_insn_el(s, 0, EXCP_UDEF, syn, s->fp_excp_el); return false; -- 2.43.0
