@@ -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;
}
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(-)