diff mbox series

[v8,02/10] target/riscv: handle vstart >= vl in vext_set_tail_elems_1s()

Message ID 20240308215402.117405-3-dbarboza@ventanamicro.com (mailing list archive)
State New, archived
Headers show
Series riscv: set vstart_eq_zero on mark_vs_dirty | expand

Commit Message

Daniel Henrique Barboza March 8, 2024, 9:53 p.m. UTC
We're going to make changes that will required each helper to be
responsible for the 'vstart' management, i.e. we will relieve the
'vstart < vl' assumption that helpers have today.

To do that we'll need to deal with how we're updating tail elements
first. We can't update them if vstart >= vl.

We already have the vext_set_tail_elems_1s() helper to update tail
elements.  Change it to accept an 'env' pointer, where we can read both
vstart and vl, and make it a no-op if vstart >= vl. Note that the
callers will need to set env->start after the helper from now on.

We'll enforce the use of this helper to update tail elements on all
instructions, making everyone able to skip the tail update if vstart
isn't adequate.

Let's also simplify the API a little by removing the 'nf' argument since
it can be derived from 'desc'.

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
---
 target/riscv/vector_helper.c | 30 +++++++++++++++++-------------
 1 file changed, 17 insertions(+), 13 deletions(-)

Comments

Richard Henderson March 9, 2024, 6:40 p.m. UTC | #1
On 3/8/24 11:53, Daniel Henrique Barboza wrote:
> +static void vext_set_tail_elems_1s(CPURISCVState *env, void *vd,
> +                                   uint32_t desc, uint32_t esz,
> +                                   uint32_t max_elems)
>   {
>       uint32_t vta = vext_vta(desc);
> +    uint32_t nf = vext_nf(desc);
>       int k;
>   
> -    if (vta == 0) {
> +    /*
> +     * Section 5.4 of the RVV spec mentions:
> +     * "When vstart ≥ vl, there are no body elements, and no
> +     *  elements are updated in any destination vector register
> +     *  group, including that no tail elements are updated
> +     *  with agnostic values."
> +     */
> +    if (vta == 0 || env->vstart >= env->vl) {
>           return;
>       }

This isn't going to work for ...

> @@ -222,9 +230,8 @@ vext_ldst_stride(void *vd, void *v0, target_ulong base,
>               k++;
>           }
>       }
> +    vext_set_tail_elems_1s(env, vd, desc, esz, max_elems);
>       env->vstart = 0;

... ldst, because we also need to increment vstart in the load loop, for consumption by 
the exception path.

You'll need to structure the helper as

     if (vstart >= vl) {
        vstart = 0;
        return;
     }
     for (i = vstart; i < vl; vstart = ++i) {
         ...
     }
     set_tail_elems(...);
     vstart = 0;


r~
diff mbox series

Patch

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index ca79571ae2..db1d3f77ce 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -174,19 +174,27 @@  GEN_VEXT_ST_ELEM(ste_h, int16_t, H2, stw)
 GEN_VEXT_ST_ELEM(ste_w, int32_t, H4, stl)
 GEN_VEXT_ST_ELEM(ste_d, int64_t, H8, stq)
 
-static void vext_set_tail_elems_1s(target_ulong vl, void *vd,
-                                   uint32_t desc, uint32_t nf,
-                                   uint32_t esz, uint32_t max_elems)
+static void vext_set_tail_elems_1s(CPURISCVState *env, void *vd,
+                                   uint32_t desc, uint32_t esz,
+                                   uint32_t max_elems)
 {
     uint32_t vta = vext_vta(desc);
+    uint32_t nf = vext_nf(desc);
     int k;
 
-    if (vta == 0) {
+    /*
+     * Section 5.4 of the RVV spec mentions:
+     * "When vstart ≥ vl, there are no body elements, and no
+     *  elements are updated in any destination vector register
+     *  group, including that no tail elements are updated
+     *  with agnostic values."
+     */
+    if (vta == 0 || env->vstart >= env->vl) {
         return;
     }
 
     for (k = 0; k < nf; ++k) {
-        vext_set_elems_1s(vd, vta, (k * max_elems + vl) * esz,
+        vext_set_elems_1s(vd, vta, (k * max_elems + env->vl) * esz,
                           (k * max_elems + max_elems) * esz);
     }
 }
@@ -222,9 +230,8 @@  vext_ldst_stride(void *vd, void *v0, target_ulong base,
             k++;
         }
     }
+    vext_set_tail_elems_1s(env, vd, desc, esz, max_elems);
     env->vstart = 0;
-
-    vext_set_tail_elems_1s(env->vl, vd, desc, nf, esz, max_elems);
 }
 
 #define GEN_VEXT_LD_STRIDE(NAME, ETYPE, LOAD_FN)                        \
@@ -281,9 +288,8 @@  vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc,
             k++;
         }
     }
+    vext_set_tail_elems_1s(env, vd, desc, esz, max_elems);
     env->vstart = 0;
-
-    vext_set_tail_elems_1s(evl, vd, desc, nf, esz, max_elems);
 }
 
 /*
@@ -402,9 +408,8 @@  vext_ldst_index(void *vd, void *v0, target_ulong base,
             k++;
         }
     }
+    vext_set_tail_elems_1s(env, vd, desc, esz, max_elems);
     env->vstart = 0;
-
-    vext_set_tail_elems_1s(env->vl, vd, desc, nf, esz, max_elems);
 }
 
 #define GEN_VEXT_LD_INDEX(NAME, ETYPE, INDEX_FN, LOAD_FN)                  \
@@ -532,9 +537,8 @@  ProbeSuccess:
             k++;
         }
     }
+    vext_set_tail_elems_1s(env, vd, desc, esz, max_elems);
     env->vstart = 0;
-
-    vext_set_tail_elems_1s(env->vl, vd, desc, nf, esz, max_elems);
 }
 
 #define GEN_VEXT_LDFF(NAME, ETYPE, LOAD_FN)               \