diff options
author | Chih-Min Chao <chihmin.chao@sifive.com> | 2020-05-07 23:25:46 -0700 |
---|---|---|
committer | Chih-Min Chao <chihmin.chao@sifive.com> | 2020-05-11 19:39:46 -0700 |
commit | e8da0d62c39756f893d1d18ab31b51b12a347f0e (patch) | |
tree | bbbc4d2a0ddb9024e5f7345edaeb14721882a026 /spike_main | |
parent | 3baafbe3559fb62b8a4d3f13288593035e4502d3 (diff) | |
download | spike-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.cc | 123 |
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 + )); + } } } |