Provide a helper that 1's element I for all NF vectors.
For the callers, this performs the element mask test once
instead of NF times.

Signed-off-by: Richard Henderson <[email protected]>
---
 target/riscv/tcg/vector_helper.c | 69 ++++++++++++++++----------------
 1 file changed, 34 insertions(+), 35 deletions(-)

diff --git a/target/riscv/tcg/vector_helper.c b/target/riscv/tcg/vector_helper.c
index e28d8a3d9f..20a8f95efb 100644
--- a/target/riscv/tcg/vector_helper.c
+++ b/target/riscv/tcg/vector_helper.c
@@ -328,6 +328,15 @@ static void vext_set_tail_elems_1s(uint32_t vl, void *vd,
     }
 }
 
+static void vext_set_nf_elems_1s(void *vd, uint32_t i, uint32_t nf,
+                                 uint32_t esz, uint32_t max_elems)
+{
+    for (uint32_t k = 0; k < nf; ++k) {
+        vext_set_elems_1s(vd, true, (i + k * max_elems) * esz,
+                          (i + k * max_elems + 1) * esz);
+    }
+}
+
 /*
  * stride: access vector element from strided memory
  */
@@ -337,7 +346,6 @@ vext_ldst_stride(void *vd, void *v0, target_ulong base, 
target_ulong stride,
                  vext_ldst_elem_fn_tlb *ldst_elem, uint32_t log2_esz,
                  uintptr_t ra)
 {
-    uint32_t i, k;
     uint32_t nf = vext_nf(desc);
     uint32_t max_elems = vext_max_elems(desc, log2_esz);
     uint32_t esz = 1 << log2_esz;
@@ -345,23 +353,21 @@ vext_ldst_stride(void *vd, void *v0, target_ulong base, 
target_ulong stride,
 
     VSTART_CHECK_EARLY_EXIT(env, env->vl);
 
-    for (i = env->vstart; i < env->vl; env->vstart = ++i) {
-        k = 0;
-        while (k < nf) {
-            if (!vm && !vext_elem_mask(v0, i)) {
-                /* set masked-off elements to 1s */
-                vext_set_elems_1s(vd, vma, (i + k * max_elems) * esz,
-                                  (i + k * max_elems + 1) * esz);
-                k++;
-                continue;
+    for (uint32_t i = env->vstart; i < env->vl; env->vstart = ++i) {
+        if (!vm && !vext_elem_mask(v0, i)) {
+            if (vma) {
+                vext_set_nf_elems_1s(vd, i, nf, esz, max_elems);
             }
+            continue;
+        }
+
+        for (uint32_t k = 0; k < nf; ++k) {
             target_ulong addr = base + stride * i + (k << log2_esz);
             ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
-            k++;
         }
     }
-    env->vstart = 0;
 
+    env->vstart = 0;
     vext_set_tail_elems_1s(env->vl, vd, desc, nf, esz, max_elems);
 }
 
@@ -632,7 +638,6 @@ vext_ldst_index(void *vd, void *v0, target_ulong base,
                 vext_ldst_elem_fn_tlb *ldst_elem,
                 uint32_t log2_esz, uintptr_t ra)
 {
-    uint32_t i, k;
     uint32_t nf = vext_nf(desc);
     uint32_t vm = vext_vm(desc);
     uint32_t max_elems = vext_max_elems(desc, log2_esz);
@@ -641,24 +646,21 @@ vext_ldst_index(void *vd, void *v0, target_ulong base,
 
     VSTART_CHECK_EARLY_EXIT(env, env->vl);
 
-    /* load bytes from guest memory */
-    for (i = env->vstart; i < env->vl; env->vstart = ++i) {
-        k = 0;
-        while (k < nf) {
-            if (!vm && !vext_elem_mask(v0, i)) {
-                /* set masked-off elements to 1s */
-                vext_set_elems_1s(vd, vma, (i + k * max_elems) * esz,
-                                  (i + k * max_elems + 1) * esz);
-                k++;
-                continue;
+    for (uint32_t i = env->vstart; i < env->vl; env->vstart = ++i) {
+        if (!vm && !vext_elem_mask(v0, i)) {
+            if (vma) {
+                vext_set_nf_elems_1s(vd, i, nf, esz, max_elems);
             }
+            continue;
+        }
+
+        for (uint32_t k = 0; k < nf; ++k) {
             abi_ptr addr = get_index_addr(base, i, vs2) + (k << log2_esz);
             ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
-            k++;
         }
     }
-    env->vstart = 0;
 
+    env->vstart = 0;
     vext_set_tail_elems_1s(env->vl, vd, desc, nf, esz, max_elems);
 }
 
@@ -824,25 +826,22 @@ ProbeSuccess:
             }
         } else {
             for (i = env->vstart; i < env->vl; i++) {
-                k = 0;
-                while (k < nf) {
-                    if (!vext_elem_mask(v0, i)) {
-                        /* set masked-off elements to 1s */
-                        vext_set_elems_1s(vd, vma, (i + k * max_elems) * esz,
-                                          (i + k * max_elems + 1) * esz);
-                        k++;
-                        continue;
+                if (!vext_elem_mask(v0, i)) {
+                    if (vma) {
+                        vext_set_nf_elems_1s(vd, i, nf, esz, max_elems);
                     }
+                    continue;
+                }
+                for (k = 0; k < nf; ++k) {
                     addr = base + ((i * nf + k) << log2_esz);
                     ldst_tlb(env, adjust_addr(env, addr), i + k * max_elems,
                              vd, ra);
-                    k++;
                 }
             }
         }
     }
-    env->vstart = 0;
 
+    env->vstart = 0;
     vext_set_tail_elems_1s(env->vl, vd, desc, nf, esz, max_elems);
 }
 
-- 
2.43.0


Reply via email to