@@ -111,6 +111,9 @@ FIELD(VTYPE, VEDIV, 5, 2)
FIELD(VTYPE, RESERVED, 7, sizeof(target_ulong) * 8 - 9)
FIELD(VTYPE, VILL, sizeof(target_ulong) * 8 - 1, 1)
+FIELD(VTYPE, RESERVED_UXL32, 7, 23)
+FIELD(VTYPE, VILL_UXL32, 31, 1)
+
struct CPURISCVState {
target_ulong gpr[32];
uint64_t fpr[32]; /* assume both F and D extensions */
@@ -35,7 +35,7 @@ static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
/* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
s1 = tcg_constant_tl(RV_VLEN_MAX);
} else {
- s1 = gpr_src(ctx, a->rs1);
+ s1 = gpr_src_u(ctx, a->rs1);
}
gen_helper_vsetvl(dst, cpu_env, s1, s2);
@@ -61,7 +61,7 @@ static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a)
/* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
s1 = tcg_constant_tl(RV_VLEN_MAX);
} else {
- s1 = gpr_src(ctx, a->rs1);
+ s1 = gpr_src_u(ctx, a->rs1);
}
gen_helper_vsetvl(dst, cpu_env, s1, s2);
@@ -163,7 +163,7 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
dest = tcg_temp_new_ptr();
mask = tcg_temp_new_ptr();
- base = gpr_src(s, rs1);
+ base = gpr_src_u(s, rs1);
/*
* As simd_desc supports at most 256 bytes, and in this implementation,
@@ -318,8 +318,8 @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
dest = tcg_temp_new_ptr();
mask = tcg_temp_new_ptr();
- base = gpr_src(s, rs1);
- stride = gpr_src(s, rs2);
+ base = gpr_src_u(s, rs1);
+ stride = gpr_src_s(s, rs2);
desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
@@ -442,7 +442,7 @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
dest = tcg_temp_new_ptr();
mask = tcg_temp_new_ptr();
index = tcg_temp_new_ptr();
- base = gpr_src(s, rs1);
+ base = gpr_src_u(s, rs1);
desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
@@ -571,7 +571,7 @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
dest = tcg_temp_new_ptr();
mask = tcg_temp_new_ptr();
- base = gpr_src(s, rs1);
+ base = gpr_src_u(s, rs1);
desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
@@ -645,7 +645,7 @@ static bool amo_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
dest = tcg_temp_new_ptr();
mask = tcg_temp_new_ptr();
index = tcg_temp_new_ptr();
- base = gpr_src(s, rs1);
+ base = gpr_src_u(s, rs1);
desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
@@ -731,12 +731,13 @@ static bool amo_op(DisasContext *s, arg_rwdvm *a, uint8_t seq)
*/
static bool amo_check(DisasContext *s, arg_rwdvm* a)
{
- return (!s->vill && has_ext(s, RVA) &&
- (!a->wd || vext_check_overlap_mask(s, a->rd, a->vm, false)) &&
- vext_check_reg(s, a->rd, false) &&
- vext_check_reg(s, a->rs2, false) &&
- ((1 << s->sew) <= sizeof(target_ulong)) &&
- ((1 << s->sew) >= 4));
+ return !s->vill && has_ext(s, RVA) &&
+ (!a->wd || vext_check_overlap_mask(s, a->rd, a->vm, false)) &&
+ vext_check_reg(s, a->rd, false) &&
+ vext_check_reg(s, a->rs2, false) &&
+ (s->uxl32 ? ((1 << s->sew) == 4) :
+ (((1 << s->sew) <= sizeof(target_ulong)) &&
+ ((1 << s->sew) >= 4)));
}
static bool amo_check64(DisasContext *s, arg_rwdvm* a)
@@ -840,7 +841,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 = gpr_src(s, rs1);
+ src1 = gpr_src_s(s, rs1);
data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
data = FIELD_DP32(data, VDATA, VM, vm);
@@ -882,7 +883,7 @@ do_opivx_gvec(DisasContext *s, arg_rmrr *a, GVecGen2sFn *gvec_fn,
if (a->vm && s->vl_eq_vlmax) {
TCGv_i64 src1 = tcg_temp_new_i64();
- tcg_gen_ext_tl_i64(src1, gpr_src(s, a->rs1));
+ tcg_gen_ext_tl_i64(src1, gpr_src_s(s, a->rs1));
gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
src1, MAXSZ(s), MAXSZ(s));
@@ -1635,7 +1636,7 @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
TCGLabel *over = gen_new_label();
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
- s1 = gpr_src(s, a->rs1);
+ s1 = gpr_src_s(s, a->rs1);
if (s->vl_eq_vlmax) {
tcg_gen_gvec_dup_tl(s->sew, vreg_ofs(s, a->rd),
@@ -2609,6 +2610,9 @@ static bool trans_vext_x_v(DisasContext *s, arg_r *a)
} else {
/* This instruction ignores LMUL and vector register groups */
int vlmax = s->vlen >> (3 + s->sew);
+ if (s->uxl32) {
+ tcg_gen_ext32u_tl(cpu_gpr[a->rs1], cpu_gpr[a->rs1]);
+ }
vec_element_loadx(s, tmp, a->rs2, cpu_gpr[a->rs1], vlmax);
}
@@ -2667,6 +2671,9 @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
}
t1 = tcg_temp_new_i64();
+ if (s->uxl32) {
+ tcg_gen_ext32u_tl(cpu_gpr[a->rs1], cpu_gpr[a->rs1]);
+ }
tcg_gen_extu_tl_i64(t1, cpu_gpr[a->rs1]);
vec_element_storei(s, a->rd, 0, t1);
tcg_temp_free_i64(t1);
@@ -2780,6 +2787,9 @@ static bool trans_vrgather_vx(DisasContext *s, arg_rmrr *a)
if (a->rs1 == 0) {
vec_element_loadi(s, dest, a->rs2, 0);
} else {
+ if (unlikely(s->uxl32)) {
+ tcg_gen_ext32u_tl(cpu_gpr[a->rs1], cpu_gpr[a->rs1]);
+ }
vec_element_loadx(s, dest, a->rs2, cpu_gpr[a->rs1], vlmax);
}
@@ -35,10 +35,19 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
uint8_t ediv = FIELD_EX64(s2, VTYPE, VEDIV);
bool vill = FIELD_EX64(s2, VTYPE, VILL);
target_ulong reserved = FIELD_EX64(s2, VTYPE, RESERVED);
+ bool uxl32 = riscv_cpu_is_uxl32(env);
+ if (uxl32) {
+ vill = FIELD_EX64(s2, VTYPE, VILL_UXL32);
+ reserved = FIELD_EX64(s2, VTYPE, RESERVED_UXL32);
+ }
if ((sew > cpu->cfg.elen) || vill || (ediv != 0) || (reserved != 0)) {
/* only set vill bit. */
- env->vtype = FIELD_DP64(0, VTYPE, VILL, 1);
+ if (uxl32) {
+ env->vtype = FIELD_DP64(0, VTYPE, VILL_UXL32, 1);
+ } else {
+ env->vtype = FIELD_DP64(0, VTYPE, VILL, 1);
+ }
env->vl = 0;
env->vstart = 0;
return 0;
@@ -479,14 +488,18 @@ GEN_VEXT_ST_US(vse_v_d, int64_t, int64_t, ste_d)
/*
*** index: access vector element from indexed memory
*/
-typedef target_ulong vext_get_index_addr(target_ulong base,
- uint32_t idx, void *vs2);
+typedef target_ulong vext_get_index_addr(bool uxl32, target_ulong base,
+ uint32_t idx, void *vs2);
-#define GEN_VEXT_GET_INDEX_ADDR(NAME, ETYPE, H) \
-static target_ulong NAME(target_ulong base, \
- uint32_t idx, void *vs2) \
-{ \
- return (base + *((ETYPE *)vs2 + H(idx))); \
+#define GEN_VEXT_GET_INDEX_ADDR(NAME, ETYPE, H) \
+static target_ulong NAME(bool uxl32, target_ulong base, \
+ uint32_t idx, void *vs2) \
+{ \
+ if (uxl32) { \
+ return base + (int32_t)(*((ETYPE *)vs2 + H(idx))); \
+ } else { \
+ return base + *((ETYPE *)vs2 + H(idx)); \
+ } \
}
GEN_VEXT_GET_INDEX_ADDR(idx_b, int8_t, H1)
@@ -508,13 +521,14 @@ vext_ldst_index(void *vd, void *v0, target_ulong base,
uint32_t vm = vext_vm(desc);
uint32_t mlen = vext_mlen(desc);
uint32_t vlmax = vext_maxsz(desc) / esz;
+ bool uxl32 = riscv_cpu_is_uxl32(env);
/* probe every access*/
for (i = 0; i < env->vl; i++) {
if (!vm && !vext_elem_mask(v0, mlen, i)) {
continue;
}
- probe_pages(env, get_index_addr(base, i, vs2), nf * msz, ra,
+ probe_pages(env, get_index_addr(uxl32, base, i, vs2), nf * msz, ra,
access_type);
}
/* load bytes from guest memory */
@@ -524,7 +538,7 @@ vext_ldst_index(void *vd, void *v0, target_ulong base,
continue;
}
while (k < nf) {
- abi_ptr addr = get_index_addr(base, i, vs2) + k * msz;
+ abi_ptr addr = get_index_addr(uxl32, base, i, vs2) + k * msz;
ldst_elem(env, addr, i + k * vlmax, vd, ra);
k++;
}
@@ -784,19 +798,22 @@ vext_amo_noatomic(void *vs3, void *v0, target_ulong base,
uint32_t vm = vext_vm(desc);
uint32_t mlen = vext_mlen(desc);
uint32_t vlmax = vext_maxsz(desc) / esz;
+ bool uxl32 = riscv_cpu_is_uxl32(env);
for (i = 0; i < env->vl; i++) {
if (!vm && !vext_elem_mask(v0, mlen, i)) {
continue;
}
- probe_pages(env, get_index_addr(base, i, vs2), msz, ra, MMU_DATA_LOAD);
- probe_pages(env, get_index_addr(base, i, vs2), msz, ra, MMU_DATA_STORE);
+ probe_pages(env, get_index_addr(uxl32, base, i, vs2), msz, ra,
+ MMU_DATA_LOAD);
+ probe_pages(env, get_index_addr(uxl32, base, i, vs2), msz, ra,
+ MMU_DATA_STORE);
}
for (i = 0; i < env->vl; i++) {
if (!vm && !vext_elem_mask(v0, mlen, i)) {
continue;
}
- addr = get_index_addr(base, i, vs2);
+ addr = get_index_addr(uxl32, base, i, vs2);
noatomic_op(vs3, addr, wd, i, env, ra);
}
clear_elem(vs3, env->vl, env->vl * esz, vlmax * esz);
@@ -4682,7 +4699,8 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
uint32_t vlmax = env_archcpu(env)->cfg.vlen / mlen; \
uint32_t vm = vext_vm(desc); \
uint32_t vl = env->vl; \
- target_ulong offset = s1, i; \
+ target_ulong offset, i; \
+ offset = riscv_cpu_is_uxl32(env) ? s1 & UINT32_MAX : s1; \
\
for (i = offset; i < vl; i++) { \
if (!vm && !vext_elem_mask(v0, mlen, i)) { \
@@ -4707,7 +4725,8 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
uint32_t vlmax = env_archcpu(env)->cfg.vlen / mlen; \
uint32_t vm = vext_vm(desc); \
uint32_t vl = env->vl; \
- target_ulong offset = s1, i; \
+ target_ulong offset, i; \
+ offset = riscv_cpu_is_uxl32(env) ? s1 & UINT32_MAX : s1; \
\
for (i = 0; i < vl; ++i) { \
target_ulong j = i + offset; \
@@ -4734,6 +4753,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
uint32_t vm = vext_vm(desc); \
uint32_t vl = env->vl; \
uint32_t i; \
+ s1 = riscv_cpu_is_uxl32(env) ? s1 & UINT32_MAX : s1; \
\
for (i = 0; i < vl; i++) { \
if (!vm && !vext_elem_mask(v0, mlen, i)) { \
@@ -4763,6 +4783,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
uint32_t vm = vext_vm(desc); \
uint32_t vl = env->vl; \
uint32_t i; \
+ s1 = riscv_cpu_is_uxl32(env) ? s1 & UINT32_MAX : s1; \
\
for (i = 0; i < vl; i++) { \
if (!vm && !vext_elem_mask(v0, mlen, i)) { \
@@ -4823,8 +4844,9 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
uint32_t vlmax = env_archcpu(env)->cfg.vlen / mlen; \
uint32_t vm = vext_vm(desc); \
uint32_t vl = env->vl; \
- uint64_t index = s1; \
+ uint64_t index; \
uint32_t i; \
+ index = riscv_cpu_is_uxl32(env) ? s1 & UINT32_MAX : s1; \
\
for (i = 0; i < vl; i++) { \
if (!vm && !vext_elem_mask(v0, mlen, i)) { \
For integer operations, the scalar can be taken from the scalar x register specified by rs1. If XLEN<SEW, the value from the x register is sign-extended to SEW bits. Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com> --- target/riscv/cpu.h | 3 ++ target/riscv/insn_trans/trans_rvv.c.inc | 44 ++++++++++++-------- target/riscv/vector_helper.c | 54 +++++++++++++++++-------- 3 files changed, 68 insertions(+), 33 deletions(-)