diff mbox series

[v3,19/20] target/riscv: Adjust scalar reg in vector with XLEN

Message ID 20211111055800.42672-20-zhiwei_liu@c-sky.com
State New
Headers show
Series Support UXL filed in xstatus | expand

Commit Message

LIU Zhiwei Nov. 11, 2021, 5:57 a.m. UTC
When sew <= 32bits, not need to extend scalar reg.
When sew > 32bits, if xlen is less that sew, we should sign extend
the scalar register, except explicitly specified by the spec.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
---
 target/riscv/insn_trans/trans_rvv.c.inc | 44 ++++++++++++++++++-------
 1 file changed, 32 insertions(+), 12 deletions(-)

Comments

Richard Henderson Nov. 11, 2021, 11:46 a.m. UTC | #1
On 11/11/21 6:57 AM, LIU Zhiwei wrote:
> @@ -2670,6 +2672,7 @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
>           /* This instruction ignores LMUL and vector register groups */
>           int maxsz = s->vlen >> 3;
>           TCGv_i64 t1;
> +        TCGv src1 = get_gpr(s, a->rs1, EXT_ZERO);

A reminder that this is zero-extend for v0.7.1 and sign-extend for v1.0.0.

> @@ -2679,7 +2682,7 @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
>           }
>   
>           t1 = tcg_temp_new_i64();
> -        tcg_gen_extu_tl_i64(t1, cpu_gpr[a->rs1]);
> +        tcg_gen_extu_tl_i64(t1, src1);

Likewise.

>           vec_element_storei(s, a->rd, 0, t1);
>           tcg_temp_free_i64(t1);
>       done:
> @@ -2748,12 +2751,28 @@ static bool slideup_check(DisasContext *s, arg_rmrr *a)
>               (a->rd != a->rs2));
>   }
>   
> +/* OPIVXU without GVEC IR */
> +#define GEN_OPIVXU_TRANS(NAME, CHECK)                                    \
> +static bool trans_##NAME(DisasContext *s, arg_rmrr *a)                   \
> +{                                                                        \
> +    if (CHECK(s, a)) {                                                   \
> +        static gen_helper_opivx * const fns[4] = {                       \
> +            gen_helper_##NAME##_b, gen_helper_##NAME##_h,                \
> +            gen_helper_##NAME##_w, gen_helper_##NAME##_d,                \
> +        };                                                               \
> +                                                                         \
> +        return opivx_trans(a->rd, a->rs1, a->rs2, a->vm,                 \
> +                           fns[s->sew], s, EXT_ZERO);                    \
> +    }                                                                    \
> +    return false;                                                        \
> +}
> +
>   GEN_OPIVX_TRANS(vslideup_vx, slideup_check)
> -GEN_OPIVX_TRANS(vslide1up_vx, slideup_check)
> +GEN_OPIVXU_TRANS(vslide1up_vx, slideup_check)
>   GEN_OPIVI_TRANS(vslideup_vi, 1, vslideup_vx, slideup_check)
>   
>   GEN_OPIVX_TRANS(vslidedown_vx, opivx_check)
> -GEN_OPIVX_TRANS(vslide1down_vx, opivx_check)
> +GEN_OPIVXU_TRANS(vslide1down_vx, opivx_check)
>   GEN_OPIVI_TRANS(vslidedown_vi, 1, vslidedown_vx, opivx_check)

Likewise.

So if this patch set goes in after rvv 1.0, this whole patch may be dropped.


r~
LIU Zhiwei Nov. 11, 2021, 2:43 p.m. UTC | #2
On 2021/11/11 下午7:46, Richard Henderson wrote:

