Re: [PATCH v2 06/18] target/riscv: Add packed SIMD shift instructions

MOLLY CHEN <[email protected]>
Newsgroups org.nongnu.qemu-riscv,org.nongnu.qemu-devel
Message-ID <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.