qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v3 0/5] target/arm: Preparatory work for SVE
@ 2018-01-23  3:53 Richard Henderson
  2018-01-23  3:53 ` [Qemu-devel] [PATCH v3 1/5] target/arm: Expand vector registers " Richard Henderson
                   ` (5 more replies)
  0 siblings, 6 replies; 16+ messages in thread
From: Richard Henderson @ 2018-01-23  3:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, alex.bennee

Based on PMM's target-arm.next branch, which now has most of v2.

While looking again at ZCR_ELx, I think that there's an existing
bug in the FPCR/FPSR system registers, wherein we do not have an
access function for when the FPU is disabled.


r~


Richard Henderson (5):
  target/arm: Expand vector registers for SVE
  target/arm: Add predicate registers for SVE
  target/arm: Add SVE to migration state
  target/arm: Add ZCR_ELx
  target/arm: Add SVE state to TB->FLAGS

 target/arm/cpu.h           |  84 ++++++++++++++++++------
 target/arm/translate.h     |   2 +
 target/arm/helper.c        | 156 ++++++++++++++++++++++++++++++++++++++++++++-
 target/arm/machine.c       |  88 ++++++++++++++++++++++++-
 target/arm/translate-a64.c |  10 +--
 target/arm/translate.c     |   7 +-
 6 files changed, 318 insertions(+), 29 deletions(-)

-- 
2.14.3

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [Qemu-devel] [PATCH v3 1/5] target/arm: Expand vector registers for SVE
  2018-01-23  3:53 [Qemu-devel] [PATCH v3 0/5] target/arm: Preparatory work for SVE Richard Henderson
