diff mbox series

[05/55] target/arm: Let vfp_access_check() handle late NOCP checks

Message ID 20210607165821.9892-6-peter.maydell@linaro.org
State Superseded
Headers show
Series target/arm: First slice of MVE implementation | expand

Commit Message

Peter Maydell June 7, 2021, 4:57 p.m. UTC
In commit a3494d4671797c we reworked the M-profile handling of its
checks for when the NOCP exception should be raised because the FPU
is disabled, so that (in line with the architecture) the NOCP check
is done early over a large range of the encoding space, and takes
precedence over UNDEF exceptions.  As part of this, we removed the
code from full_vfp_access_check() which raised an exception there for
M-profile with the FPU disabled, because it was no longer reachable.

For MVE, some instructions which are outside the "coprocessor space"
region of the encoding space must nonetheless do "is the FPU enabled"
checks and possibly raise a NOCP exception.  (In particular this
covers the MVE-specific low-overhead branch insns LCTP, DLSTP and
WLSTP.) To support these insns, reinstate the code in
full_vfp_access_check(), so that their trans functions can call
vfp_access_check() and get the correct behaviour.

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

---
 target/arm/translate-vfp.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

-- 
2.20.1

Comments

Richard Henderson June 7, 2021, 11:50 p.m. UTC | #1
On 6/7/21 9:57 AM, Peter Maydell wrote:
> In commit a3494d4671797c we reworked the M-profile handling of its

> checks for when the NOCP exception should be raised because the FPU

> is disabled, so that (in line with the architecture) the NOCP check

> is done early over a large range of the encoding space, and takes

> precedence over UNDEF exceptions.  As part of this, we removed the

> code from full_vfp_access_check() which raised an exception there for

> M-profile with the FPU disabled, because it was no longer reachable.

> 

> For MVE, some instructions which are outside the "coprocessor space"

> region of the encoding space must nonetheless do "is the FPU enabled"

> checks and possibly raise a NOCP exception.  (In particular this

> covers the MVE-specific low-overhead branch insns LCTP, DLSTP and

> WLSTP.) To support these insns, reinstate the code in

> full_vfp_access_check(), so that their trans functions can call

> vfp_access_check() and get the correct behaviour.

> 

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

> ---

>   target/arm/translate-vfp.c | 20 +++++++++++++++-----

>   1 file changed, 15 insertions(+), 5 deletions(-)


Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~
diff mbox series

Patch

diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c
index 3a56639e708..6a572591ce9 100644
--- a/target/arm/translate-vfp.c
+++ b/target/arm/translate-vfp.c
@@ -143,11 +143,21 @@  static void gen_preserve_fp_state(DisasContext *s)
 static bool full_vfp_access_check(DisasContext *s, bool ignore_vfp_enabled)
 {
     if (s->fp_excp_el) {
-        /* M-profile handled this earlier, in disas_m_nocp() */
-        assert (!arm_dc_feature(s, ARM_FEATURE_M));
-        gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
-                           syn_fp_access_trap(1, 0xe, false),
-                           s->fp_excp_el);
+        if (arm_dc_feature(s, ARM_FEATURE_M)) {
+            /*
+             * M-profile mostly catches the "FPU disabled" case early, in
+             * disas_m_nocp(), but a few insns (eg LCTP, WLSTP, DLSTP)
+             * which do coprocessor-checks are outside the large ranges of
+             * the encoding space handled by the patterns in m-nocp.decode,
+             * and for them we may need to raise NOCP here.
+             */
+            gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
+                               syn_uncategorized(), s->fp_excp_el);
+        } else {
+            gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
+                               syn_fp_access_trap(1, 0xe, false),
+                               s->fp_excp_el);
+        }
         return false;
     }