> On 11/11/21 6:57 AM, LIU Zhiwei wrote:
>> @@ -2670,6 +2672,7 @@ static bool trans_vmv_s_x(DisasContext *s, 
>> arg_vmv_s_x *a)
>>           /* This instruction ignores LMUL and vector register groups */
>>           int maxsz = s->vlen >> 3;
>>           TCGv_i64 t1;
>> +        TCGv src1 = get_gpr(s, a->rs1, EXT_ZERO);
>
> A reminder that this is zero-extend for v0.7.1 and sign-extend for 
> v1.0.0.
>
>> @@ -2679,7 +2682,7 @@ static bool trans_vmv_s_x(DisasContext *s, 
>> arg_vmv_s_x *a)
>>           }
>>             t1 = tcg_temp_new_i64();
>> -        tcg_gen_extu_tl_i64(t1, cpu_gpr[a->rs1]);
>> +        tcg_gen_extu_tl_i64(t1, src1);
>
> Likewise.
>
>>           vec_element_storei(s, a->rd, 0, t1);
>>           tcg_temp_free_i64(t1);
>>       done:
>> @@ -2748,12 +2751,28 @@ static bool slideup_check(DisasContext *s, 
>> arg_rmrr *a)
>>               (a->rd != a->rs2));
>>   }
>>   +/* OPIVXU without GVEC IR */
>> +#define GEN_OPIVXU_TRANS(NAME, 
>> CHECK)                                    \
>> +static bool trans_##NAME(DisasContext *s, arg_rmrr 
>> *a)                   \
>> +{ \
>> +    if (CHECK(s, a)) 
>> {                                                   \
>> +        static gen_helper_opivx * const fns[4] = 
>> {                       \
>> +            gen_helper_##NAME##_b, 
>> gen_helper_##NAME##_h,                \
>> +            gen_helper_##NAME##_w, 
>> gen_helper_##NAME##_d,                \
>> + }; \
>> + \
>> +        return opivx_trans(a->rd, a->rs1, a->rs2, 
>> a->vm,                 \
>> +                           fns[s->sew], s, 
>> EXT_ZERO);                    \
>> + } \
>> +    return 
>> false;                                                        \
>> +}
>> +
>>   GEN_OPIVX_TRANS(vslideup_vx, slideup_check)
>> -GEN_OPIVX_TRANS(vslide1up_vx, slideup_check)
>> +GEN_OPIVXU_TRANS(vslide1up_vx, slideup_check)
>>   GEN_OPIVI_TRANS(vslideup_vi, 1, vslideup_vx, slideup_check)
>>     GEN_OPIVX_TRANS(vslidedown_vx, opivx_check)
>> -GEN_OPIVX_TRANS(vslide1down_vx, opivx_check)
>> +GEN_OPIVXU_TRANS(vslide1down_vx, opivx_check)
>>   GEN_OPIVI_TRANS(vslidedown_vi, 1, vslidedown_vx, opivx_check)
>
> Likewise.
>
> So if this patch set goes in after rvv 1.0, this whole patch may be 
> dropped.
>
Got it.

Thanks,
Zhiwei

>
> r~
diff mbox series

Patch

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index 41c7c88904..7301992f82 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -833,7 +833,7 @@  typedef void gen_helper_opivx(TCGv_ptr, TCGv_ptr, TCGv, TCGv_ptr,
                               TCGv_env, TCGv_i32);
 
 static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
-                        gen_helper_opivx *fn, DisasContext *s)
+                        gen_helper_opivx *fn, DisasContext *s, DisasExtend ext)
 {
     TCGv_ptr dest, src2, mask;
     TCGv src1;
@@ -846,7 +846,7 @@  static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
     dest = tcg_temp_new_ptr();
     mask = tcg_temp_new_ptr();
     src2 = tcg_temp_new_ptr();
-    src1 = get_gpr(s, rs1, EXT_NONE);
+    src1 = get_gpr(s, rs1, ext);
 
     data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
     data = FIELD_DP32(data, VDATA, VM, vm);
@@ -895,7 +895,7 @@  do_opivx_gvec(DisasContext *s, arg_rmrr *a, GVecGen2sFn *gvec_fn,
         tcg_temp_free_i64(src1);
         return true;
     }
-    return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s);
+    return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s, EXT_SIGN);
 }
 
 /* OPIVX with GVEC IR */
@@ -1128,7 +1128,7 @@  static bool do_opivx_widen(DisasContext *s, arg_rmrr *a,
                            gen_helper_opivx *fn)
 {
     if (opivx_widen_check(s, a)) {
-        return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s);
+        return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s, EXT_SIGN);
     }
     return false;
 }
@@ -1213,7 +1213,7 @@  static bool do_opiwx_widen(DisasContext *s, arg_rmrr *a,
                            gen_helper_opivx *fn)
 {
     if (opiwx_widen_check(s, a)) {
-        return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s);
+        return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s, EXT_SIGN);
     }
     return false;
 }