@ 2018-01-23  3:53 ` Richard Henderson
  2018-01-29 17:30   ` Peter Maydell
  2018-01-23  3:53 ` [Qemu-devel] [PATCH v3 2/5] target/arm: Add predicate " Richard Henderson
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 16+ messages in thread
From: Richard Henderson @ 2018-01-23  3:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, alex.bennee

Change vfp.regs as a uint64_t to vfp.zregs as an ARMVectorReg.
The previous patches have made the change in representation
relatively painless.

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/cpu.h           | 59 +++++++++++++++++++++++++++++++---------------
 target/arm/machine.c       | 35 ++++++++++++++++++++++++++-
 target/arm/translate-a64.c |  8 +++----
 target/arm/translate.c     |  7 +++---
 4 files changed, 81 insertions(+), 28 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index d2bb59eded..1854fe51a8 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -153,6 +153,42 @@ typedef struct {
     uint32_t base_mask;
 } TCR;
 
+/* Define a maximum sized vector register.
+ * For 32-bit, this is a 128-bit NEON/AdvSIMD register.
+ * For 64-bit, this is a 2048-bit SVE register.
+ *
+ * Note that the mapping between S, D, and Q views of the register bank
+ * differs between AArch64 and AArch32.
+ * In AArch32:
+ *  Qn = regs[n].d[1]:regs[n].d[0]
+ *  Dn = regs[n / 2].d[n & 1]
+ *  Sn = regs[n / 4].d[n % 4 / 2],
+ *       bits 31..0 for even n, and bits 63..32 for odd n
+ *       (and regs[16] to regs[31] are inaccessible)
+ * In AArch64:
+ *  Zn = regs[n].d[*]
+ *  Qn = regs[n].d[1]:regs[n].d[0]
+ *  Dn = regs[n].d[0]
+ *  Sn = regs[n].d[0] bits 31..0
+ *
+ * This corresponds to the architecturally defined mapping between
+ * the two execution states, and means we do not need to explicitly
+ * map these registers when changing states.
+ *
+ * Align the data for use with TCG host vector operations.
+ */
+
+#ifdef TARGET_AARCH64
+# define ARM_MAX_VQ    16
+#else
+# define ARM_MAX_VQ    1
+#endif
+
+typedef struct ARMVectorReg {
+    uint64_t d[2 * ARM_MAX_VQ] QEMU_ALIGNED(16);
+} ARMVectorReg;
+
+
 typedef struct CPUARMState {
     /* Regs for current mode.  */
     uint32_t regs[16];
@@ -477,22 +513,7 @@ typedef struct CPUARMState {
 
     /* VFP coprocessor state.  */
     struct {
-        /* VFP/Neon register state. Note that the mapping between S, D and Q
-         * views of the register bank differs between AArch64 and AArch32:
-         * In AArch32:
-         *  Qn = regs[2n+1]:regs[2n]
-         *  Dn = regs[n]
-         *  Sn = regs[n/2] bits 31..0 for even n, and bits 63..32 for odd n
-         * (and regs[32] to regs[63] are inaccessible)
-         * In AArch64:
-         *  Qn = regs[2n+1]:regs[2n]
-         *  Dn = regs[2n]
-         *  Sn = regs[2n] bits 31..0
-         * This corresponds to the architecturally defined mapping between
-         * the two execution states, and means we do not need to explicitly
-         * map these registers when changing states.
-         */
-        uint64_t regs[64];
+        ARMVectorReg zregs[32];
 
         uint32_t xregs[16];
         /* We store these fpcsr fields separately for convenience.  */
@@ -2769,7 +2790,7 @@ static inline void *arm_get_el_change_hook_opaque(ARMCPU *cpu)
  */
 static inline uint64_t *aa32_vfp_dreg(CPUARMState *env, unsigned regno)
 {
-    return &env->vfp.regs[regno];
+    return &env->vfp.zregs[regno >> 1].d[regno & 1];
 }
 
 /**
@@ -2778,7 +2799,7 @@ static inline uint64_t *aa32_vfp_dreg(CPUARMState *env, unsigned regno)
  */
 static inline uint64_t *aa32_vfp_qreg(CPUARMState *env, unsigned regno)
 {
-    return &env->vfp.regs[2 * regno];
+    return &env->vfp.zregs[regno].d[0];
 }
 
 /**
@@ -2787,7 +2808,7 @@ static inline uint64_t *aa32_vfp_qreg(CPUARMState *env, unsigned regno)
  */
 static inline uint64_t *aa64_vfp_qreg(CPUARMState *env, unsigned regno)
 {
-    return &env->vfp.regs[2 * regno];
+    return &env->vfp.zregs[regno].d[0];
 }
 
 #endif
diff --git a/target/arm/machine.c b/target/arm/machine.c
index a85c2430d3..cb0e1c92bb 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -50,7 +50,40 @@ static const VMStateDescription vmstate_vfp = {
     .minimum_version_id = 3,
     .needed = vfp_needed,
     .fields = (VMStateField[]) {
-        VMSTATE_UINT64_ARRAY(env.vfp.regs, ARMCPU, 64),
+        /* For compatibility, store Qn out of Zn here.  */
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[0].d, ARMCPU, 0, 2),
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[1].d, ARMCPU, 0, 2),
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[2].d, ARMCPU, 0, 2),
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[3].d, ARMCPU, 0, 2),
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[4].d, ARMCPU, 0, 2),
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[5].d, ARMCPU, 0, 2),
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[6].d, ARMCPU, 0, 2),
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[7].d, ARMCPU, 0, 2),
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[8].d, ARMCPU, 0, 2),
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[9].d, ARMCPU, 0, 2),
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[10].d, ARMCPU, 0, 2),
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[11].d, ARMCPU, 0, 2),
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[12].d, ARMCPU, 0, 2),
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[13].d, ARMCPU, 0, 2),
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[14].d, ARMCPU, 0, 2),
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[15].d, ARMCPU, 0, 2),
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[16].d, ARMCPU, 0, 2),
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[17].d, ARMCPU, 0, 2),
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[18].d, ARMCPU, 0, 2),
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[19].d, ARMCPU, 0, 2),
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[20].d, ARMCPU, 0, 2),
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[21].d, ARMCPU, 0, 2),
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[22].d, ARMCPU, 0, 2),
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[23].d, ARMCPU, 0, 2),
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[24].d, ARMCPU, 0, 2),
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[25].d, ARMCPU, 0, 2),
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[26].d, ARMCPU, 0, 2),
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[27].d, ARMCPU, 0, 2),
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[28].d, ARMCPU, 0, 2),
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[29].d, ARMCPU, 0, 2),
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[30].d, ARMCPU, 0, 2),
+        VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[31].d, ARMCPU, 0, 2),
+
         /* The xregs array is a little awkward because element 1 (FPSCR)
          * requires a specific accessor, so we have to split it up in
          * the vmstate:
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index eed64c73e5..10eef870fe 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -517,8 +517,8 @@ static inline int vec_reg_offset(DisasContext *s, int regno,
 {
     int offs = 0;
 #ifdef HOST_WORDS_BIGENDIAN
-    /* This is complicated slightly because vfp.regs[2n] is
-     * still the low half and  vfp.regs[2n+1] the high half
+    /* This is complicated slightly because vfp.zregs[n].d[0] is
+     * still the low half and vfp.zregs[n].d[1] the high half
      * of the 128 bit vector, even on big endian systems.
      * Calculate the offset assuming a fully bigendian 128 bits,
      * then XOR to account for the order of the two 64 bit halves.
@@ -528,7 +528,7 @@ static inline int vec_reg_offset(DisasContext *s, int regno,
 #else
     offs += element * (1 << size);
 #endif
-    offs += offsetof(CPUARMState, vfp.regs[regno * 2]);
+    offs += offsetof(CPUARMState, vfp.zregs[regno]);
     assert_fp_access_checked(s);
     return offs;
 }
@@ -537,7 +537,7 @@ static inline int vec_reg_offset(DisasContext *s, int regno,
 static inline int vec_full_reg_offset(DisasContext *s, int regno)
 {
     assert_fp_access_checked(s);
-    return offsetof(CPUARMState, vfp.regs[regno * 2]);
+    return offsetof(CPUARMState, vfp.zregs[regno]);
 }
 
 /* Return a newly allocated pointer to the vector register.  */
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 55826b7e5a..a8c13d3758 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -1512,13 +1512,12 @@ static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
     }
 }
 
-static inline long
-vfp_reg_offset (int dp, int reg)
+static inline long vfp_reg_offset(bool dp, unsigned reg)
 {
     if (dp) {
-        return offsetof(CPUARMState, vfp.regs[reg]);
+        return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
     } else {
-        long ofs = offsetof(CPUARMState, vfp.regs[reg >> 1]);
+        long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
         if (reg & 1) {
             ofs += offsetof(CPU_DoubleU, l.upper);
         } else {
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [Qemu-devel] [PATCH v3 2/5] target/arm: Add predicate registers for SVE
  2018-01-23  3:53 [Qemu-devel] [PATCH v3 0/5] target/arm: Preparatory work for SVE Richard Henderson
  2018-01-23  3:53 ` [Qemu-devel] [PATCH v3 1/5] target/arm: Expand vector registers " Richard Henderson
