diff mbox series

[v2,03/25] target/arm: Move fp access syndrome adjust out of raise_exception

Message ID 20220607024734.541321-4-richard.henderson@linaro.org
State New
Headers show
Series target/arm: tidy exception routing | expand

Commit Message

Richard Henderson June 7, 2022, 2:47 a.m. UTC
Create helper_exception_advsimdfp_access to handle both
the routing and the syndrome contents, depending on the
eventual target EL and mode.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/helper.h        |  1 +
 target/arm/translate.h     |  9 +++++++++
 target/arm/op_helper.c     | 32 +++++++++++++++++++++++---------
 target/arm/translate-a64.c |  5 ++---
 target/arm/translate-vfp.c |  4 +++-
 5 files changed, 38 insertions(+), 13 deletions(-)

Comments

Peter Maydell June 9, 2022, 3:59 p.m. UTC | #1
On Tue, 7 Jun 2022 at 03:50, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Create helper_exception_advsimdfp_access to handle both
> the routing and the syndrome contents, depending on the
> eventual target EL and mode.

Bit awkward to have "TGE means go to EL2, not EL1" in two places
now, but I'm going to assume that either (a) this gets cleaned up
later in the series or (b) that it's the least-worst option, so

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM
Richard Henderson June 9, 2022, 5:09 p.m. UTC | #2
On 6/9/22 08:59, Peter Maydell wrote:
> On Tue, 7 Jun 2022 at 03:50, Richard Henderson
> <richard.henderson@linaro.org> wrote:
>>
>> Create helper_exception_advsimdfp_access to handle both
>> the routing and the syndrome contents, depending on the
>> eventual target EL and mode.
> 
> Bit awkward to have "TGE means go to EL2, not EL1" in two places
> now, but I'm going to assume that either (a) this gets cleaned up
> later in the series or (b) that it's the least-worst option, so

Hmm, well.  I had planned for it to go away from within raise_exception later in the 
series, but it didn't work out, so I could drop this.


r~
diff mbox series

Patch

diff --git a/target/arm/helper.h b/target/arm/helper.h
index 5161cdf73d..a13007699d 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -46,6 +46,7 @@  DEF_HELPER_FLAGS_3(sel_flags, TCG_CALL_NO_RWG_SE,
                    i32, i32, i32, i32)
 DEF_HELPER_2(exception_internal, noreturn, env, i32)
 DEF_HELPER_4(exception_with_syndrome, noreturn, env, i32, i32, i32)
+DEF_HELPER_3(exception_advsimdfp_access, noreturn, env, i32, i32)
 DEF_HELPER_2(exception_bkpt_insn, noreturn, env, i32)
 DEF_HELPER_2(exception_pc_alignment, noreturn, env, tl)
 DEF_HELPER_1(setend, void, env)
diff --git a/target/arm/translate.h b/target/arm/translate.h
index 9f0bb270c5..da5f89d49d 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -337,6 +337,15 @@  static inline void gen_exception(int excp, uint32_t syndrome,
                                        tcg_constant_i32(target_el));
 }
 
+static inline void gen_exception_advsimdfp_access(DisasContext *s,
+                                                  uint32_t syndrome)
+{
+    gen_helper_exception_advsimdfp_access(cpu_env,
+                                          tcg_constant_i32(syndrome),
+                                          tcg_constant_i32(s->fp_excp_el));
+    s->base.is_jmp = DISAS_NORETURN;
+}
+
 /* Generate an architectural singlestep exception */
 static inline void gen_swstep_exception(DisasContext *s, int isv, int ex)
 {
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
index c4bd668870..67b7dbeaa9 100644
--- a/target/arm/op_helper.c
+++ b/target/arm/op_helper.c
@@ -34,16 +34,8 @@  void raise_exception(CPUARMState *env, uint32_t excp,
     CPUState *cs = env_cpu(env);
 
     if (target_el == 1 && (arm_hcr_el2_eff(env) & HCR_TGE)) {
-        /*
-         * Redirect NS EL1 exceptions to NS EL2. These are reported with
-         * their original syndrome register value, with the exception of
-         * SIMD/FP access traps, which are reported as uncategorized
-         * (see DDI0478C.a D1.10.4)
-         */
+        /* Redirect NS EL1 exceptions to NS EL2. */
         target_el = 2;
-        if (syn_get_ec(syndrome) == EC_ADVSIMDFPACCESSTRAP) {
-            syndrome = syn_uncategorized();
-        }
     }
 
     assert(!excp_is_internal(excp));
@@ -384,6 +376,28 @@  void HELPER(exception_with_syndrome)(CPUARMState *env, uint32_t excp,
     raise_exception(env, excp, syndrome, target_el);
 }
 
+/* Raise an exception with EC_ADVSIMDFPACCESS. */
+void HELPER(exception_advsimdfp_access)(CPUARMState *env,
+                                        uint32_t syndrome, uint32_t target_el)
+{
+    if (target_el == 1 && (arm_hcr_el2_eff(env) & HCR_TGE)) {
+        /*
+         * SIMD/FP access traps, when re-routed to EL2, are reported with
+         * uncategorized syndrome.  See DDI0487H.a rule RJNBTN.
+         */
+        target_el = 2;
+        syndrome = syn_uncategorized();
+    } else if (arm_el_is_aa64(env, target_el)) {
+        /*
+         * From AArch32, we will have filled in TA and/or COPROC for use
+         * by aa32 HSR.  But in aa64 ESR_ELx, the low 20 bits are RES0.
+         */
+        syndrome &= 0xfff00000;
+    }
+
+    raise_exception(env, EXCP_UDEF, syndrome, target_el);
+}
+
 /* Raise an EXCP_BKPT with the specified syndrome register value,
  * targeting the correct exception level for debug exceptions.
  */
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 14b90a37ea..3251c69180 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -1161,9 +1161,8 @@  static bool fp_access_check(DisasContext *s)
         assert(!s->fp_access_checked);
         s->fp_access_checked = true;
 
-        gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
-                           syn_fp_access_trap(1, 0xe, false, 0),
-                           s->fp_excp_el);
+        gen_a64_set_pc_im(s->pc_curr);
+        gen_exception_advsimdfp_access(s, syn_fp_access_trap(1, 0xe, false, 0));
         return false;
     }
     s->fp_access_checked = true;
diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c
index 0f797c56fd..2a98387411 100644
--- a/target/arm/translate-vfp.c
+++ b/target/arm/translate-vfp.c
@@ -230,7 +230,9 @@  static bool vfp_access_check_a(DisasContext *s, bool ignore_vfp_enabled)
         int coproc = arm_dc_feature(s, ARM_FEATURE_V8) ? 0 : 0xa;
         uint32_t syn = syn_fp_access_trap(1, 0xe, false, coproc);
 
-        gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn, s->fp_excp_el);
+        gen_set_condexec(s);
+        gen_set_pc_im(s, s->pc_curr);
+        gen_exception_advsimdfp_access(s, syn);
         return false;
     }