@@ -1312,7 +1312,8 @@  static bool trans_##NAME(DisasContext *s, arg_rmrr *a)                   \
             gen_helper_##NAME##_w, gen_helper_##NAME##_d,                \
         };                                                               \
                                                                          \
-        return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew], s);\
+        return opivx_trans(a->rd, a->rs1, a->rs2, a->vm,                 \
+                           fns[s->sew], s, EXT_SIGN);                    \
     }                                                                    \
     return false;                                                        \
 }
@@ -1386,7 +1387,7 @@  do_opivx_gvec_shift(DisasContext *s, arg_rmrr *a, GVecGen2sFn32 *gvec_fn,
         tcg_temp_free_i32(src1);
         return true;
     }
-    return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s);
+    return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s, EXT_SIGN);
 }
 
 #define GEN_OPIVX_GVEC_SHIFT_TRANS(NAME, SUF) \
@@ -1472,7 +1473,8 @@  static bool trans_##NAME(DisasContext *s, arg_rmrr *a)                   \
             gen_helper_##NAME##_h,                                       \
             gen_helper_##NAME##_w,                                       \
         };                                                               \
-        return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew], s);\
+        return opivx_trans(a->rd, a->rs1, a->rs2, a->vm,                 \
+                           fns[s->sew], s, EXT_SIGN);                    \
     }                                                                    \
     return false;                                                        \
 }
@@ -2670,6 +2672,7 @@  static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
         /* This instruction ignores LMUL and vector register groups */
         int maxsz = s->vlen >> 3;
         TCGv_i64 t1;
+        TCGv src1 = get_gpr(s, a->rs1, EXT_ZERO);
         TCGLabel *over = gen_new_label();
 
         tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
@@ -2679,7 +2682,7 @@  static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
         }
 
         t1 = tcg_temp_new_i64();
-        tcg_gen_extu_tl_i64(t1, cpu_gpr[a->rs1]);
+        tcg_gen_extu_tl_i64(t1, src1);
         vec_element_storei(s, a->rd, 0, t1);
         tcg_temp_free_i64(t1);
     done:
@@ -2748,12 +2751,28 @@  static bool slideup_check(DisasContext *s, arg_rmrr *a)
             (a->rd != a->rs2));
 }
 
+/* OPIVXU without GVEC IR */
+#define GEN_OPIVXU_TRANS(NAME, CHECK)                                    \
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a)                   \
+{                                                                        \
+    if (CHECK(s, a)) {                                                   \
+        static gen_helper_opivx * const fns[4] = {                       \
+            gen_helper_##NAME##_b, gen_helper_##NAME##_h,                \
+            gen_helper_##NAME##_w, gen_helper_##NAME##_d,                \
+        };                                                               \
+                                                                         \
+        return opivx_trans(a->rd, a->rs1, a->rs2, a->vm,                 \
+                           fns[s->sew], s, EXT_ZERO);                    \
+    }                                                                    \
+    return false;                                                        \
+}
+
 GEN_OPIVX_TRANS(vslideup_vx, slideup_check)
-GEN_OPIVX_TRANS(vslide1up_vx, slideup_check)
+GEN_OPIVXU_TRANS(vslide1up_vx, slideup_check)
 GEN_OPIVI_TRANS(vslideup_vi, 1, vslideup_vx, slideup_check)
 
 GEN_OPIVX_TRANS(vslidedown_vx, opivx_check)
-GEN_OPIVX_TRANS(vslide1down_vx, opivx_check)
+GEN_OPIVXU_TRANS(vslide1down_vx, opivx_check)
 GEN_OPIVI_TRANS(vslidedown_vi, 1, vslidedown_vx, opivx_check)
 
 /* Vector Register Gather Instruction */
@@ -2803,7 +2822,8 @@  static bool trans_vrgather_vx(DisasContext *s, arg_rmrr *a)
             gen_helper_vrgather_vx_b, gen_helper_vrgather_vx_h,
             gen_helper_vrgather_vx_w, gen_helper_vrgather_vx_d
         };
-        return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew], s);
+        return opivx_trans(a->rd, a->rs1, a->rs2, a->vm,
+                           fns[s->sew], s, EXT_SIGN);
     }
     return true;
 }