@ 2018-01-23  3:53 ` Richard Henderson
  2018-01-23 11:46   ` Alex Bennée
  2018-01-29 17:30   ` Peter Maydell
  2018-01-23  3:53 ` [Qemu-devel] [PATCH v3 3/5] target/arm: Add SVE to migration state Richard Henderson
                   ` (3 subsequent siblings)
  5 siblings, 2 replies; 16+ messages in thread
From: Richard Henderson @ 2018-01-23  3:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, alex.bennee

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/cpu.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 1854fe51a8..3f4f6b6144 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -188,6 +188,13 @@ typedef struct ARMVectorReg {
     uint64_t d[2 * ARM_MAX_VQ] QEMU_ALIGNED(16);
 } ARMVectorReg;
 
+/* In AArch32 mode, predicate registers do not exist at all.  */
+#ifdef TARGET_AARCH64
+typedef struct ARMPredicateReg {
+    uint64_t p[2 * ARM_MAX_VQ / 8] QEMU_ALIGNED(16);
+} ARMPredicateReg;
+#endif
+
 
 typedef struct CPUARMState {
     /* Regs for current mode.  */
@@ -515,6 +522,11 @@ typedef struct CPUARMState {
     struct {
         ARMVectorReg zregs[32];
 
+#ifdef TARGET_AARCH64
+        /* Store FFR as pregs[16] to make it easier to treat as any other.  */
+        ARMPredicateReg pregs[17];
+#endif
+
         uint32_t xregs[16];
         /* We store these fpcsr fields separately for convenience.  */
         int vec_len;
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [Qemu-devel] [PATCH v3 3/5] target/arm: Add SVE to migration state
  2018-01-23  3:53 [Qemu-devel] [PATCH v3 0/5] target/arm: Preparatory work for SVE Richard Henderson
  2018-01-23  3:53 ` [Qemu-devel] [PATCH v3 1/5] target/arm: Expand vector registers " Richard Henderson
  2018-01-23  3:53 ` [Qemu-devel] [PATCH v3 2/5] target/arm: Add predicate " Richard Henderson
@ 2018-01-23  3:53 ` Richard Henderson
  2018-01-26 15:05   ` Alex Bennée
  2018-01-29 17:32   ` Peter Maydell
  2018-01-23  3:53 ` [Qemu-devel] [PATCH v3 4/5] target/arm: Add ZCR_ELx Richard Henderson
                   ` (2 subsequent siblings)
  5 siblings, 2 replies; 16+ messages in thread
From: Richard Henderson @ 2018-01-23  3:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, alex.bennee

Save the high parts of the Zregs and all of the Pregs.
The ZCR_ELx registers are migrated via the CP mechanism.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/machine.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/target/arm/machine.c b/target/arm/machine.c
index cb0e1c92bb..2c8b43062f 100644
--- a/target/arm/machine.c
+++ b/target/arm/machine.c
@@ -122,6 +122,56 @@ static const VMStateDescription vmstate_iwmmxt = {
     }
 };
 
