* [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