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