+#ifdef TARGET_AARCH64
+/* The expression ARM_MAX_VQ - 2 is 0 for pure AArch32 build,
+ * and ARMPredicateReg is actively empty.  This triggers errors
+ * in the expansion of the VMSTATE macros.
+ */
+
+static bool sve_needed(void *opaque)
+{
+    ARMCPU *cpu = opaque;
+    CPUARMState *env = &cpu->env;
+
+    return arm_feature(env, ARM_FEATURE_SVE);
+}
+
+/* The first two words of each Zreg is stored in VFP state.  */
+static const VMStateDescription vmstate_zreg_hi_reg = {
+    .name = "cpu/sve/zreg_hi",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT64_SUB_ARRAY(d, ARMVectorReg, 2, ARM_MAX_VQ - 2),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static const VMStateDescription vmstate_preg_reg = {
+    .name = "cpu/sve/preg",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT64_ARRAY(p, ARMPredicateReg, 2 * ARM_MAX_VQ / 8),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static const VMStateDescription vmstate_sve = {
+    .name = "cpu/sve",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .needed = sve_needed,
+    .fields = (VMStateField[]) {
+        VMSTATE_STRUCT_ARRAY(env.vfp.zregs, ARMCPU, 32, 0,
+                             vmstate_zreg_hi_reg, ARMVectorReg),
+        VMSTATE_STRUCT_ARRAY(env.vfp.pregs, ARMCPU, 17, 0,
+                             vmstate_preg_reg, ARMPredicateReg),
+        VMSTATE_END_OF_LIST()
+    }
+};
+#endif /* AARCH64 */
+
 static bool m_needed(void *opaque)
 {
     ARMCPU *cpu = opaque;
@@ -586,6 +636,9 @@ const VMStateDescription vmstate_arm_cpu = {
         &vmstate_pmsav7,
         &vmstate_pmsav8,
         &vmstate_m_security,
+#ifdef TARGET_AARCH64
+        &vmstate_sve,
+#endif
         NULL
     }
 };
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [Qemu-devel] [PATCH v3 4/5] target/arm: Add ZCR_ELx
  2018-01-23  3:53 [Qemu-devel] [PATCH v3 0/5] target/arm: Preparatory work for SVE Richard Henderson
                   ` (2 preceding siblings ...)
  2018-01-23  3:53 ` [Qemu-devel] [PATCH v3 3/5] target/arm: Add SVE to migration state Richard Henderson
@ 2018-01-23  3:53 ` Richard Henderson
  2018-01-23 16:23   ` Richard Henderson
  2018-01-29 17:48   ` Peter Maydell
  2018-01-23  3:53 ` [Qemu-devel] [PATCH v3 5/5] target/arm: Add SVE state to TB->FLAGS Richard Henderson
  2018-02-08 14:34 ` [Qemu-devel] [PATCH v3 0/5] target/arm: Preparatory work for SVE Peter Maydell
  5 siblings, 2 replies; 16+ messages in thread
From: Richard Henderson @ 2018-01-23  3:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, alex.bennee

Define ZCR_EL[1-3].

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/cpu.h    |   5 ++
 target/arm/helper.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 136 insertions(+)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 3f4f6b6144..17955ad3ef 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -549,6 +549,9 @@ typedef struct CPUARMState {
          */
         float_status fp_status;
         float_status standard_fp_status;
+
+        /* ZCR_EL[1-3] */
+        uint64_t zcr_el[4];
     } vfp;
     uint64_t exclusive_addr;
     uint64_t exclusive_val;
@@ -923,6 +926,8 @@ void pmccntr_sync(CPUARMState *env);
 #define CPTR_TCPAC    (1U << 31)
 #define CPTR_TTA      (1U << 20)
 #define CPTR_TFP      (1U << 10)
+#define CPTR_TZ       (1U << 8)   /* CPTR_EL2 */
+#define CPTR_EZ       (1U << 8)   /* CPTR_EL3 */
 
 #define MDCR_EPMAD    (1U << 21)
 #define MDCR_EDAD     (1U << 20)
diff --git a/target/arm/helper.c b/target/arm/helper.c
index bfce09643b..db67e8ac72 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -4266,6 +4266,125 @@ static const ARMCPRegInfo debug_lpae_cp_reginfo[] = {
     REGINFO_SENTINEL
 };
 
+/* Return the exception level to which SVE-disabled exceptions should
+ * be taken, or 0 if SVE is enabled.
+ */
+static int sve_exception_el(CPUARMState *env)
+{
+#ifndef CONFIG_USER_ONLY
+    unsigned current_el = arm_current_el(env);
+
+    /* The CPACR.ZEN controls traps to EL1:
+     * 0, 2 : trap EL0 and EL1 accesses
+     * 1    : trap only EL0 accesses
+     * 3    : trap no accesses
+     */
+    switch (extract32(env->cp15.cpacr_el1, 16, 2)) {
+    default:
+        if (current_el <= 1) {
+            /* Trap to PL1, which might be EL1 or EL3 */
+            if (arm_is_secure(env) && !arm_el_is_aa64(env, 3)) {
+                return 3;
+            }
+            return 1;
+        }
+        break;
+    case 1:
+        if (current_el == 0) {
+            return 1;
+        }
+        break;
+    case 3:
+        break;
+    }
+
+    /* Similarly for CPACR.FPEN, after having checked ZEN.  */
+    switch (extract32(env->cp15.cpacr_el1, 20, 2)) {
+    default:
+        if (current_el <= 1) {
+            if (arm_is_secure(env) && !arm_el_is_aa64(env, 3)) {
+                return 3;
+            }
+            return 1;
+        }
+        break;
+    case 1:
+        if (current_el == 0) {
+            return 1;
+        }
+        break;
+    case 3:
+        break;
+    }
+
+    /* CPTR_EL2.  Check both TZ and TFP.  */
+    if (current_el <= 2
+        && (env->cp15.cptr_el[2] & (CPTR_TFP | CPTR_TZ))
+        && !arm_is_secure_below_el3(env)) {
+        return 2;
+    }
+
+    /* CPTR_EL3.  Check both EZ and TFP.  */
+    if (!(env->cp15.cptr_el[3] & CPTR_EZ)
+        || (env->cp15.cptr_el[3] & CPTR_TFP)) {
+        return 3;
+    }
+#endif
+    return 0;
+}
+
+static CPAccessResult zcr_access(CPUARMState *env, const ARMCPRegInfo *ri,
+                                 bool isread)
+{
+    switch (sve_exception_el(env)) {
+    case 3:
+        return CP_ACCESS_TRAP_EL3;
+    case 2:
+        return CP_ACCESS_TRAP_EL2;
+    case 1:
+        return CP_ACCESS_TRAP;
+    }
+    return CP_ACCESS_OK;
+}
+
+static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                      uint64_t value)
+{
+    /* Bits other than [3:0] are RAZ/WI.  */
+    raw_write(env, ri, value & 0xf);
+}
+
+static const ARMCPRegInfo zcr_el1_reginfo = {
+    .name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
+    .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
+    .access = PL1_RW, .accessfn = zcr_access, .type = ARM_CP_64BIT,
+    .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
+    .writefn = zcr_write, .raw_writefn = raw_write
+};
+
+static const ARMCPRegInfo zcr_el2_reginfo = {
+    .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
+    .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
+    .access = PL2_RW, .accessfn = zcr_access, .type = ARM_CP_64BIT,
+    .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[2]),
+    .writefn = zcr_write, .raw_writefn = raw_write
+};
+
+static const ARMCPRegInfo zcr_no_el2_reginfo = {
+    .name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
+    .opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
+    .access = PL2_RW, .type = ARM_CP_64BIT,
+    .readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore
+};
+
+static const ARMCPRegInfo zcr_el3_reginfo = {
+    .name = "ZCR_EL3", .state = ARM_CP_STATE_AA64,
+    .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 2, .opc2 = 0,
+    .access = PL3_RW, .accessfn = zcr_access, .type = ARM_CP_64BIT,
+    .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[3]),
+    .writefn = zcr_write, .raw_writefn = raw_write
+};
+
 void hw_watchpoint_update(ARMCPU *cpu, int n)
 {
     CPUARMState *env = &cpu->env;
@@ -5332,6 +5451,18 @@ void register_cp_regs_for_features(ARMCPU *cpu)
         }
         define_one_arm_cp_reg(cpu, &sctlr);
     }
+
+    if (arm_feature(env, ARM_FEATURE_SVE)) {
+        define_one_arm_cp_reg(cpu, &zcr_el1_reginfo);
+        if (arm_feature(env, ARM_FEATURE_EL2)) {
+            define_one_arm_cp_reg(cpu, &zcr_el2_reginfo);
+        } else {
+            define_one_arm_cp_reg(cpu, &zcr_no_el2_reginfo);
+        }
+        if (arm_feature(env, ARM_FEATURE_EL3)) {
+            define_one_arm_cp_reg(cpu, &zcr_el3_reginfo);
+        }
+    }
 }
 
 void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [Qemu-devel] [PATCH v3 5/5] target/arm: Add SVE state to TB->FLAGS
  2018-01-23  3:53 [Qemu-devel] [PATCH v3 0/5] target/arm: Preparatory work for SVE Richard Henderson
                   ` (3 preceding siblings ...)
  2018-01-23  3:53 ` [Qemu-devel] [PATCH v3 4/5] target/arm: Add ZCR_ELx Richard Henderson
@ 2018-01-23  3:53 ` Richard Henderson
  2018-01-29 18:01   ` Peter Maydell
  2018-02-08 14:34 ` [Qemu-devel] [PATCH v3 0/5] target/arm: Preparatory work for SVE Peter Maydell
  5 siblings, 1 reply; 16+ messages in thread
From: Richard Henderson @ 2018-01-23  3:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, alex.bennee

Add both SVE exception state and vector length.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/cpu.h           |  8 ++++++++
 target/arm/translate.h     |  2 ++
 target/arm/helper.c        | 25 ++++++++++++++++++++++++-
 target/arm/translate-a64.c |  2 ++
 4 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 17955ad3ef..a311d4e327 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -2648,6 +2648,10 @@ static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
 #define ARM_TBFLAG_TBI0_MASK (0x1ull << ARM_TBFLAG_TBI0_SHIFT)
 #define ARM_TBFLAG_TBI1_SHIFT 1        /* TBI1 for EL0/1  */
 #define ARM_TBFLAG_TBI1_MASK (0x1ull << ARM_TBFLAG_TBI1_SHIFT)
+#define ARM_TBFLAG_SVEEXC_EL_SHIFT  2
+#define ARM_TBFLAG_SVEEXC_EL_MASK   (0x3 << ARM_TBFLAG_SVEEXC_EL_SHIFT)
+#define ARM_TBFLAG_ZCR_LEN_SHIFT    4
+#define ARM_TBFLAG_ZCR_LEN_MASK     (0xf << ARM_TBFLAG_ZCR_LEN_SHIFT)
 
 /* some convenience accessor macros */
 #define ARM_TBFLAG_AARCH64_STATE(F) \
@@ -2684,6 +2688,10 @@ static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
     (((F) & ARM_TBFLAG_TBI0_MASK) >> ARM_TBFLAG_TBI0_SHIFT)
 #define ARM_TBFLAG_TBI1(F) \
     (((F) & ARM_TBFLAG_TBI1_MASK) >> ARM_TBFLAG_TBI1_SHIFT)
+#define ARM_TBFLAG_SVEEXC_EL(F) \
+    (((F) & ARM_TBFLAG_SVEEXC_EL_MASK) >> ARM_TBFLAG_SVEEXC_EL_SHIFT)
+#define ARM_TBFLAG_ZCR_LEN(F) \
+    (((F) & ARM_TBFLAG_ZCR_LEN_MASK) >> ARM_TBFLAG_ZCR_LEN_SHIFT)
 
 static inline bool bswap_code(bool sctlr_b)
 {
diff --git a/target/arm/translate.h b/target/arm/translate.h
index 3f4df91e5e..c47febf99d 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -29,6 +29,8 @@ typedef struct DisasContext {
     bool tbi1;         /* TBI1 for EL0/1, not used for EL2/3 */
     bool ns;        /* Use non-secure CPREG bank on access */
     int fp_excp_el; /* FP exception EL or 0 if enabled */
+    int sve_excp_el; /* SVE exception EL or 0 if enabled */
+    int sve_len;     /* SVE vector length in bytes */
     /* Flag indicating that exceptions from secure mode are routed to EL3. */
     bool secure_routed_to_el3;
     bool vfp_enabled; /* FP enabled via FPSCR.EN */
diff --git a/target/arm/helper.c b/target/arm/helper.c
index db67e8ac72..d46d3622fc 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -11823,14 +11823,37 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
                           target_ulong *cs_base, uint32_t *pflags)
 {
     ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
+    int fp_el = fp_exception_el(env);
     uint32_t flags;
 
     if (is_a64(env)) {
+        int sve_el = sve_exception_el(env);
+        uint32_t zcr_len;
+
         *pc = env->pc;
         flags = ARM_TBFLAG_AARCH64_STATE_MASK;
         /* Get control bits for tagged addresses */
         flags |= (arm_regime_tbi0(env, mmu_idx) << ARM_TBFLAG_TBI0_SHIFT);
         flags |= (arm_regime_tbi1(env, mmu_idx) << ARM_TBFLAG_TBI1_SHIFT);
+        flags |= sve_el << ARM_TBFLAG_SVEEXC_EL_SHIFT;
+
+        /* If SVE is disabled, but FP is enabled,
+           then the effective len is 0.  */
+        if (sve_el != 0 && fp_el == 0) {
+            zcr_len = 0;
+        } else {
+            int current_el = arm_current_el(env);
+
+            zcr_len = env->vfp.zcr_el[current_el <= 1 ? 1 : current_el];
+            zcr_len &= 0xf;
+            if (current_el < 2 && arm_feature(env, ARM_FEATURE_EL2)) {
+                zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[2]);
+            }
+            if (current_el < 3 && arm_feature(env, ARM_FEATURE_EL3)) {
+                zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[3]);
+            }
+        }
+        flags |= zcr_len << ARM_TBFLAG_ZCR_LEN_SHIFT;
     } else {
         *pc = env->regs[15];
         flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)
@@ -11873,7 +11896,7 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
     if (arm_cpu_data_is_big_endian(env)) {
         flags |= ARM_TBFLAG_BE_DATA_MASK;
     }
-    flags |= fp_exception_el(env) << ARM_TBFLAG_FPEXC_EL_SHIFT;
+    flags |= fp_el << ARM_TBFLAG_FPEXC_EL_SHIFT;
 
     if (arm_v7m_is_handler_mode(env)) {
         flags |= ARM_TBFLAG_HANDLER_MASK;
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 10eef870fe..4c1eca7062 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -11263,6 +11263,8 @@ static int aarch64_tr_init_disas_context(DisasContextBase *dcbase,
     dc->user = (dc->current_el == 0);
 #endif
     dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(dc->base.tb->flags);
+    dc->sve_excp_el = ARM_TBFLAG_SVEEXC_EL(dc->base.tb->flags);
+    dc->sve_len = (ARM_TBFLAG_ZCR_LEN(dc->base.tb->flags) + 1) * 16;
     dc->vec_len = 0;
     dc->vec_stride = 0;
     dc->cp_regs = arm_cpu->cp_regs;
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH v3 2/5] target/arm: Add predicate registers for SVE
  2018-01-23  3:53 ` [Qemu-devel] [PATCH v3 2/5] target/arm: Add predicate " Richard Henderson
@ 2018-01-23 11:46   ` Alex Bennée
  2018-01-29 17:30   ` Peter Maydell
  1 sibling, 0 replies; 16+ messages in thread
From: Alex Bennée @ 2018-01-23 11:46 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, peter.maydell


Richard Henderson <richard.henderson@linaro.org> writes:

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

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>

> ---
>  target/arm/cpu.h | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
>
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index 1854fe51a8..3f4f6b6144 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -188,6 +188,13 @@ typedef struct ARMVectorReg {
>      uint64_t d[2 * ARM_MAX_VQ] QEMU_ALIGNED(16);
>  } ARMVectorReg;
>
> +/* In AArch32 mode, predicate registers do not exist at all.  */
> +#ifdef TARGET_AARCH64
> +typedef struct ARMPredicateReg {
> +    uint64_t p[2 * ARM_MAX_VQ / 8] QEMU_ALIGNED(16);
> +} ARMPredicateReg;
> +#endif
> +
>
>  typedef struct CPUARMState {
>      /* Regs for current mode.  */
> @@ -515,6 +522,11 @@ typedef struct CPUARMState {
>      struct {
>          ARMVectorReg zregs[32];
>
> +#ifdef TARGET_AARCH64
> +        /* Store FFR as pregs[16] to make it easier to treat as any other.  */
> +        ARMPredicateReg pregs[17];
> +#endif
> +
>          uint32_t xregs[16];
>          /* We store these fpcsr fields separately for convenience.  */
>          int vec_len;


--
Alex Bennée

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH v3 4/5] target/arm: Add ZCR_ELx
  2018-01-23  3:53 ` [Qemu-devel] [PATCH v3 4/5] target/arm: Add ZCR_ELx Richard Henderson
@ 2018-01-23 16:23   ` Richard Henderson
  2018-01-29 17:48   ` Peter Maydell
  1 sibling, 0 replies; 16+ messages in thread
From: Richard Henderson @ 2018-01-23 16:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, alex.bennee

On 01/22/2018 07:53 PM, Richard Henderson wrote:
> +static const ARMCPRegInfo zcr_el1_reginfo = {
> +    .name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
> +    .opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
> +    .access = PL1_RW, .accessfn = zcr_access, .type = ARM_CP_64BIT,
> +    .fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
> +    .writefn = zcr_write, .raw_writefn = raw_write
> +};

Ho hum.  Got far enough in the rest of my rebasing to see that .type must be
dropped -- there's an assert saying STATE_AA64 implies 64BIT and shouldn't be
repeated.


r~

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH v3 3/5] target/arm: Add SVE to migration state
  2018-01-23  3:53 ` [Qemu-devel] [PATCH v3 3/5] target/arm: Add SVE to migration state Richard Henderson
@ 2018-01-26 15:05   ` Alex Bennée
  2018-01-29 17:32   ` Peter Maydell
  1 sibling, 0 replies; 16+ messages in thread
From: Alex Bennée @ 2018-01-26 15:05 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, peter.maydell


Richard Henderson <richard.henderson@linaro.org> writes:

> Save the high parts of the Zregs and all of the Pregs.
> The ZCR_ELx registers are migrated via the CP mechanism.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>

> ---
>  target/arm/machine.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 53 insertions(+)
>
> diff --git a/target/arm/machine.c b/target/arm/machine.c
> index cb0e1c92bb..2c8b43062f 100644
> --- a/target/arm/machine.c
> +++ b/target/arm/machine.c
> @@ -122,6 +122,56 @@ static const VMStateDescription vmstate_iwmmxt = {
>      }
>  };
>
> +#ifdef TARGET_AARCH64
> +/* The expression ARM_MAX_VQ - 2 is 0 for pure AArch32 build,
> + * and ARMPredicateReg is actively empty.  This triggers errors
> + * in the expansion of the VMSTATE macros.
> + */
> +
> +static bool sve_needed(void *opaque)
> +{
> +    ARMCPU *cpu = opaque;
> +    CPUARMState *env = &cpu->env;
> +
> +    return arm_feature(env, ARM_FEATURE_SVE);
> +}
> +
> +/* The first two words of each Zreg is stored in VFP state.  */
> +static const VMStateDescription vmstate_zreg_hi_reg = {
> +    .name = "cpu/sve/zreg_hi",
> +    .version_id = 1,
> +    .minimum_version_id = 1,
> +    .fields = (VMStateField[]) {
> +        VMSTATE_UINT64_SUB_ARRAY(d, ARMVectorReg, 2, ARM_MAX_VQ - 2),
> +        VMSTATE_END_OF_LIST()
> +    }
> +};
> +
> +static const VMStateDescription vmstate_preg_reg = {
> +    .name = "cpu/sve/preg",
> +    .version_id = 1,
> +    .minimum_version_id = 1,
> +    .fields = (VMStateField[]) {
> +        VMSTATE_UINT64_ARRAY(p, ARMPredicateReg, 2 * ARM_MAX_VQ / 8),
> +        VMSTATE_END_OF_LIST()
> +    }
> +};
> +
> +static const VMStateDescription vmstate_sve = {
> +    .name = "cpu/sve",
> +    .version_id = 1,
> +    .minimum_version_id = 1,
> +    .needed = sve_needed,
> +    .fields = (VMStateField[]) {
> +        VMSTATE_STRUCT_ARRAY(env.vfp.zregs, ARMCPU, 32, 0,
> +                             vmstate_zreg_hi_reg, ARMVectorReg),
> +        VMSTATE_STRUCT_ARRAY(env.vfp.pregs, ARMCPU, 17, 0,
> +                             vmstate_preg_reg, ARMPredicateReg),
> +        VMSTATE_END_OF_LIST()
> +    }
> +};
> +#endif /* AARCH64 */
> +
>  static bool m_needed(void *opaque)
>  {
>      ARMCPU *cpu = opaque;
> @@ -586,6 +636,9 @@ const VMStateDescription vmstate_arm_cpu = {
>          &vmstate_pmsav7,
>          &vmstate_pmsav8,
>          &vmstate_m_security,
> +#ifdef TARGET_AARCH64
> +        &vmstate_sve,
> +#endif
>          NULL
>      }
>  };


--
Alex Bennée

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH v3 1/5] target/arm: Expand vector registers for SVE
  2018-01-23  3:53 ` [Qemu-devel] [PATCH v3 1/5] target/arm: Expand vector registers " Richard Henderson
@ 2018-01-29 17:30   ` Peter Maydell
  0 siblings, 0 replies; 16+ messages in thread
From: Peter Maydell @ 2018-01-29 17:30 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers, Alex Bennée

On 23 January 2018 at 03:53, Richard Henderson
<richard.henderson@linaro.org> wrote:
> Change vfp.regs as a uint64_t to vfp.zregs as an ARMVectorReg.
> The previous patches have made the change in representation
> relatively painless.
>
> Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/arm/cpu.h           | 59 +++++++++++++++++++++++++++++++---------------
>  target/arm/machine.c       | 35 ++++++++++++++++++++++++++-
>  target/arm/translate-a64.c |  8 +++----
>  target/arm/translate.c     |  7 +++---
>  4 files changed, 81 insertions(+), 28 deletions(-)
>

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

thanks
-- PMM

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH v3 2/5] target/arm: Add predicate registers for SVE
  2018-01-23  3:53 ` [Qemu-devel] [PATCH v3 2/5] target/arm: Add predicate " Richard Henderson
  2018-01-23 11:46   ` Alex Bennée
@ 2018-01-29 17:30   ` Peter Maydell
  1 sibling, 0 replies; 16+ messages in thread
From: Peter Maydell @ 2018-01-29 17:30 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers, Alex Bennée

On 23 January 2018 at 03:53, Richard Henderson
<richard.henderson@linaro.org> wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/arm/cpu.h | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
>
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index 1854fe51a8..3f4f6b6144 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -188,6 +188,13 @@ typedef struct ARMVectorReg {
>      uint64_t d[2 * ARM_MAX_VQ] QEMU_ALIGNED(16);
>  } ARMVectorReg;
>
> +/* In AArch32 mode, predicate registers do not exist at all.  */
> +#ifdef TARGET_AARCH64
> +typedef struct ARMPredicateReg {
> +    uint64_t p[2 * ARM_MAX_VQ / 8] QEMU_ALIGNED(16);
> +} ARMPredicateReg;
> +#endif
> +
>
>  typedef struct CPUARMState {
>      /* Regs for current mode.  */
> @@ -515,6 +522,11 @@ typedef struct CPUARMState {
>      struct {
>          ARMVectorReg zregs[32];
>
> +#ifdef TARGET_AARCH64
> +        /* Store FFR as pregs[16] to make it easier to treat as any other.  */
> +        ARMPredicateReg pregs[17];
> +#endif

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

thanks
-- PMM

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH v3 3/5] target/arm: Add SVE to migration state
  2018-01-23  3:53 ` [Qemu-devel] [PATCH v3 3/5] target/arm: Add SVE to migration state Richard Henderson
  2018-01-26 15:05   ` Alex Bennée
@ 2018-01-29 17:32   ` Peter Maydell
  1 sibling, 0 replies; 16+ messages in thread
From: Peter Maydell @ 2018-01-29 17:32 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers, Alex Bennée

On 23 January 2018 at 03:53, Richard Henderson
<richard.henderson@linaro.org> wrote:
> Save the high parts of the Zregs and all of the Pregs.
> The ZCR_ELx registers are migrated via the CP mechanism.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/arm/machine.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 53 insertions(+)
>

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

thanks
-- PMM

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH v3 4/5] target/arm: Add ZCR_ELx
  2018-01-23  3:53 ` [Qemu-devel] [PATCH v3 4/5] target/arm: Add ZCR_ELx Richard Henderson
  2018-01-23 16:23   ` Richard Henderson
@ 2018-01-29 17:48   ` Peter Maydell
  1 sibling, 0 replies; 16+ messages in thread
From: Peter Maydell @ 2018-01-29 17:48 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers, Alex Bennée

On 23 January 2018 at 03:53, Richard Henderson
<richard.henderson@linaro.org> wrote:
> Define ZCR_EL[1-3].
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/arm/cpu.h    |   5 ++
>  target/arm/helper.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 136 insertions(+)
>

Apart from the issue you've noticed about not wanting to specify
.type:

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

thanks
-- PMM

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH v3 5/5] target/arm: Add SVE state to TB->FLAGS
  2018-01-23  3:53 ` [Qemu-devel] [PATCH v3 5/5] target/arm: Add SVE state to TB->FLAGS Richard Henderson
@ 2018-01-29 18:01   ` Peter Maydell
  2018-01-29 18:16     ` Richard Henderson
  0 siblings, 1 reply; 16+ messages in thread
From: Peter Maydell @ 2018-01-29 18:01 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers, Alex Bennée

On 23 January 2018 at 03:53, Richard Henderson
<richard.henderson@linaro.org> wrote:
> Add both SVE exception state and vector length.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

> diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
> index 10eef870fe..4c1eca7062 100644
> --- a/target/arm/translate-a64.c
> +++ b/target/arm/translate-a64.c
> @@ -11263,6 +11263,8 @@ static int aarch64_tr_init_disas_context(DisasContextBase *dcbase,
>      dc->user = (dc->current_el == 0);
>  #endif
>      dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(dc->base.tb->flags);
> +    dc->sve_excp_el = ARM_TBFLAG_SVEEXC_EL(dc->base.tb->flags);
> +    dc->sve_len = (ARM_TBFLAG_ZCR_LEN(dc->base.tb->flags) + 1) * 16;

You've carefully arranged that the sve_excp checks are a superset
of the fp_excp checks, which means that we get the correct
exception prioritization by always doing the sve_excp check first
and then the fp_excp check second, without having to look at
whether fp_excp_el or sve_excp_el is larger to see which should
take precedence. We could
  assert(dc->sve_excp_el <= dc->fp_excp_el);
and perhaps have a comment noting why this is useful...

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

thanks
-- PMM

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH v3 5/5] target/arm: Add SVE state to TB->FLAGS
  2018-01-29 18:01   ` Peter Maydell
@ 2018-01-29 18:16     ` Richard Henderson
  0 siblings, 0 replies; 16+ messages in thread
From: Richard Henderson @ 2018-01-29 18:16 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers, Alex Bennée

On 01/29/2018 10:01 AM, Peter Maydell wrote:
> On 23 January 2018 at 03:53, Richard Henderson
> <richard.henderson@linaro.org> wrote:
>> Add both SVE exception state and vector length.
>>
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> 
>> diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
>> index 10eef870fe..4c1eca7062 100644
>> --- a/target/arm/translate-a64.c
>> +++ b/target/arm/translate-a64.c
>> @@ -11263,6 +11263,8 @@ static int aarch64_tr_init_disas_context(DisasContextBase *dcbase,
>>      dc->user = (dc->current_el == 0);
>>  #endif
>>      dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(dc->base.tb->flags);
>> +    dc->sve_excp_el = ARM_TBFLAG_SVEEXC_EL(dc->base.tb->flags);
>> +    dc->sve_len = (ARM_TBFLAG_ZCR_LEN(dc->base.tb->flags) + 1) * 16;
> 
> You've carefully arranged that the sve_excp checks are a superset
> of the fp_excp checks, which means that we get the correct
> exception prioritization by always doing the sve_excp check first
> and then the fp_excp check second, without having to look at
> whether fp_excp_el or sve_excp_el is larger to see which should
> take precedence. We could
>   assert(dc->sve_excp_el <= dc->fp_excp_el);
> and perhaps have a comment noting why this is useful...

Sort of, I suppose.  Modulo the fact that "enabled" is zero,
so sve disabled &  fp enabled means sve_el > fp_el.

But you're right that to some extent I'm doing too much work
replicating the fp exception check.


r~

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Qemu-devel] [PATCH v3 0/5] target/arm: Preparatory work for SVE
  2018-01-23  3:53 [Qemu-devel] [PATCH v3 0/5] target/arm: Preparatory work for SVE Richard Henderson
                   ` (4 preceding siblings ...)
  2018-01-23  3:53 ` [Qemu-devel] [PATCH v3 5/5] target/arm: Add SVE state to TB->FLAGS Richard Henderson
@ 2018-02-08 14:34 ` Peter Maydell
  5 siblings, 0 replies; 16+ messages in thread
From: Peter Maydell @ 2018-02-08 14:34 UTC (permalink / raw)
  To: Richard Henderson; +Cc: QEMU Developers, Alex Bennée

On 23 January 2018 at 03:53, Richard Henderson
<richard.henderson@linaro.org> wrote:
> Based on PMM's target-arm.next branch, which now has most of v2.
>
> While looking again at ZCR_ELx, I think that there's an existing
> bug in the FPCR/FPSR system registers, wherein we do not have an
> access function for when the FPU is disabled.

Applied to target-arm.next, thanks.

-- PMM

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2018-02-08 14:34 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-01-23  3:53 [Qemu-devel] [PATCH v3 0/5] target/arm: Preparatory work for SVE Richard Henderson
2018-01-23  3:53 ` [Qemu-devel] [PATCH v3 1/5] target/arm: Expand vector registers " Richard Henderson
2018-01-29 17:30   ` Peter Maydell
2018-01-23  3:53 ` [Qemu-devel] [PATCH v3 2/5] target/arm: Add predicate " Richard Henderson
2018-01-23 11:46   ` Alex Bennée
2018-01-29 17:30   ` Peter Maydell
2018-01-23  3:53 ` [Qemu-devel] [PATCH v3 3/5] target/arm: Add SVE to migration state Richard Henderson
2018-01-26 15:05   ` Alex Bennée
2018-01-29 17:32   ` Peter Maydell
2018-01-23  3:53 ` [Qemu-devel] [PATCH v3 4/5] target/arm: Add ZCR_ELx Richard Henderson
2018-01-23 16:23   ` Richard Henderson
2018-01-29 17:48   ` Peter Maydell
2018-01-23  3:53 ` [Qemu-devel] [PATCH v3 5/5] target/arm: Add SVE state to TB->FLAGS Richard Henderson
2018-01-29 18:01   ` Peter Maydell
2018-01-29 18:16     ` Richard Henderson
2018-02-08 14:34 ` [Qemu-devel] [PATCH v3 0/5] target/arm: Preparatory work for SVE Peter Maydell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).