qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/4] target/arm: Fix sve pred_desc decoding
@ 2021-01-13  6:26 Richard Henderson
  2021-01-13  6:26 ` [PATCH v2 1/4] target/arm: Introduce PREDDESC field definitions Richard Henderson
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Richard Henderson @ 2021-01-13  6:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, qemu-arm

There was an inconsistency between encoding, which uses
SIMD_DATA_SHIFT, and decoding which used SIMD_OPRSZ_BITS.
This happened to be ok, until e2e7168a214, which reduced
the size of SIMD_OPRSZ_BITS, which lead to truncating all
predicate vector lengths.

Changes in v2:
  * Introduce and use PREDDESC field definitions, rather
    than abusing a different SIMD_* macro.


r~


Richard Henderson (4):
  target/arm: Introduce PREDDESC field definitions
  target/arm: Update PFIRST, PNEXT for pred_desc
  target/arm: Update ZIP, UZP, TRN for pred_desc
  target/arm: Update REV, PUNPK for pred_desc

 target/arm/internals.h     |  9 +++++++++
 target/arm/sve_helper.c    | 33 +++++++++++++++++----------------
 target/arm/translate-sve.c | 31 +++++++++++--------------------
 3 files changed, 37 insertions(+), 36 deletions(-)

-- 
2.25.1



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

* [PATCH v2 1/4] target/arm: Introduce PREDDESC field definitions
  2021-01-13  6:26 [PATCH v2 0/4] target/arm: Fix sve pred_desc decoding Richard Henderson
@ 2021-01-13  6:26 ` Richard Henderson
  2021-01-13  6:26 ` [PATCH v2 2/4] target/arm: Update PFIRST, PNEXT for pred_desc Richard Henderson
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Richard Henderson @ 2021-01-13  6:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, qemu-arm, qemu-stable

SVE predicate operations cannot use the "usual" simd_desc
encoding, because the lengths are not a multiple of 8.
But we were abusing the SIMD_* fields to store values anyway.
This abuse broke when SIMD_OPRSZ_BITS was modified in e2e7168a214.

Introduce a new set of field definitions for exclusive use
of predicates, so that it is obvious what kind of predicate
we are manipulating.  To be used in future patches.

Cc: qemu-stable@nongnu.org
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/internals.h | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/target/arm/internals.h b/target/arm/internals.h
index 5460678756..73698587d6 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -1312,6 +1312,15 @@ void arm_log_exception(int idx);
 #define LOG2_TAG_GRANULE 4
 #define TAG_GRANULE      (1 << LOG2_TAG_GRANULE)
 
+/*
+ * SVE predicates are 1/8 the size of SVE vectors, and cannot use
+ * the same simd_desc() encoding due to restrictions on size.
+ * Use these instead.
+ */
+FIELD(PREDDESC, OPRSZ, 0, 6)
+FIELD(PREDDESC, ESZ, 6, 2)
+FIELD(PREDDESC, DATA, 8, 24)
+
 /*
  * The SVE simd_data field, for memory ops, contains either
  * rd (5 bits) or a shift count (2 bits).
-- 
2.25.1



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

* [PATCH v2 2/4] target/arm: Update PFIRST, PNEXT for pred_desc
  2021-01-13  6:26 [PATCH v2 0/4] target/arm: Fix sve pred_desc decoding Richard Henderson
  2021-01-13  6:26 ` [PATCH v2 1/4] target/arm: Introduce PREDDESC field definitions Richard Henderson
@ 2021-01-13  6:26 ` Richard Henderson
  2021-01-13  6:26 ` [PATCH v2 3/4] target/arm: Update ZIP, UZP, TRN " Richard Henderson
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Richard Henderson @ 2021-01-13  6:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, qemu-arm, qemu-stable

These two were odd, in that do_pfirst_pnext passed the
count of 64-bit words rather than bytes.  Change to pass
the standard pred_full_reg_size to avoid confusion.

Cc: qemu-stable@nongnu.org
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/sve_helper.c    | 7 ++++---
 target/arm/translate-sve.c | 6 +++---
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
index 5f037c3a8f..ff01851bf2 100644
--- a/target/arm/sve_helper.c
+++ b/target/arm/sve_helper.c
@@ -889,8 +889,9 @@ static intptr_t last_active_element(uint64_t *g, intptr_t words, intptr_t esz)
     return (intptr_t)-1 << esz;
 }
 
