qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 2/4] target/riscv: Add right functions to set agnostic elements


From: Huang Tao
Subject: [PATCH 2/4] target/riscv: Add right functions to set agnostic elements
Date: Wed, 6 Mar 2024 17:20:10 +0800

We add vext_set_elems_1s to set agnostic elements to 1s in both big
and little endian situation.
In the function vext_set_elems_1s. We using esz argument to get the first
element to set. 'cnt' is just idx * esz.

Signed-off-by: Huang Tao <eric.huang@linux.alibaba.com>
---
 target/riscv/vector_internals.c | 53 +++++++++++++++++++++++++++++++++
 target/riscv/vector_internals.h |  2 ++
 2 files changed, 55 insertions(+)

diff --git a/target/riscv/vector_internals.c b/target/riscv/vector_internals.c
index 349b24f4ae..455be96996 100644
--- a/target/riscv/vector_internals.c
+++ b/target/riscv/vector_internals.c
@@ -20,6 +20,59 @@
 #include "vector_internals.h"
 
 /* set agnostic elements to 1s */
+#if HOST_BIG_ENDIAN
+void vext_set_elems_1s(void *vd, uint32_t is_agnostic, uint32_t esz,
+                       uint32_t idx, uint32_t tot)
+{
+    if (is_agnostic == 0) {
+        /* policy undisturbed */
+        return;
+    }
+    void *base = NULL;
+    switch (esz) {
+    case 1:
+        base = ((int8_t *)vd + H1(idx));
+    break;
+    case 2:
+        base = ((int16_t *)vd + H2(idx));
+    break;
+    case 4:
+        base = ((int32_t *)vd + H4(idx));
+    break;
+    case 8:
+        base = ((int64_t *)vd + H8(idx));
+    break;
+    default:
+        g_assert_not_reached();
+    break;
+    }
+    /*
+     * spilt the elements into 2 parts
+     * part_begin: the memory need to be set in the first uint64_t unit
+     * part_allign: the memory need to be set begins from next uint64_t
+     *              unit and alligned to 8
+     */
+    uint32_t cnt = idx * esz;
+    int part_begin, part_allign;
+    part_begin = MIN(tot - cnt, 8 - (cnt % 8));
+    part_allign = ((tot - cnt - part_begin) / 8) * 8;
+
+    memset(base - part_begin + 1, -1, part_begin);
+    memset(QEMU_ALIGN_PTR_UP(base, 8), -1, part_allign);
+}
+#else
+void vext_set_elems_1s(void *vd, uint32_t is_agnostic, uint32_t esz,
+                       uint32_t idx, uint32_t tot)
+{
+    if (is_agnostic == 0) {
+        /* policy undisturbed */
+        return;
+    }
+    uint32_t cnt = idx * esz;
+    memset(vd + cnt, -1, tot - cnt);
+}
+#endif
+
 void vext_set_elems_1s_le(void *base, uint32_t is_agnostic, uint32_t cnt,
                        uint32_t tot)
 {
diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h
index fa599f60ca..c96e52f926 100644
--- a/target/riscv/vector_internals.h
+++ b/target/riscv/vector_internals.h
@@ -114,6 +114,8 @@ static inline uint32_t vext_get_total_elems(CPURISCVState 
*env, uint32_t desc,
 }
 
 /* set agnostic elements to 1s */
+void vext_set_elems_1s(void *vd, uint32_t is_agnostic, uint32_t esz,
+                       uint32_t idx, uint32_t tot);
 void vext_set_elems_1s_le(void *base, uint32_t is_agnostic, uint32_t cnt,
                        uint32_t tot);
 
-- 
2.41.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]