aboutsummaryrefslogtreecommitdiff
path: root/spike_main
diff options
context:
space:
mode:
authorChih-Min Chao <chihmin.chao@sifive.com>2020-05-13 20:31:13 -0700
committerChih-Min Chao <chihmin.chao@sifive.com>2020-05-13 22:08:50 -0700
commite792aae0a95f4f4d12f9bcbc7da81db1d912ca8d (patch)
treeb6ad74452aebf760b172c5cf3dbf8a32e00cd139 /spike_main
parent7e75ab9f7417a1c31b1f97bd69a9683251b5224a (diff)
downloadspike-e792aae0a95f4f4d12f9bcbc7da81db1d912ca8d.zip
spike-e792aae0a95f4f4d12f9bcbc7da81db1d912ca8d.tar.gz
spike-e792aae0a95f4f4d12f9bcbc7da81db1d912ca8d.tar.bz2
rvv: change to 0.9amo
Signed-off-by: Chih-Min Chao <chihmin.chao@sifive.com>
Diffstat (limited to 'spike_main')
-rw-r--r--spike_main/disasm.cc55
1 files changed, 36 insertions, 19 deletions
diff --git a/spike_main/disasm.cc b/spike_main/disasm.cc
index 571ec23..fbfa869 100644
--- a/spike_main/disasm.cc
+++ b/spike_main/disasm.cc
@@ -382,6 +382,8 @@ disassembler_t::disassembler_t(int xlen)
const uint32_t mask_nf = 0x7Ul << 29;
const uint32_t mask_wd = 0x1Ul << 26;
const uint32_t mask_vldst = 0x7Ul << 12 | 0x1UL << 28;
+ const uint32_t mask_amoop = 0x1fUl;
+ const uint32_t mask_width = 0x7Ul << 12;
#define DECLARE_INSN(code, match, mask) \
const uint32_t match_##code = match; \
@@ -1149,25 +1151,40 @@ disassembler_t::disassembler_t(int xlen)
#undef DISASM_OPIV_W__INSN
#undef DISASM_VFUNARY0_INSN
- #define DISASM_VAMO_INSN(name) \
- add_insn(new disasm_insn_t(#name "e.v", match_##name##e_v | mask_wd, \
- mask_##name##e_v | mask_wd, \
- {&vd, &v_address, &vs2, &vd, &opt, &vm})); \
- add_insn(new disasm_insn_t(#name "e.v", match_##name##e_v, \
- mask_##name##e_v | mask_wd, \
- {&x0, &v_address, &vs2, &vd, &opt, &vm}));
-
- DISASM_VAMO_INSN(vamoswap);
- DISASM_VAMO_INSN(vamoadd);
- DISASM_VAMO_INSN(vamoxor);
- DISASM_VAMO_INSN(vamoand);
- DISASM_VAMO_INSN(vamoor);
- DISASM_VAMO_INSN(vamomin);
- DISASM_VAMO_INSN(vamomax);
- DISASM_VAMO_INSN(vamominu);
- DISASM_VAMO_INSN(vamomaxu);
-
- #undef DISASM_VAMO_INSN
+ // vector amo
+ std::vector<const arg_t *> v_fmt_amo_wd = {&vd, &v_address, &vs2, &vd, &opt, &vm};
+ std::vector<const arg_t *> v_fmt_amo = {&x0, &v_address, &vs2, &vd, &opt, &vm};
+ for (size_t elt = 0; elt <= 3; ++elt) {
+ const ldst_seg_t template_insn[] = {
+ {match_vamoswape8_v | mask_wd, mask_vamoswape8_v | mask_wd,
+ "%se%d.v", v_fmt_amo_wd},
+ {match_vamoswape8_v, mask_vamoswape8_v | mask_wd,
+ "%se%d.v", v_fmt_amo},
+ };
+ std::pair<const char*, reg_t> amo_map[] = {
+ {"vamoswap", 0x01ul << 27},
+ {"vamoadd", 0x00ul << 27},
+ {"vamoxor", 0x04ul << 27},
+ {"vamoor", 0x0cul << 27},
+ {"vamomin", 0x10ul << 27},
+ {"vamomax", 0x14ul << 27},
+ {"vamominu", 0x18ul << 27},
+ {"vamomaxu", 0x1cul << 27}};
+ const reg_t elt_map[] = {0x0ul << 12, 0x4ul << 12,
+ 0x6ul <<12, 0x7ul << 12};
+
+ for (size_t idx = 0; idx < sizeof(amo_map) / sizeof(amo_map[0]); ++idx) {
+ for (auto item : template_insn) {
+ char buf[128];
+ sprintf(buf, item.fmt, amo_map[idx].first, 8 << elt);
+ add_insn(new disasm_insn_t(buf,
+ (item.match & ~mask_width & ~mask_amoop) |
+ (amo_map[idx].second | elt_map[elt]),
+ item.mask,
+ item.arg));
+ }
+ }
+ }
if (xlen == 32) {
DISASM_INSN("c.flw", c_flw, 0, {&rvc_fp_rs2s, &rvc_lw_address});