on 2026/8/20 0:10, Max Chou wrote:

On 2026-07-17 10:06, Molly Chen wrote:
Signed-off-by: Molly Chen<[email protected]>
---
  target/riscv/helper.h                       |  43 ++++++
  target/riscv/insn32.decode                  |  57 ++++++++
  target/riscv/tcg/insn_trans/trans_rvp.c.inc |  43 ++++++
  target/riscv/tcg/psimd_helper.c             | 149 ++++++++++++++++++++
  4 files changed, 292 insertions(+)
...
diff --git a/target/riscv/tcg/psimd_helper.c b/target/riscv/tcg/psimd_helper.c
index 034afe5a054..8b106a336f5 100644
--- a/target/riscv/tcg/psimd_helper.c
+++ b/target/riscv/tcg/psimd_helper.c
@@ -1903,3 +1903,152 @@ GEN_PSIMD_BINOP(mslt, uint32_t, int32_t, uint32_t,
  GEN_PSIMD_BINOP(msltu, uint32_t, uint32_t, uint32_t,
                  EXTRACT32, INSERT32, ELEMS_W, PSIMD_DO_LT_MASK)
+/* Shift operations (immediate and register) */
+
+GEN_PSIMD_SHIFTOP(pslli_b, target_ulong, uint8_t, uint8_t,
+                  EXTRACT8, INSERT8, ELEMS_B, 0x07, PSIMD_DO_SLL)
+GEN_PSIMD_SHIFTOP(psll_bs, target_ulong, uint8_t, uint8_t,
+                  EXTRACT8, INSERT8, ELEMS_B, 0x07, PSIMD_DO_SLL)
The spec instead specifies a uniform 5-bit mask (shamt = X[rs2][4:0]),
regardless of element width.
So the SHMASK should be 0x1f for PSLL/PSRL/PSRA.[BS|HS] instructions.

...

|You are right. The byte and halfword shift forms should both use the low 5 bits of rs2. I will change their SHMASK arguments to 0x1f in the next revision.|

+
+/**
+ * SSHAR - 32-bit scalar variable shift with rounding and saturation
+ */
+uint32_t HELPER(sshar)(CPURISCVState *env, uint32_t rs1, uint32_t rs2)
+{
+    int32_t a = (int32_t)rs1;
+    int8_t shamt = (int8_t)(rs2 & 0xFF);
+    int sat = 0;
+    int32_t res;
+
+    if (shamt >= 0) {
+        int64_t shifted = (int64_t)a << shamt;
+        res = signed_saturate_w(shifted, &sat);
+    } else {
+        int right = -shamt;
+        if (right >= 32) {
+            res = (a < 0) ? -1 : 0;
According to the p ext isa spec, SSHAR here extracts a sign-filled
33-bit value and then applies RNU rounding. The result here should be
0 for both positive and negative inputs.

Yes, I will fix it.


+        } else {
+            int64_t rounded = ((a >> (right - 1)) + 1) >> 1;
Here may has undefined behavior for negative sources at in-range
amounts.

|Right-shifting a negative signed integer is implementation-defined, rather than undefined. QEMU already relies on the supported compilers performing an arithmetic right shift in this case. However, the expression does contain a real undefined-behavior case for a positive source: when e1 is INT32_MAX and right is 1, the addition of one overflows before the result is assigned to WTYPE. I will cast e1 to WTYPE before the first shift so that the shift and rounding addition are both evaluated in the wider type.|


I think that we could extract the SSHAR implementation from
GEN_PSIMD_VAR_SSHAR and share it between here and
GEN_PSIMD_VAR_SSHAR.

|Good suggestion. I will extract the common SSHAR operation into a shared helper and use it for both implementations in the next revision.|
||
|Thanks for the review.|
Molly

Reply via email to