aboutsummaryrefslogtreecommitdiff
path: root/spike_main
diff options
context:
space:
mode:
authorChih-Min Chao <chihmin.chao@sifive.com>2020-05-07 23:25:46 -0700
committerChih-Min Chao <chihmin.chao@sifive.com>2020-05-11 19:39:46 -0700
commite8da0d62c39756f893d1d18ab31b51b12a347f0e (patch)
treebbbc4d2a0ddb9024e5f7345edaeb14721882a026 /spike_main
parent3baafbe3559fb62b8a4d3f13288593035e4502d3 (diff)
downloadspike-e8da0d62c39756f893d1d18ab31b51b12a347f0e.zip
spike-e8da0d62c39756f893d1d18ab31b51b12a347f0e.tar.gz
spike-e8da0d62c39756f893d1d18ab31b51b12a347f0e.tar.bz2
rvv: change to 0.9 ldst
Signed-off-by: Chih-Min Chao <chihmin.chao@sifive.com>
Diffstat (limited to 'spike_main')
-rw-r--r--spike_main/disasm.cc123
1 files changed, 58 insertions, 65 deletions
diff --git a/spike_main/disasm.cc b/spike_main/disasm.cc
index 8056ca9..60a31e6 100644
--- a/spike_main/disasm.cc
+++ b/spike_main/disasm.cc
@@ -326,6 +326,12 @@ struct : public arg_t {
}
} v_vtype;
+typedef struct {
+ reg_t match;
+ reg_t mask;
+ const char *fmt;
+ std::vector<const arg_t*>& arg;
+} ldst_seg_t;
std::string disassembler_t::disassemble(insn_t insn) const
{
@@ -345,6 +351,7 @@ disassembler_t::disassembler_t(int xlen)
const uint32_t mask_rvc_rs2 = 0x1fUL << 2;
const uint32_t mask_rvc_imm = mask_rvc_rs2 | 0x1000UL;
const uint32_t mask_nf = 0x7Ul << 29;
+ const uint32_t mask_vldst = 0x7Ul << 12 | 0x1UL << 28;
#define DECLARE_INSN(code, match, mask) \
const uint32_t match_##code = match; \
@@ -699,78 +706,64 @@ disassembler_t::disassembler_t(int xlen)
DISASM_INSN("vsetvli", vsetvli, 0, {&xrd, &xrs1, &v_vtype});
DISASM_INSN("vsetvl", vsetvl, 0, {&xrd, &xrs1, &xrs2});
- #define DISASM_VMEM_LD_INSN(name, ff, fmt) \
- add_insn(new disasm_insn_t("vl" #name "b" #ff ".v", match_vl##name##b##ff##_v, mask_vl##name##b##ff##_v | mask_nf, fmt)); \
- add_insn(new disasm_insn_t("vl" #name "h" #ff ".v", match_vl##name##h##ff##_v, mask_vl##name##h##ff##_v | mask_nf, fmt)); \
- add_insn(new disasm_insn_t("vl" #name "w" #ff ".v", match_vl##name##w##ff##_v, mask_vl##name##w##ff##_v | mask_nf, fmt)); \
- add_insn(new disasm_insn_t("vl" #name "e" #ff ".v", match_vl##name##e##ff##_v, mask_vl##name##e##ff##_v | mask_nf, fmt)); \
- add_insn(new disasm_insn_t("vl" #name "bu" #ff ".v", match_vl##name##bu##ff##_v, mask_vl##name##bu##ff##_v | mask_nf, fmt)); \
- add_insn(new disasm_insn_t("vl" #name "hu" #ff ".v", match_vl##name##hu##ff##_v, mask_vl##name##hu##ff##_v | mask_nf, fmt)); \
- add_insn(new disasm_insn_t("vl" #name "wu" #ff ".v", match_vl##name##wu##ff##_v, mask_vl##name##wu##ff##_v | mask_nf, fmt));
-
- #define DISASM_VMEM_ST_INSN(name, fmt) \
- add_insn(new disasm_insn_t("vs" #name "b.v", match_vs##name##b_v, mask_vs##name##b_v | mask_nf, fmt)); \
- add_insn(new disasm_insn_t("vs" #name "h.v", match_vs##name##h_v, mask_vs##name##h_v | mask_nf, fmt)); \
- add_insn(new disasm_insn_t("vs" #name "w.v", match_vs##name##w_v, mask_vs##name##w_v | mask_nf, fmt)); \
- add_insn(new disasm_insn_t("vs" #name "e.v", match_vs##name##e_v, mask_vs##name##e_v | mask_nf, fmt));
-
- const std::vector<const arg_t *> v_ld_unit = {&vd, &v_address, &opt, &vm};
- const std::vector<const arg_t *> v_st_unit = {&vs3, &v_address, &opt, &vm};
- const std::vector<const arg_t *> v_ld_stride = {&vd, &v_address, &xrs2, &opt, &vm};
- const std::vector<const arg_t *> v_st_stride = {&vs3, &v_address, &xrs2, &opt, &vm};
- const std::vector<const arg_t *> v_ld_index = {&vd, &v_address, &vs2, &opt, &vm};
- const std::vector<const arg_t *> v_st_index = {&vs3, &v_address, &vs2, &opt, &vm};
-
- DISASM_VMEM_LD_INSN( , , v_ld_unit);
- DISASM_VMEM_ST_INSN( , v_st_unit);
- DISASM_VMEM_LD_INSN(s, , v_ld_stride);
- DISASM_VMEM_ST_INSN(s, v_st_stride);
- DISASM_VMEM_LD_INSN(x, , v_ld_index);
- DISASM_VMEM_ST_INSN(x, v_st_index);
- DISASM_VMEM_LD_INSN( , ff, v_ld_unit);
-
- #undef DISASM_VMEM_LD_INSN
- #undef DISASM_VMEM_ST_INSN
+ #define DISASM_VMEM_INSN(name, fmt, ff) \
+ add_insn(new disasm_insn_t(#name "8" #ff ".v", match_##name##8##ff##_v, mask_##name##8##ff##_v | mask_nf, fmt)); \
+ add_insn(new disasm_insn_t(#name "16" #ff ".v", match_##name##16##ff##_v, mask_##name##16##ff##_v | mask_nf, fmt)); \
+ add_insn(new disasm_insn_t(#name "32" #ff ".v", match_##name##32##ff##_v, mask_##name##32##ff##_v | mask_nf, fmt)); \
+ add_insn(new disasm_insn_t(#name "64" #ff ".v", match_##name##64##ff##_v, mask_##name##64##ff##_v | mask_nf, fmt)); \
+ add_insn(new disasm_insn_t(#name "128" #ff ".v", match_##name##128##ff##_v, mask_##name##128##ff##_v | mask_nf, fmt)); \
+ add_insn(new disasm_insn_t(#name "256" #ff ".v", match_##name##256##ff##_v, mask_##name##256##ff##_v | mask_nf, fmt)); \
+ add_insn(new disasm_insn_t(#name "512" #ff ".v", match_##name##512##ff##_v, mask_##name##512##ff##_v | mask_nf, fmt)); \
+ add_insn(new disasm_insn_t(#name "1024" #ff ".v", match_##name##1024##ff##_v, mask_##name##1024##ff##_v | mask_nf, fmt)); \
+
+ std::vector<const arg_t *> v_ld_unit = {&vd, &v_address, &opt, &vm};
+ std::vector<const arg_t *> v_st_unit = {&vs3, &v_address, &opt, &vm};
+ std::vector<const arg_t *> v_ld_stride = {&vd, &v_address, &xrs2, &opt, &vm};
+ std::vector<const arg_t *> v_st_stride = {&vs3, &v_address, &xrs2, &opt, &vm};
+ std::vector<const arg_t *> v_ld_index = {&vd, &v_address, &vs2, &opt, &vm};
+ std::vector<const arg_t *> v_st_index = {&vs3, &v_address, &vs2, &opt, &vm};
+
+ DISASM_VMEM_INSN(vle, v_ld_unit, );
+ DISASM_VMEM_INSN(vlse, v_ld_stride, );
+ DISASM_VMEM_INSN(vlxei, v_ld_index, );
+ DISASM_VMEM_INSN(vle, v_ld_unit, ff);
+ DISASM_VMEM_INSN(vse, v_st_unit, );
+ DISASM_VMEM_INSN(vsse, v_st_stride, );
+ DISASM_VMEM_INSN(vsxei, v_st_index, );
+ DISASM_VMEM_INSN(vsuxei, v_st_unit, );
+
+ #undef DISASM_VMEM_INSN
// handle vector segment load/store
- for (size_t nf = 1; nf <= 7; ++nf) {
- std::pair<reg_t, reg_t> insn_code[] = {
- {match_vle_v, mask_vle_v},
- {match_vse_v, mask_vse_v},
+ for (size_t elt = 0; elt <= 7; ++elt) {
+ const ldst_seg_t template_insn[] = {
+ {match_vle8_v, mask_vle8_v, "vlseg%de%d.v", v_ld_unit},
+ {match_vse8_v, mask_vse8_v, "vsseg%de%d.v", v_st_unit},
- {match_vlse_v, mask_vlse_v},
- {match_vsse_v, mask_vssw_v},
+ {match_vlse8_v, mask_vlse8_v, "vlsseg%de%d.v", v_ld_stride},
+ {match_vsse8_v, mask_vsse8_v, "vssseg%de%d.v", v_st_stride},
- {match_vlxe_v, mask_vlxe_v},
- {match_vsxe_v, mask_vsxw_v},
+ {match_vlxei8_v, mask_vlxei8_v, "vlxseg%dei%d.v", v_ld_index},
+ {match_vsxei8_v, mask_vsxei8_v, "vsxseg%dei%d.v", v_st_index},
- {match_vleff_v, mask_vleff_v},
+ {match_vle8ff_v, mask_vle8ff_v, "vlseg%de%dff.v", v_ld_unit}
};
- std::pair<const char *, std::vector<const arg_t*>> fmts[] = {
- {"vlseg%de.v", {&vd, &v_address, &opt, &vm}},
- {"vsseg%de.v", {&vs3, &v_address, &opt, &vm}},
-
- {"vlsseg%de.v", {&vd, &v_address, &xrs2, &opt, &vm}},
- {"vssseg%de.v", {&vs3, &v_address, &xrs2, &opt, &vm}},
-
- {"vlxseg%de.v", {&vd, &v_address, &vs2, &opt, &vm}},
- {"vsxseg%de.v", {&vs3, &v_address, &vs2, &opt, &vm}},
-
- {"vlseg%deff.v", {&vd, &v_address, &opt, &vm}},
- };
-
-
-
- for (size_t idx_insn = 0; idx_insn < sizeof(insn_code) / sizeof(insn_code[0]); ++idx_insn) {
- const reg_t match_nf = nf << 29;
- char buf[128];
- sprintf(buf, fmts[idx_insn].first, nf + 1);
- add_insn(new disasm_insn_t(buf,
- insn_code[idx_insn].first | match_nf,
- insn_code[idx_insn].second | mask_nf,
- fmts[idx_insn].second
- ));
+ reg_t elt_map[] = {0x00000000, 0x00005000, 0x00006000, 0x00007000,
+ 0x10000000, 0x10005000, 0x10006000, 0x10007000};
+
+ for (size_t nf = 1; nf <= 7; ++nf) {
+ for (auto item : template_insn) {
+ const reg_t match_nf = nf << 29;
+ char buf[128];
+ sprintf(buf, item.fmt, nf + 1, 8 << elt);
+ add_insn(new disasm_insn_t(
+ buf,
+ ((item.match | match_nf) & ~mask_vldst) | elt_map[elt],
+ item.mask | mask_nf,
+ item.arg
+ ));
+ }
}
}