XTheadVector indexed store instructions diff from RVV1.0 in the following
points:
1. Different mask reg layout.
2. Different access width. As same as XTheadVector indexed load instructions,
except store does not need to distinguish between zero and sign extended.
3. Different masked elements process policy.
4. Different check policy.
Signed-off-by: Huang Tao <eric.huang@linux.alibaba.com>
---
target/riscv/helper.h | 13 +++++
.../riscv/insn_trans/trans_xtheadvector.c.inc | 49 +++++++++++++++++--
target/riscv/xtheadvector_helper.c | 24 +++++++++
3 files changed, 82 insertions(+), 4 deletions(-)
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 733071bdc6..fd81db2f74 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1409,3 +1409,16 @@ DEF_HELPER_6(th_vlxhu_v_w, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(th_vlxhu_v_d, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(th_vlxwu_v_w, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(th_vlxwu_v_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsxb_v_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsxb_v_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsxb_v_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsxb_v_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsxh_v_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsxh_v_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsxh_v_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsxw_v_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsxw_v_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsxe_v_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsxe_v_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsxe_v_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsxe_v_d, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 8148097de3..68a2a9a0cf 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -537,6 +537,51 @@ GEN_TH_TRANS(th_vlxbu_v, 4, rnfvm, ld_index_op_th, ld_index_check_th)
GEN_TH_TRANS(th_vlxhu_v, 5, rnfvm, ld_index_op_th, ld_index_check_th)
GEN_TH_TRANS(th_vlxwu_v, 6, rnfvm, ld_index_op_th, ld_index_check_th)
+/*
+ * This function is almost the copy of st_index_op, except:
+ * 1) different data encoding.
+ */
+static bool st_index_op_th(DisasContext *s, arg_rnfvm *a, uint8_t seq)
+{
+ uint32_t data = 0;
+ gen_helper_ldst_index_th *fn;
+ static gen_helper_ldst_index_th * const fns[4][4] = {
+ { gen_helper_th_vsxb_v_b, gen_helper_th_vsxb_v_h,
+ gen_helper_th_vsxb_v_w, gen_helper_th_vsxb_v_d },
+ { NULL, gen_helper_th_vsxh_v_h,
+ gen_helper_th_vsxh_v_w, gen_helper_th_vsxh_v_d },
+ { NULL, NULL,
+ gen_helper_th_vsxw_v_w, gen_helper_th_vsxw_v_d },
+ { gen_helper_th_vsxe_v_b, gen_helper_th_vsxe_v_h,
+ gen_helper_th_vsxe_v_w, gen_helper_th_vsxe_v_d }
+ };
+
+ fn = fns[seq][s->sew];
+ if (fn == NULL) {
+ return false;
+ }
+
+ data = FIELD_DP32(data, VDATA_TH, MLEN, s->mlen);
+ data = FIELD_DP32(data, VDATA_TH, VM, a->vm);
+ data = FIELD_DP32(data, VDATA_TH, LMUL, s->lmul);
+ data = FIELD_DP32(data, VDATA_TH, NF, a->nf);
+ return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
+}
+
+static bool st_index_check_th(DisasContext *s, arg_rnfvm* a)
+{
+ return (require_xtheadvector(s) &&
+ vext_check_isa_ill(s) &&
+ th_check_reg(s, a->rd, false) &&
+ th_check_reg(s, a->rs2, false) &&
+ th_check_nf(s, a->rd, a->nf));
+}
+
+GEN_TH_TRANS(th_vsxb_v, 0, rnfvm, st_index_op_th, st_index_check_th)
+GEN_TH_TRANS(th_vsxh_v, 1, rnfvm, st_index_op_th, st_index_check_th)
+GEN_TH_TRANS(th_vsxw_v, 2, rnfvm, st_index_op_th, st_index_check_th)
+GEN_TH_TRANS(th_vsxe_v, 3, rnfvm, st_index_op_th, st_index_check_th)
+
#define TH_TRANS_STUB(NAME) \
static bool trans_##NAME(DisasContext *s, arg_##NAME *a) \
{ \
@@ -550,10 +595,6 @@ TH_TRANS_STUB(th_vleff_v)
TH_TRANS_STUB(th_vlbuff_v)
TH_TRANS_STUB(th_vlhuff_v)
TH_TRANS_STUB(th_vlwuff_v)
-TH_TRANS_STUB(th_vsxb_v)
-TH_TRANS_STUB(th_vsxh_v)
-TH_TRANS_STUB(th_vsxw_v)
-TH_TRANS_STUB(th_vsxe_v)
TH_TRANS_STUB(th_vamoswapw_v)
TH_TRANS_STUB(th_vamoaddw_v)
TH_TRANS_STUB(th_vamoxorw_v)
diff --git a/target/riscv/xtheadvector_helper.c b/target/riscv/xtheadvector_helper.c
index a9ae157296..22af4774df 100644
--- a/target/riscv/xtheadvector_helper.c
+++ b/target/riscv/xtheadvector_helper.c
@@ -518,3 +518,27 @@ GEN_TH_LD_INDEX(th_vlxhu_v_w, uint16_t, uint32_t, idx_w, ldhu_w, clearl_th)
GEN_TH_LD_INDEX(th_vlxhu_v_d, uint16_t, uint64_t, idx_d, ldhu_d, clearq_th)
GEN_TH_LD_INDEX(th_vlxwu_v_w, uint32_t, uint32_t, idx_w, ldwu_w, clearl_th)
GEN_TH_LD_INDEX(th_vlxwu_v_d, uint32_t, uint64_t, idx_d, ldwu_d, clearq_th)
+
+/* Similar to GEN_VEXT_ST_INDEX */
+#define GEN_TH_ST_INDEX(NAME, MTYPE, ETYPE, INDEX_FN, STORE_FN) \
+void HELPER(NAME)(void *vd, void *v0, target_ulong base, \
+ void *vs2, CPURISCVState *env, uint32_t desc) \
+{ \
+ th_ldst_index(vd, v0, base, vs2, env, desc, INDEX_FN, \
+ STORE_FN, NULL, sizeof(ETYPE), sizeof(MTYPE), \
+ GETPC()); \
+}
+
+GEN_TH_ST_INDEX(th_vsxb_v_b, int8_t, int8_t, idx_b, stb_b)
+GEN_TH_ST_INDEX(th_vsxb_v_h, int8_t, int16_t, idx_h, stb_h)
+GEN_TH_ST_INDEX(th_vsxb_v_w, int8_t, int32_t, idx_w, stb_w)
+GEN_TH_ST_INDEX(th_vsxb_v_d, int8_t, int64_t, idx_d, stb_d)
+GEN_TH_ST_INDEX(th_vsxh_v_h, int16_t, int16_t, idx_h, sth_h)
+GEN_TH_ST_INDEX(th_vsxh_v_w, int16_t, int32_t, idx_w, sth_w)
+GEN_TH_ST_INDEX(th_vsxh_v_d, int16_t, int64_t, idx_d, sth_d)
+GEN_TH_ST_INDEX(th_vsxw_v_w, int32_t, int32_t, idx_w, stw_w)
+GEN_TH_ST_INDEX(th_vsxw_v_d, int32_t, int64_t, idx_d, stw_d)
+GEN_TH_ST_INDEX(th_vsxe_v_b, int8_t, int8_t, idx_b, ste_b)
+GEN_TH_ST_INDEX(th_vsxe_v_h, int16_t, int16_t, idx_h, ste_h)
+GEN_TH_ST_INDEX(th_vsxe_v_w, int32_t, int32_t, idx_w, ste_w)
+GEN_TH_ST_INDEX(th_vsxe_v_d, int64_t, int64_t, idx_d, ste_d)
--
2.44.0