From 7e75ab9f7417a1c31b1f97bd69a9683251b5224a Mon Sep 17 00:00:00 2001 From: Chih-Min Chao Date: Thu, 7 May 2020 21:09:47 -0700 Subject: rvv: amo pre-0.9 Signed-off-by: Chih-Min Chao --- riscv/decode.h | 52 +++++++++++++++++++++++++++++++++++++++++++++++ riscv/insns/vamoadde_v.h | 2 ++ riscv/insns/vamoande_v.h | 2 ++ riscv/insns/vamomaxe_v.h | 2 ++ riscv/insns/vamomaxue_v.h | 2 ++ riscv/insns/vamomine_v.h | 2 ++ riscv/insns/vamominue_v.h | 2 ++ riscv/insns/vamoore_v.h | 2 ++ riscv/insns/vamoswape_v.h | 2 ++ riscv/insns/vamoxore_v.h | 2 ++ riscv/mmu.h | 2 ++ riscv/processor.cc | 5 +++++ riscv/riscv.mk.in | 12 +++++++++++ spike_main/disasm.cc | 27 ++++++++++++++++++++++++ 14 files changed, 116 insertions(+) create mode 100644 riscv/insns/vamoadde_v.h create mode 100644 riscv/insns/vamoande_v.h create mode 100644 riscv/insns/vamomaxe_v.h create mode 100644 riscv/insns/vamomaxue_v.h create mode 100644 riscv/insns/vamomine_v.h create mode 100644 riscv/insns/vamominue_v.h create mode 100644 riscv/insns/vamoore_v.h create mode 100644 riscv/insns/vamoswape_v.h create mode 100644 riscv/insns/vamoxore_v.h diff --git a/riscv/decode.h b/riscv/decode.h index bf7d2ae..d4db8e7 100644 --- a/riscv/decode.h +++ b/riscv/decode.h @@ -112,6 +112,7 @@ public: uint64_t rvc_rs2s() { return 8 + x(2, 3); } uint64_t v_vm() { return x(25, 1); } + uint64_t v_wd() { return x(26, 1); } uint64_t v_nf() { return x(29, 3); } uint64_t v_simm5() { return xs(15, 5); } uint64_t v_zimm5() { return x(15, 5); } @@ -1705,6 +1706,57 @@ for (reg_t i = 0; i < P.VU.vlmax && P.VU.vl != 0; ++i) { \ p->VU.vstart = 0; // +// vector: amo +// +#define VI_AMO(op, type) \ + require_vector; \ + require_extension(EXT_ZVAMO); \ + VI_CHECK_SSS(false); \ + VI_DUPLICATE_VREG(insn.rs2(), P.VU.vlmax); \ + const reg_t vl = P.VU.vl; \ + const reg_t baseAddr = RS1; \ + const reg_t vd = insn.rd(); \ + const reg_t rs2_num = insn.rs2(); \ + for (reg_t i = P.VU.vstart; i < vl; ++i) { \ + VI_ELEMENT_SKIP(i); \ + VI_STRIP(i); \ + switch (P.VU.vsew) { \ + case e8: {\ + auto vs3 = P.VU.elt< type ## 8_t>(vd, vreg_inx); \ + auto val = MMU.amo_uint8(baseAddr + index[i], [&]( type ## 8_t lhs) { op }); \ + if (insn.v_wd()) \ + P.VU.elt< type ## 8_t>(vd, vreg_inx, true) = val; \ + } \ + break; \ + case e16: {\ + auto vs3 = P.VU.elt< type ## 16_t>(vd, vreg_inx); \ + auto val = MMU.amo_uint16(baseAddr + index[i], [&]( type ## 16_t lhs) { op }); \ + if (insn.v_wd()) \ + P.VU.elt< type ## 16_t>(vd, vreg_inx, true) = val; \ + } \ + break; \ + case e32: {\ + auto vs3 = P.VU.elt< type ## 32_t>(vd, vreg_inx); \ + auto val = MMU.amo_uint32(baseAddr + index[i], [&]( type ## 32_t lhs) { op }); \ + if (insn.v_wd()) \ + P.VU.elt< type ## 32_t>(vd, vreg_inx, true) = val; \ + } \ + break; \ + case e64: {\ + auto vs3 = P.VU.elt< type ## 64_t>(vd, vreg_inx); \ + auto val = MMU.amo_uint64(baseAddr + index[i], [&]( type ## 64_t lhs) { op }); \ + if (insn.v_wd()) \ + P.VU.elt< type ## 64_t>(vd, vreg_inx, true) = val; \ + } \ + break; \ + default: \ + require(0); \ + break; \ + } \ + } \ + P.VU.vstart = 0; + +// // vector: vfp helper // #define VI_VFP_COMMON \ diff --git a/riscv/insns/vamoadde_v.h b/riscv/insns/vamoadde_v.h new file mode 100644 index 0000000..9e59bdd --- /dev/null +++ b/riscv/insns/vamoadde_v.h @@ -0,0 +1,2 @@ +//vamoadde.v vd, (rs1), vs2, vd +VI_AMO({ return lhs + vs3; }, uint); diff --git a/riscv/insns/vamoande_v.h b/riscv/insns/vamoande_v.h new file mode 100644 index 0000000..90eb60d --- /dev/null +++ b/riscv/insns/vamoande_v.h @@ -0,0 +1,2 @@ +//vamoande.v vd, (rs1), vs2, vd +VI_AMO({ return lhs & vs3; }, uint); diff --git a/riscv/insns/vamomaxe_v.h b/riscv/insns/vamomaxe_v.h new file mode 100644 index 0000000..ab6539d --- /dev/null +++ b/riscv/insns/vamomaxe_v.h @@ -0,0 +1,2 @@ +//vamomaxe.v vd, (rs1), vs2, vd +VI_AMO({ return lhs >= vs3 ? lhs : vs3; }, int); diff --git a/riscv/insns/vamomaxue_v.h b/riscv/insns/vamomaxue_v.h new file mode 100644 index 0000000..1bdc50c --- /dev/null +++ b/riscv/insns/vamomaxue_v.h @@ -0,0 +1,2 @@ +//vamomaxue.v vd, (rs1), vs2, vd +VI_AMO({ return lhs >= vs3 ? lhs : vs3;; }, uint); diff --git a/riscv/insns/vamomine_v.h b/riscv/insns/vamomine_v.h new file mode 100644 index 0000000..fd931b2 --- /dev/null +++ b/riscv/insns/vamomine_v.h @@ -0,0 +1,2 @@ +//vamomine.v vd, (rs1), vs2, vd +VI_AMO({ return lhs < vs3 ? lhs : vs3; }, int); diff --git a/riscv/insns/vamominue_v.h b/riscv/insns/vamominue_v.h new file mode 100644 index 0000000..d8616da --- /dev/null +++ b/riscv/insns/vamominue_v.h @@ -0,0 +1,2 @@ +//vamominue.v vd, (rs1), vs2, vd +VI_AMO({ return lhs < vs3 ? lhs : vs3;; }, uint); diff --git a/riscv/insns/vamoore_v.h b/riscv/insns/vamoore_v.h new file mode 100644 index 0000000..c35789c --- /dev/null +++ b/riscv/insns/vamoore_v.h @@ -0,0 +1,2 @@ +//vamoore.v vd, (rs1), vs2, vd +VI_AMO({ return lhs | vs3; }, uint); diff --git a/riscv/insns/vamoswape_v.h b/riscv/insns/vamoswape_v.h new file mode 100644 index 0000000..4cc15cb --- /dev/null +++ b/riscv/insns/vamoswape_v.h @@ -0,0 +1,2 @@ +//vamoswape.v vd, (rs1), vs2, vd +VI_AMO({ return vs3; }, uint); diff --git a/riscv/insns/vamoxore_v.h b/riscv/insns/vamoxore_v.h new file mode 100644 index 0000000..7eb1199 --- /dev/null +++ b/riscv/insns/vamoxore_v.h @@ -0,0 +1,2 @@ +//vamoore.v vd, (rs1), vs2, vd +VI_AMO({ return lhs ^ vs3; }, uint); diff --git a/riscv/mmu.h b/riscv/mmu.h index b84fd4a..271faac 100644 --- a/riscv/mmu.h +++ b/riscv/mmu.h @@ -205,6 +205,8 @@ public: store_func(uint64) // perform an atomic memory operation at an aligned address + amo_func(uint8) + amo_func(uint16) amo_func(uint32) amo_func(uint64) diff --git a/riscv/processor.cc b/riscv/processor.cc index d5cbc98..b0da161 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -272,6 +272,8 @@ void processor_t::parse_isa_string(const char* str) auto ext_str = std::string(ext, end - ext); if (ext_str == "zfh") { extension_table[EXT_ZFH] = true; + } else if (ext_str == "zvamo") { + extension_table[EXT_ZVAMO] = true; } else { sprintf(error_msg, "unsupported extension '%s'", ext_str.c_str()); bad_isa_string(str, error_msg); @@ -297,6 +299,9 @@ void processor_t::parse_isa_string(const char* str) if (supports_extension('Q') && !supports_extension('D')) bad_isa_string(str, "'Q' extension requires 'D'"); + + if (supports_extension(EXT_ZVAMO) && !supports_extension('V')) + bad_isa_string(str, "'Zvamo' extension requires 'V'"); } void state_t::reset(reg_t max_isa) diff --git a/riscv/riscv.mk.in b/riscv/riscv.mk.in index e597427..eeff3d0 100644 --- a/riscv/riscv.mk.in +++ b/riscv/riscv.mk.in @@ -645,6 +645,17 @@ riscv_insn_ext_v_alu_fp = \ vmfne_vf \ vmfne_vv \ +riscv_insn_ext_v_amo = \ + vamoswape_v \ + vamoadde_v \ + vamoande_v \ + vamomaxe_v \ + vamomaxue_v \ + vamomine_v \ + vamominue_v \ + vamoore_v \ + vamoxore_v \ + riscv_insn_ext_v_ldst = \ vle8_v \ vle16_v \ @@ -688,6 +699,7 @@ riscv_insn_ext_v_ctrl = \ riscv_insn_ext_v = \ $(riscv_insn_ext_v_alu_fp) \ $(riscv_insn_ext_v_alu_int) \ + $(riscv_insn_ext_v_amo) \ $(riscv_insn_ext_v_ctrl) \ $(riscv_insn_ext_v_ldst) \ diff --git a/spike_main/disasm.cc b/spike_main/disasm.cc index e62c985..571ec23 100644 --- a/spike_main/disasm.cc +++ b/spike_main/disasm.cc @@ -349,6 +349,12 @@ struct : public arg_t { } } v_vtype; +struct : public arg_t { + std::string to_string(insn_t insn) const { + return "x0"; + } +} x0; + typedef struct { reg_t match; reg_t mask; @@ -374,6 +380,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_wd = 0x1Ul << 26; const uint32_t mask_vldst = 0x7Ul << 12 | 0x1UL << 28; #define DECLARE_INSN(code, match, mask) \ @@ -1142,6 +1149,26 @@ 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 + if (xlen == 32) { DISASM_INSN("c.flw", c_flw, 0, {&rvc_fp_rs2s, &rvc_lw_address}); DISASM_INSN("c.flwsp", c_flwsp, 0, {&frd, &rvc_lwsp_address}); -- cgit v1.1