-uint32_t HELPER(sve_pfirst)(void *vd, void *vg, uint32_t words)
+uint32_t HELPER(sve_pfirst)(void *vd, void *vg, uint32_t pred_desc)
 {
+    intptr_t words = DIV_ROUND_UP(FIELD_EX32(pred_desc, PREDDESC, OPRSZ), 8);
     uint32_t flags = PREDTEST_INIT;
     uint64_t *d = vd, *g = vg;
     intptr_t i = 0;
@@ -914,8 +915,8 @@ uint32_t HELPER(sve_pfirst)(void *vd, void *vg, uint32_t words)
 
 uint32_t HELPER(sve_pnext)(void *vd, void *vg, uint32_t pred_desc)
 {
-    intptr_t words = extract32(pred_desc, 0, SIMD_OPRSZ_BITS);
-    intptr_t esz = extract32(pred_desc, SIMD_DATA_SHIFT, 2);
+    intptr_t words = DIV_ROUND_UP(FIELD_EX32(pred_desc, PREDDESC, OPRSZ), 8);
+    intptr_t esz = FIELD_EX32(pred_desc, PREDDESC, ESZ);
     uint32_t flags = PREDTEST_INIT;
     uint64_t *d = vd, *g = vg, esz_mask;
     intptr_t i, next;
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 0c3a6d2121..efcb646f72 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -1494,10 +1494,10 @@ static bool do_pfirst_pnext(DisasContext *s, arg_rr_esz *a,
     TCGv_ptr t_pd = tcg_temp_new_ptr();
     TCGv_ptr t_pg = tcg_temp_new_ptr();
     TCGv_i32 t;
-    unsigned desc;
+    unsigned desc = 0;
 
-    desc = DIV_ROUND_UP(pred_full_reg_size(s), 8);
-    desc = deposit32(desc, SIMD_DATA_SHIFT, 2, a->esz);
+    desc = FIELD_DP32(desc, PREDDESC, OPRSZ, pred_full_reg_size(s));
+    desc = FIELD_DP32(desc, PREDDESC, ESZ, a->esz);
 
     tcg_gen_addi_ptr(t_pd, cpu_env, pred_full_reg_offset(s, a->rd));
     tcg_gen_addi_ptr(t_pg, cpu_env, pred_full_reg_offset(s, a->rn));
-- 
2.25.1



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

* [PATCH v2 3/4] target/arm: Update ZIP, UZP, TRN for pred_desc
  2021-01-13  6:26 [PATCH v2 0/4] target/arm: Fix sve pred_desc decoding Richard Henderson
  2021-01-13  6:26 ` [PATCH v2 1/4] target/arm: Introduce PREDDESC field definitions Richard Henderson
  2021-01-13  6:26 ` [PATCH v2 2/4] target/arm: Update PFIRST, PNEXT for pred_desc Richard Henderson
@ 2021-01-13  6:26 ` Richard Henderson
  2021-01-13  6:26 ` [PATCH v2 4/4] target/arm: Update REV, PUNPK " Richard Henderson
  2021-01-19 11:28 ` [PATCH v2 0/4] target/arm: Fix sve pred_desc decoding Peter Maydell
  4 siblings, 0 replies; 6+ messages in thread
From: Richard Henderson @ 2021-01-13  6:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, qemu-arm, qemu-stable

Update all users of do_perm_pred3 for the new
predicate descriptor field definitions.

Cc: qemu-stable@nongnu.org
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/sve_helper.c    | 18 +++++++++---------
 target/arm/translate-sve.c | 12 ++++--------
 2 files changed, 13 insertions(+), 17 deletions(-)

diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
index ff01851bf2..7eec4b6b73 100644
--- a/target/arm/sve_helper.c
+++ b/target/arm/sve_helper.c
@@ -1868,9 +1868,9 @@ static uint64_t compress_bits(uint64_t x, int n)
 
 void HELPER(sve_zip_p)(void *vd, void *vn, void *vm, uint32_t pred_desc)
 {
-    intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
-    int esz = extract32(pred_desc, SIMD_DATA_SHIFT, 2);
-    intptr_t high = extract32(pred_desc, SIMD_DATA_SHIFT + 2, 1);
+    intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
+    int esz = FIELD_EX32(pred_desc, PREDDESC, ESZ);
+    intptr_t high = FIELD_EX32(pred_desc, PREDDESC, DATA);
     uint64_t *d = vd;
     intptr_t i;
 
@@ -1929,9 +1929,9 @@ void HELPER(sve_zip_p)(void *vd, void *vn, void *vm, uint32_t pred_desc)
 
 void HELPER(sve_uzp_p)(void *vd, void *vn, void *vm, uint32_t pred_desc)
 {
-    intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
-    int esz = extract32(pred_desc, SIMD_DATA_SHIFT, 2);
-    int odd = extract32(pred_desc, SIMD_DATA_SHIFT + 2, 1) << esz;
+    intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
+    int esz = FIELD_EX32(pred_desc, PREDDESC, ESZ);
+    int odd = FIELD_EX32(pred_desc, PREDDESC, DATA) << esz;
     uint64_t *d = vd, *n = vn, *m = vm;
     uint64_t l, h;
     intptr_t i;
@@ -1986,9 +1986,9 @@ void HELPER(sve_uzp_p)(void *vd, void *vn, void *vm, uint32_t pred_desc)
 
 void HELPER(sve_trn_p)(void *vd, void *vn, void *vm, uint32_t pred_desc)
 {
-    intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
-    uintptr_t esz = extract32(pred_desc, SIMD_DATA_SHIFT, 2);
-    bool odd = extract32(pred_desc, SIMD_DATA_SHIFT + 2, 1);
+    intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
+    int esz = FIELD_EX32(pred_desc, PREDDESC, ESZ);
+    int odd = FIELD_EX32(pred_desc, PREDDESC, DATA);
     uint64_t *d = vd, *n = vn, *m = vm;
     uint64_t mask;
     int shr, shl;
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index efcb646f72..0baca176a0 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -2110,19 +2110,15 @@ static bool do_perm_pred3(DisasContext *s, arg_rrr_esz *a, bool high_odd,
 
     unsigned vsz = pred_full_reg_size(s);
 
-    /* Predicate sizes may be smaller and cannot use simd_desc.
-       We cannot round up, as we do elsewhere, because we need
-       the exact size for ZIP2 and REV.  We retain the style for
-       the other helpers for consistency.  */
     TCGv_ptr t_d = tcg_temp_new_ptr();
     TCGv_ptr t_n = tcg_temp_new_ptr();
     TCGv_ptr t_m = tcg_temp_new_ptr();
     TCGv_i32 t_desc;
-    int desc;
+    uint32_t desc = 0;
 
-    desc = vsz - 2;
-    desc = deposit32(desc, SIMD_DATA_SHIFT, 2, a->esz);
-    desc = deposit32(desc, SIMD_DATA_SHIFT + 2, 2, high_odd);
+    desc = FIELD_DP32(desc, PREDDESC, OPRSZ, vsz);
+    desc = FIELD_DP32(desc, PREDDESC, ESZ, a->esz);
+    desc = FIELD_DP32(desc, PREDDESC, DATA, high_odd);
 
     tcg_gen_addi_ptr(t_d, cpu_env, pred_full_reg_offset(s, a->rd));
     tcg_gen_addi_ptr(t_n, cpu_env, pred_full_reg_offset(s, a->rn));
-- 
2.25.1



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

* [PATCH v2 4/4] target/arm: Update REV, PUNPK for pred_desc
  2021-01-13  6:26 [PATCH v2 0/4] target/arm: Fix sve pred_desc decoding Richard Henderson
                   ` (2 preceding siblings ...)
  2021-01-13  6:26 ` [PATCH v2 3/4] target/arm: Update ZIP, UZP, TRN " Richard Henderson
@ 2021-01-13  6:26 ` Richard Henderson
  2021-01-19 11:28 ` [PATCH v2 0/4] target/arm: Fix sve pred_desc decoding Peter Maydell
  4 siblings, 0 replies; 6+ messages in thread
From: Richard Henderson @ 2021-01-13  6:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, qemu-arm, qemu-stable

Update all users of do_perm_pred2 for the new
predicate descriptor field definitions.

Cc: qemu-stable@nongnu.org
Buglink: https://bugs.launchpad.net/bugs/1908551
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/sve_helper.c    |  8 ++++----
 target/arm/translate-sve.c | 13 ++++---------
 2 files changed, 8 insertions(+), 13 deletions(-)

diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
index 7eec4b6b73..844db08bd5 100644
--- a/target/arm/sve_helper.c
+++ b/target/arm/sve_helper.c
@@ -2036,8 +2036,8 @@ static uint8_t reverse_bits_8(uint8_t x, int n)
 
 void HELPER(sve_rev_p)(void *vd, void *vn, uint32_t pred_desc)
 {
-    intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
-    int esz = extract32(pred_desc, SIMD_DATA_SHIFT, 2);
+    intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
+    int esz = FIELD_EX32(pred_desc, PREDDESC, ESZ);
     intptr_t i, oprsz_2 = oprsz / 2;
 
     if (oprsz <= 8) {
@@ -2066,8 +2066,8 @@ void HELPER(sve_rev_p)(void *vd, void *vn, uint32_t pred_desc)
 
 void HELPER(sve_punpk_p)(void *vd, void *vn, uint32_t pred_desc)
 {
-    intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
-    intptr_t high = extract32(pred_desc, SIMD_DATA_SHIFT + 2, 1);
+    intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
+    intptr_t high = FIELD_EX32(pred_desc, PREDDESC, DATA);
     uint64_t *d = vd;
     intptr_t i;
 
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 0baca176a0..27402af23c 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -2145,19 +2145,14 @@ static bool do_perm_pred2(DisasContext *s, arg_rr_esz *a, bool high_odd,
     TCGv_ptr t_d = tcg_temp_new_ptr();
     TCGv_ptr t_n = tcg_temp_new_ptr();
     TCGv_i32 t_desc;
-    int desc;
+    uint32_t desc = 0;
 
     tcg_gen_addi_ptr(t_d, cpu_env, pred_full_reg_offset(s, a->rd));
     tcg_gen_addi_ptr(t_n, cpu_env, pred_full_reg_offset(s, a->rn));
 
-    /* Predicate sizes may be smaller and cannot use simd_desc.
-       We cannot round up, as we do elsewhere, because we need
-       the exact size for ZIP2 and REV.  We retain the style for
-       the other helpers for consistency.  */
-
-    desc = vsz - 2;
-    desc = deposit32(desc, SIMD_DATA_SHIFT, 2, a->esz);
-    desc = deposit32(desc, SIMD_DATA_SHIFT + 2, 2, high_odd);
+    desc = FIELD_DP32(desc, PREDDESC, OPRSZ, vsz);
+    desc = FIELD_DP32(desc, PREDDESC, ESZ, a->esz);
+    desc = FIELD_DP32(desc, PREDDESC, DATA, high_odd);
     t_desc = tcg_const_i32(desc);
 
     fn(t_d, t_n, t_desc);
-- 
2.25.1



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

* Re: [PATCH v2 0/4] target/arm: Fix sve pred_desc decoding
  2021-01-13  6:26 [PATCH v2 0/4] target/arm: Fix sve pred_desc decoding Richard Henderson
                   ` (3 preceding siblings ...)
  2021-01-13  6:26 ` [PATCH v2 4/4] target/arm: Update REV, PUNPK " Richard Henderson
@ 2021-01-19 11:28 ` Peter Maydell
  4 siblings, 0 replies; 6+ messages in thread
From: Peter Maydell @ 2021-01-19 11:28 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-arm, QEMU Developers

On Wed, 13 Jan 2021 at 06:26, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> There was an inconsistency between encoding, which uses
> SIMD_DATA_SHIFT, and decoding which used SIMD_OPRSZ_BITS.
> This happened to be ok, until e2e7168a214, which reduced
> the size of SIMD_OPRSZ_BITS, which lead to truncating all
> predicate vector lengths.
>
> Changes in v2:
>   * Introduce and use PREDDESC field definitions, rather
>     than abusing a different SIMD_* macro.
>
>
> r~
>
>
> Richard Henderson (4):
>   target/arm: Introduce PREDDESC field definitions
>   target/arm: Update PFIRST, PNEXT for pred_desc
>   target/arm: Update ZIP, UZP, TRN for pred_desc
>   target/arm: Update REV, PUNPK for pred_desc

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

and applied to target-arm.next.

thanks
-- PMM


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

end of thread, other threads:[~2021-01-19 11:29 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-13  6:26 [PATCH v2 0/4] target/arm: Fix sve pred_desc decoding Richard Henderson
2021-01-13  6:26 ` [PATCH v2 1/4] target/arm: Introduce PREDDESC field definitions Richard Henderson
2021-01-13  6:26 ` [PATCH v2 2/4] target/arm: Update PFIRST, PNEXT for pred_desc Richard Henderson
2021-01-13  6:26 ` [PATCH v2 3/4] target/arm: Update ZIP, UZP, TRN " Richard Henderson
2021-01-13  6:26 ` [PATCH v2 4/4] target/arm: Update REV, PUNPK " Richard Henderson
2021-01-19 11:28 ` [PATCH v2 0/4] target/arm: Fix sve pred_desc decoding 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).