aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChih-Min Chao <chihmin.chao@sifive.com>2020-05-27 00:55:58 -0700
committerChih-Min Chao <chihmin.chao@sifive.com>2020-05-28 22:36:15 -0700
commit3035256f1a451da1dabff677e6e14b13fef7edc1 (patch)
tree0d82dd524add0706e5113c0fd9d55daf0f044d51
parentf5983b39c583971b8443b9f16705cbfb1588dbf5 (diff)
downloadriscv-isa-sim-3035256f1a451da1dabff677e6e14b13fef7edc1.zip
riscv-isa-sim-3035256f1a451da1dabff677e6e14b13fef7edc1.tar.gz
riscv-isa-sim-3035256f1a451da1dabff677e6e14b13fef7edc1.tar.bz2
rvv: add amo instructions
use --isa=rv64gcv_zvamo to enable it Signed-off-by: Chih-Min Chao <chihmin.chao@sifive.com>
-rw-r--r--riscv/decode.h43
-rw-r--r--riscv/encoding.h162
-rw-r--r--riscv/insns/vamoadde16_v.h2
-rw-r--r--riscv/insns/vamoadde32_v.h2
-rw-r--r--riscv/insns/vamoadde64_v.h2
-rw-r--r--riscv/insns/vamoadde8_v.h2
-rw-r--r--riscv/insns/vamoande16_v.h2
-rw-r--r--riscv/insns/vamoande32_v.h2
-rw-r--r--riscv/insns/vamoande64_v.h2
-rw-r--r--riscv/insns/vamoande8_v.h2
-rw-r--r--riscv/insns/vamomaxe16_v.h2
-rw-r--r--riscv/insns/vamomaxe32_v.h2
-rw-r--r--riscv/insns/vamomaxe64_v.h2
-rw-r--r--riscv/insns/vamomaxe8_v.h2
-rw-r--r--riscv/insns/vamomaxue16_v.h2
-rw-r--r--riscv/insns/vamomaxue32_v.h2
-rw-r--r--riscv/insns/vamomaxue64_v.h2
-rw-r--r--riscv/insns/vamomaxue8_v.h2
-rw-r--r--riscv/insns/vamomine16_v.h2
-rw-r--r--riscv/insns/vamomine32_v.h2
-rw-r--r--riscv/insns/vamomine64_v.h2
-rw-r--r--riscv/insns/vamomine8_v.h2
-rw-r--r--riscv/insns/vamominue16_v.h2
-rw-r--r--riscv/insns/vamominue32_v.h2
-rw-r--r--riscv/insns/vamominue64_v.h2
-rw-r--r--riscv/insns/vamominue8_v.h2
-rw-r--r--riscv/insns/vamoore16_v.h2
-rw-r--r--riscv/insns/vamoore32_v.h2
-rw-r--r--riscv/insns/vamoore64_v.h2
-rw-r--r--riscv/insns/vamoore8_v.h2
-rw-r--r--riscv/insns/vamoswape16_v.h2
-rw-r--r--riscv/insns/vamoswape32_v.h2
-rw-r--r--riscv/insns/vamoswape64_v.h2
-rw-r--r--riscv/insns/vamoswape8_v.h2
-rw-r--r--riscv/insns/vamoxore16_v.h2
-rw-r--r--riscv/insns/vamoxore32_v.h2
-rw-r--r--riscv/insns/vamoxore64_v.h2
-rw-r--r--riscv/insns/vamoxore8_v.h2
-rw-r--r--riscv/processor.cc6
-rw-r--r--riscv/riscv.mk.in39
-rw-r--r--spike_main/disasm.cc50
41 files changed, 318 insertions, 54 deletions
diff --git a/riscv/decode.h b/riscv/decode.h
index c37d409..6188e52 100644
--- a/riscv/decode.h
+++ b/riscv/decode.h
@@ -1684,6 +1684,49 @@ for (reg_t i = 0; i < vlmax && P.VU.vl != 0; ++i) { \
p->VU.vstart = 0;
//
+// vector: amo
+//
+#define VI_AMO(op, type, idx_type) \
+ require_vector; \
+ require_extension(EXT_ZVAMO); \
+ if (insn.v_wd()) \
+ require_vm; \
+ require_align(insn.rd(), P.VU.vflmul); \
+ require(P.VU.vsew <= P.get_xlen() && P.VU.vsew >= 32); \
+ require_align(insn.rd(), P.VU.vflmul); \
+ P.VU.veew = idx_type; \
+ P.VU.vemul = ((float)P.VU.veew / P.VU.vsew * P.VU.vflmul); \
+ require(P.VU.vemul >= 0.125 && P.VU.vemul <= 8); \
+ require_align(insn.rs2(), P.VU.vemul); \
+ VI_DUPLICATE_VREG(insn.rs2(), idx_type); \
+ const reg_t vl = P.VU.vl; \
+ const reg_t baseAddr = RS1; \
+ const reg_t vd = insn.rd(); \
+ for (reg_t i = P.VU.vstart; i < vl; ++i) { \
+ VI_ELEMENT_SKIP(i); \
+ VI_STRIP(i); \
+ switch (P.VU.vsew) { \
+ 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: sign/unsiged extension
#define VI_VV_EXT(div, type) \
require(insn.rd() != insn.rs2()); \
diff --git a/riscv/encoding.h b/riscv/encoding.h
index ecacefe..0726b3f 100644
--- a/riscv/encoding.h
+++ b/riscv/encoding.h
@@ -1551,42 +1551,78 @@
#define MASK_VWMACCUS_VX 0xfc00707f
#define MATCH_VWMACCSU_VX 0xfc006057
#define MASK_VWMACCSU_VX 0xfc00707f
-#define MATCH_VAMOSWAPW_V 0x800602f
-#define MASK_VAMOSWAPW_V 0xf800707f
-#define MATCH_VAMOADDW_V 0x602f
-#define MASK_VAMOADDW_V 0xf800707f
-#define MATCH_VAMOXORW_V 0x2000602f
-#define MASK_VAMOXORW_V 0xf800707f
-#define MATCH_VAMOANDW_V 0x6000602f
-#define MASK_VAMOANDW_V 0xf800707f
-#define MATCH_VAMOORW_V 0x4000602f
-#define MASK_VAMOORW_V 0xf800707f
-#define MATCH_VAMOMINW_V 0x8000602f
-#define MASK_VAMOMINW_V 0xf800707f
-#define MATCH_VAMOMAXW_V 0xa000602f
-#define MASK_VAMOMAXW_V 0xf800707f
-#define MATCH_VAMOMINUW_V 0xc000602f
-#define MASK_VAMOMINUW_V 0xf800707f
-#define MATCH_VAMOMAXUW_V 0xe000602f
-#define MASK_VAMOMAXUW_V 0xf800707f
-#define MATCH_VAMOSWAPE_V 0x800702f
-#define MASK_VAMOSWAPE_V 0xf800707f
-#define MATCH_VAMOADDE_V 0x702f
-#define MASK_VAMOADDE_V 0xf800707f
-#define MATCH_VAMOXORE_V 0x2000702f
-#define MASK_VAMOXORE_V 0xf800707f
-#define MATCH_VAMOANDE_V 0x6000702f
-#define MASK_VAMOANDE_V 0xf800707f
-#define MATCH_VAMOORE_V 0x4000702f
-#define MASK_VAMOORE_V 0xf800707f
-#define MATCH_VAMOMINE_V 0x8000702f
-#define MASK_VAMOMINE_V 0xf800707f
-#define MATCH_VAMOMAXE_V 0xa000702f
-#define MASK_VAMOMAXE_V 0xf800707f
-#define MATCH_VAMOMINUE_V 0xc000702f
-#define MASK_VAMOMINUE_V 0xf800707f
-#define MATCH_VAMOMAXUE_V 0xe000702f
-#define MASK_VAMOMAXUE_V 0xf800707f
+#define MATCH_VAMOSWAPE8_V 0x800002f
+#define MASK_VAMOSWAPE8_V 0xf800707f
+#define MATCH_VAMOADDE8_V 0x2f
+#define MASK_VAMOADDE8_V 0xf800707f
+#define MATCH_VAMOXORE8_V 0x2000002f
+#define MASK_VAMOXORE8_V 0xf800707f
+#define MATCH_VAMOANDE8_V 0x6000002f
+#define MASK_VAMOANDE8_V 0xf800707f
+#define MATCH_VAMOORE8_V 0x4000002f
+#define MASK_VAMOORE8_V 0xf800707f
+#define MATCH_VAMOMINE8_V 0x8000002f
+#define MASK_VAMOMINE8_V 0xf800707f
+#define MATCH_VAMOMAXE8_V 0xa000002f
+#define MASK_VAMOMAXE8_V 0xf800707f
+#define MATCH_VAMOMINUE8_V 0xc000002f
+#define MASK_VAMOMINUE8_V 0xf800707f
+#define MATCH_VAMOMAXUE8_V 0xe000002f
+#define MASK_VAMOMAXUE8_V 0xf800707f
+#define MATCH_VAMOSWAPE16_V 0x800502f
+#define MASK_VAMOSWAPE16_V 0xf800707f
+#define MATCH_VAMOADDE16_V 0x502f
+#define MASK_VAMOADDE16_V 0xf800707f
+#define MATCH_VAMOXORE16_V 0x2000502f
+#define MASK_VAMOXORE16_V 0xf800707f
+#define MATCH_VAMOANDE16_V 0x6000502f
+#define MASK_VAMOANDE16_V 0xf800707f
+#define MATCH_VAMOORE16_V 0x4000502f
+#define MASK_VAMOORE16_V 0xf800707f
+#define MATCH_VAMOMINE16_V 0x8000502f
+#define MASK_VAMOMINE16_V 0xf800707f
+#define MATCH_VAMOMAXE16_V 0xa000502f
+#define MASK_VAMOMAXE16_V 0xf800707f
+#define MATCH_VAMOMINUE16_V 0xc000502f
+#define MASK_VAMOMINUE16_V 0xf800707f
+#define MATCH_VAMOMAXUE16_V 0xe000502f
+#define MASK_VAMOMAXUE16_V 0xf800707f
+#define MATCH_VAMOSWAPE32_V 0x800602f
+#define MASK_VAMOSWAPE32_V 0xf800707f
+#define MATCH_VAMOADDE32_V 0x602f
+#define MASK_VAMOADDE32_V 0xf800707f
+#define MATCH_VAMOXORE32_V 0x2000602f
+#define MASK_VAMOXORE32_V 0xf800707f
+#define MATCH_VAMOANDE32_V 0x6000602f
+#define MASK_VAMOANDE32_V 0xf800707f
+#define MATCH_VAMOORE32_V 0x4000602f
+#define MASK_VAMOORE32_V 0xf800707f
+#define MATCH_VAMOMINE32_V 0x8000602f
+#define MASK_VAMOMINE32_V 0xf800707f
+#define MATCH_VAMOMAXE32_V 0xa000602f
+#define MASK_VAMOMAXE32_V 0xf800707f
+#define MATCH_VAMOMINUE32_V 0xc000602f
+#define MASK_VAMOMINUE32_V 0xf800707f
+#define MATCH_VAMOMAXUE32_V 0xe000602f
+#define MASK_VAMOMAXUE32_V 0xf800707f
+#define MATCH_VAMOSWAPE64_V 0x800702f
+#define MASK_VAMOSWAPE64_V 0xf800707f
+#define MATCH_VAMOADDE64_V 0x702f
+#define MASK_VAMOADDE64_V 0xf800707f
+#define MATCH_VAMOXORE64_V 0x2000702f
+#define MASK_VAMOXORE64_V 0xf800707f
+#define MATCH_VAMOANDE64_V 0x6000702f
+#define MASK_VAMOANDE64_V 0xf800707f
+#define MATCH_VAMOORE64_V 0x4000702f
+#define MASK_VAMOORE64_V 0xf800707f
+#define MATCH_VAMOMINE64_V 0x8000702f
+#define MASK_VAMOMINE64_V 0xf800707f
+#define MATCH_VAMOMAXE64_V 0xa000702f
+#define MASK_VAMOMAXE64_V 0xf800707f
+#define MATCH_VAMOMINUE64_V 0xc000702f
+#define MASK_VAMOMINUE64_V 0xf800707f
+#define MATCH_VAMOMAXUE64_V 0xe000702f
+#define MASK_VAMOMAXUE64_V 0xf800707f
#define MATCH_VMVNFR_V 0x9e003057
#define MASK_VMVNFR_V 0xfe00707f
#define CSR_FFLAGS 0x1
@@ -2535,24 +2571,42 @@ DECLARE_INSN(vwmaccu_vx, MATCH_VWMACCU_VX, MASK_VWMACCU_VX)
DECLARE_INSN(vwmacc_vx, MATCH_VWMACC_VX, MASK_VWMACC_VX)
DECLARE_INSN(vwmaccus_vx, MATCH_VWMACCUS_VX, MASK_VWMACCUS_VX)
DECLARE_INSN(vwmaccsu_vx, MATCH_VWMACCSU_VX, MASK_VWMACCSU_VX)
-DECLARE_INSN(vamoswapw_v, MATCH_VAMOSWAPW_V, MASK_VAMOSWAPW_V)
-DECLARE_INSN(vamoaddw_v, MATCH_VAMOADDW_V, MASK_VAMOADDW_V)
-DECLARE_INSN(vamoxorw_v, MATCH_VAMOXORW_V, MASK_VAMOXORW_V)
-DECLARE_INSN(vamoandw_v, MATCH_VAMOANDW_V, MASK_VAMOANDW_V)
-DECLARE_INSN(vamoorw_v, MATCH_VAMOORW_V, MASK_VAMOORW_V)
-DECLARE_INSN(vamominw_v, MATCH_VAMOMINW_V, MASK_VAMOMINW_V)
-DECLARE_INSN(vamomaxw_v, MATCH_VAMOMAXW_V, MASK_VAMOMAXW_V)
-DECLARE_INSN(vamominuw_v, MATCH_VAMOMINUW_V, MASK_VAMOMINUW_V)
-DECLARE_INSN(vamomaxuw_v, MATCH_VAMOMAXUW_V, MASK_VAMOMAXUW_V)
-DECLARE_INSN(vamoswape_v, MATCH_VAMOSWAPE_V, MASK_VAMOSWAPE_V)
-DECLARE_INSN(vamoadde_v, MATCH_VAMOADDE_V, MASK_VAMOADDE_V)
-DECLARE_INSN(vamoxore_v, MATCH_VAMOXORE_V, MASK_VAMOXORE_V)
-DECLARE_INSN(vamoande_v, MATCH_VAMOANDE_V, MASK_VAMOANDE_V)
-DECLARE_INSN(vamoore_v, MATCH_VAMOORE_V, MASK_VAMOORE_V)
-DECLARE_INSN(vamomine_v, MATCH_VAMOMINE_V, MASK_VAMOMINE_V)
-DECLARE_INSN(vamomaxe_v, MATCH_VAMOMAXE_V, MASK_VAMOMAXE_V)
-DECLARE_INSN(vamominue_v, MATCH_VAMOMINUE_V, MASK_VAMOMINUE_V)
-DECLARE_INSN(vamomaxue_v, MATCH_VAMOMAXUE_V, MASK_VAMOMAXUE_V)
+DECLARE_INSN(vamoswape8_v, MATCH_VAMOSWAPE8_V, MASK_VAMOSWAPE8_V)
+DECLARE_INSN(vamoadde8_v, MATCH_VAMOADDE8_V, MASK_VAMOADDE8_V)
+DECLARE_INSN(vamoxore8_v, MATCH_VAMOXORE8_V, MASK_VAMOXORE8_V)
+DECLARE_INSN(vamoande8_v, MATCH_VAMOANDE8_V, MASK_VAMOANDE8_V)
+DECLARE_INSN(vamoore8_v, MATCH_VAMOORE8_V, MASK_VAMOORE8_V)
+DECLARE_INSN(vamomine8_v, MATCH_VAMOMINE8_V, MASK_VAMOMINE8_V)
+DECLARE_INSN(vamomaxe8_v, MATCH_VAMOMAXE8_V, MASK_VAMOMAXE8_V)
+DECLARE_INSN(vamominue8_v, MATCH_VAMOMINUE8_V, MASK_VAMOMINUE8_V)
+DECLARE_INSN(vamomaxue8_v, MATCH_VAMOMAXUE8_V, MASK_VAMOMAXUE8_V)
+DECLARE_INSN(vamoswape16_v, MATCH_VAMOSWAPE16_V, MASK_VAMOSWAPE16_V)
+DECLARE_INSN(vamoadde16_v, MATCH_VAMOADDE16_V, MASK_VAMOADDE16_V)
+DECLARE_INSN(vamoxore16_v, MATCH_VAMOXORE16_V, MASK_VAMOXORE16_V)
+DECLARE_INSN(vamoande16_v, MATCH_VAMOANDE16_V, MASK_VAMOANDE16_V)
+DECLARE_INSN(vamoore16_v, MATCH_VAMOORE16_V, MASK_VAMOORE16_V)
+DECLARE_INSN(vamomine16_v, MATCH_VAMOMINE16_V, MASK_VAMOMINE16_V)
+DECLARE_INSN(vamomaxe16_v, MATCH_VAMOMAXE16_V, MASK_VAMOMAXE16_V)
+DECLARE_INSN(vamominue16_v, MATCH_VAMOMINUE16_V, MASK_VAMOMINUE16_V)
+DECLARE_INSN(vamomaxue16_v, MATCH_VAMOMAXUE16_V, MASK_VAMOMAXUE16_V)
+DECLARE_INSN(vamoswape32_v, MATCH_VAMOSWAPE32_V, MASK_VAMOSWAPE32_V)
+DECLARE_INSN(vamoadde32_v, MATCH_VAMOADDE32_V, MASK_VAMOADDE32_V)
+DECLARE_INSN(vamoxore32_v, MATCH_VAMOXORE32_V, MASK_VAMOXORE32_V)
+DECLARE_INSN(vamoande32_v, MATCH_VAMOANDE32_V, MASK_VAMOANDE32_V)
+DECLARE_INSN(vamoore32_v, MATCH_VAMOORE32_V, MASK_VAMOORE32_V)
+DECLARE_INSN(vamomine32_v, MATCH_VAMOMINE32_V, MASK_VAMOMINE32_V)
+DECLARE_INSN(vamomaxe32_v, MATCH_VAMOMAXE32_V, MASK_VAMOMAXE32_V)
+DECLARE_INSN(vamominue32_v, MATCH_VAMOMINUE32_V, MASK_VAMOMINUE32_V)
+DECLARE_INSN(vamomaxue32_v, MATCH_VAMOMAXUE32_V, MASK_VAMOMAXUE32_V)
+DECLARE_INSN(vamoswape64_v, MATCH_VAMOSWAPE64_V, MASK_VAMOSWAPE64_V)
+DECLARE_INSN(vamoadde64_v, MATCH_VAMOADDE64_V, MASK_VAMOADDE64_V)
+DECLARE_INSN(vamoxore64_v, MATCH_VAMOXORE64_V, MASK_VAMOXORE64_V)
+DECLARE_INSN(vamoande64_v, MATCH_VAMOANDE64_V, MASK_VAMOANDE64_V)
+DECLARE_INSN(vamoore64_v, MATCH_VAMOORE64_V, MASK_VAMOORE64_V)
+DECLARE_INSN(vamomine64_v, MATCH_VAMOMINE64_V, MASK_VAMOMINE64_V)
+DECLARE_INSN(vamomaxe64_v, MATCH_VAMOMAXE64_V, MASK_VAMOMAXE64_V)
+DECLARE_INSN(vamominue64_v, MATCH_VAMOMINUE64_V, MASK_VAMOMINUE64_V)
+DECLARE_INSN(vamomaxue64_v, MATCH_VAMOMAXUE64_V, MASK_VAMOMAXUE64_V)
DECLARE_INSN(vmvnfr_v, MATCH_VMVNFR_V, MASK_VMVNFR_V)
#endif
#ifdef DECLARE_CSR
diff --git a/riscv/insns/vamoadde16_v.h b/riscv/insns/vamoadde16_v.h
new file mode 100644
index 0000000..3cb3db7
--- /dev/null
+++ b/riscv/insns/vamoadde16_v.h
@@ -0,0 +1,2 @@
+//vamoadde.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs + vs3; }, uint, e16);
diff --git a/riscv/insns/vamoadde32_v.h b/riscv/insns/vamoadde32_v.h
new file mode 100644
index 0000000..2bd77fc
--- /dev/null
+++ b/riscv/insns/vamoadde32_v.h
@@ -0,0 +1,2 @@
+//vamoadde.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs + vs3; }, uint, e32);
diff --git a/riscv/insns/vamoadde64_v.h b/riscv/insns/vamoadde64_v.h
new file mode 100644
index 0000000..79ca748
--- /dev/null
+++ b/riscv/insns/vamoadde64_v.h
@@ -0,0 +1,2 @@
+//vamoadde.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs + vs3; }, uint, e64);
diff --git a/riscv/insns/vamoadde8_v.h b/riscv/insns/vamoadde8_v.h
new file mode 100644
index 0000000..06b8c79
--- /dev/null
+++ b/riscv/insns/vamoadde8_v.h
@@ -0,0 +1,2 @@
+//vamoadde.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs + vs3; }, uint, e8);
diff --git a/riscv/insns/vamoande16_v.h b/riscv/insns/vamoande16_v.h
new file mode 100644
index 0000000..be11949
--- /dev/null
+++ b/riscv/insns/vamoande16_v.h
@@ -0,0 +1,2 @@
+//vamoande.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs & vs3; }, uint, e16);
diff --git a/riscv/insns/vamoande32_v.h b/riscv/insns/vamoande32_v.h
new file mode 100644
index 0000000..7150670
--- /dev/null
+++ b/riscv/insns/vamoande32_v.h
@@ -0,0 +1,2 @@
+//vamoande.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs & vs3; }, uint, e32);
diff --git a/riscv/insns/vamoande64_v.h b/riscv/insns/vamoande64_v.h
new file mode 100644
index 0000000..3efae3b
--- /dev/null
+++ b/riscv/insns/vamoande64_v.h
@@ -0,0 +1,2 @@
+//vamoande.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs & vs3; }, uint, e64);
diff --git a/riscv/insns/vamoande8_v.h b/riscv/insns/vamoande8_v.h
new file mode 100644
index 0000000..c47645d
--- /dev/null
+++ b/riscv/insns/vamoande8_v.h
@@ -0,0 +1,2 @@
+//vamoande.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs & vs3; }, uint, e8);
diff --git a/riscv/insns/vamomaxe16_v.h b/riscv/insns/vamomaxe16_v.h
new file mode 100644
index 0000000..ca67893
--- /dev/null
+++ b/riscv/insns/vamomaxe16_v.h
@@ -0,0 +1,2 @@
+//vamomaxe.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs >= vs3 ? lhs : vs3; }, int, e16);
diff --git a/riscv/insns/vamomaxe32_v.h b/riscv/insns/vamomaxe32_v.h
new file mode 100644
index 0000000..b6823cd
--- /dev/null
+++ b/riscv/insns/vamomaxe32_v.h
@@ -0,0 +1,2 @@
+//vamomaxe.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs >= vs3 ? lhs : vs3; }, int, e32);
diff --git a/riscv/insns/vamomaxe64_v.h b/riscv/insns/vamomaxe64_v.h
new file mode 100644
index 0000000..46e8a3b
--- /dev/null
+++ b/riscv/insns/vamomaxe64_v.h
@@ -0,0 +1,2 @@
+//vamomaxe.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs >= vs3 ? lhs : vs3; }, int, e64);
diff --git a/riscv/insns/vamomaxe8_v.h b/riscv/insns/vamomaxe8_v.h
new file mode 100644
index 0000000..9697b3a
--- /dev/null
+++ b/riscv/insns/vamomaxe8_v.h
@@ -0,0 +1,2 @@
+//vamomaxe.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs >= vs3 ? lhs : vs3; }, int, e8);
diff --git a/riscv/insns/vamomaxue16_v.h b/riscv/insns/vamomaxue16_v.h
new file mode 100644
index 0000000..e05971d
--- /dev/null
+++ b/riscv/insns/vamomaxue16_v.h
@@ -0,0 +1,2 @@
+//vamomaxue.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs >= vs3 ? lhs : vs3;; }, uint, e16);
diff --git a/riscv/insns/vamomaxue32_v.h b/riscv/insns/vamomaxue32_v.h
new file mode 100644
index 0000000..9b87354
--- /dev/null
+++ b/riscv/insns/vamomaxue32_v.h
@@ -0,0 +1,2 @@
+//vamomaxue.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs >= vs3 ? lhs : vs3;; }, uint, e32);
diff --git a/riscv/insns/vamomaxue64_v.h b/riscv/insns/vamomaxue64_v.h
new file mode 100644
index 0000000..bbfbc9f
--- /dev/null
+++ b/riscv/insns/vamomaxue64_v.h
@@ -0,0 +1,2 @@
+//vamomaxue.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs >= vs3 ? lhs : vs3;; }, uint, e64);
diff --git a/riscv/insns/vamomaxue8_v.h b/riscv/insns/vamomaxue8_v.h
new file mode 100644
index 0000000..357ba24
--- /dev/null
+++ b/riscv/insns/vamomaxue8_v.h
@@ -0,0 +1,2 @@
+//vamomaxue.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs >= vs3 ? lhs : vs3;; }, uint, e8);
diff --git a/riscv/insns/vamomine16_v.h b/riscv/insns/vamomine16_v.h
new file mode 100644
index 0000000..9d1ecac
--- /dev/null
+++ b/riscv/insns/vamomine16_v.h
@@ -0,0 +1,2 @@
+//vamomine.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs < vs3 ? lhs : vs3; }, int, e16);
diff --git a/riscv/insns/vamomine32_v.h b/riscv/insns/vamomine32_v.h
new file mode 100644
index 0000000..6cb8475
--- /dev/null
+++ b/riscv/insns/vamomine32_v.h
@@ -0,0 +1,2 @@
+//vamomine.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs < vs3 ? lhs : vs3; }, int, e32);
diff --git a/riscv/insns/vamomine64_v.h b/riscv/insns/vamomine64_v.h
new file mode 100644
index 0000000..9ef3d4e
--- /dev/null
+++ b/riscv/insns/vamomine64_v.h
@@ -0,0 +1,2 @@
+//vamomine.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs < vs3 ? lhs : vs3; }, int, e64);
diff --git a/riscv/insns/vamomine8_v.h b/riscv/insns/vamomine8_v.h
new file mode 100644
index 0000000..5c035ea
--- /dev/null
+++ b/riscv/insns/vamomine8_v.h
@@ -0,0 +1,2 @@
+//vamomine.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs < vs3 ? lhs : vs3; }, int, e8);
diff --git a/riscv/insns/vamominue16_v.h b/riscv/insns/vamominue16_v.h
new file mode 100644
index 0000000..d4a8f89
--- /dev/null
+++ b/riscv/insns/vamominue16_v.h
@@ -0,0 +1,2 @@
+//vamominue.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs < vs3 ? lhs : vs3;; }, uint, e16);
diff --git a/riscv/insns/vamominue32_v.h b/riscv/insns/vamominue32_v.h
new file mode 100644
index 0000000..16296c5
--- /dev/null
+++ b/riscv/insns/vamominue32_v.h
@@ -0,0 +1,2 @@
+//vamominue.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs < vs3 ? lhs : vs3;; }, uint, e32);
diff --git a/riscv/insns/vamominue64_v.h b/riscv/insns/vamominue64_v.h
new file mode 100644
index 0000000..fd850fd
--- /dev/null
+++ b/riscv/insns/vamominue64_v.h
@@ -0,0 +1,2 @@
+//vamominue.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs < vs3 ? lhs : vs3;; }, uint, e64);
diff --git a/riscv/insns/vamominue8_v.h b/riscv/insns/vamominue8_v.h
new file mode 100644
index 0000000..3749d05
--- /dev/null
+++ b/riscv/insns/vamominue8_v.h
@@ -0,0 +1,2 @@
+//vamominue.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs < vs3 ? lhs : vs3;; }, uint, e8);
diff --git a/riscv/insns/vamoore16_v.h b/riscv/insns/vamoore16_v.h
new file mode 100644
index 0000000..a5ba1ca
--- /dev/null
+++ b/riscv/insns/vamoore16_v.h
@@ -0,0 +1,2 @@
+//vamoore.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs | vs3; }, uint, e16);
diff --git a/riscv/insns/vamoore32_v.h b/riscv/insns/vamoore32_v.h
new file mode 100644
index 0000000..94e4458
--- /dev/null
+++ b/riscv/insns/vamoore32_v.h
@@ -0,0 +1,2 @@
+//vamoore.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs | vs3; }, uint, e32);
diff --git a/riscv/insns/vamoore64_v.h b/riscv/insns/vamoore64_v.h
new file mode 100644
index 0000000..84e0394
--- /dev/null
+++ b/riscv/insns/vamoore64_v.h
@@ -0,0 +1,2 @@
+//vamoore.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs | vs3; }, uint, e64);
diff --git a/riscv/insns/vamoore8_v.h b/riscv/insns/vamoore8_v.h
new file mode 100644
index 0000000..364035d
--- /dev/null
+++ b/riscv/insns/vamoore8_v.h
@@ -0,0 +1,2 @@
+//vamoore.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs | vs3; }, uint, e8);
diff --git a/riscv/insns/vamoswape16_v.h b/riscv/insns/vamoswape16_v.h
new file mode 100644
index 0000000..31ff021
--- /dev/null
+++ b/riscv/insns/vamoswape16_v.h
@@ -0,0 +1,2 @@
+//vamoswape.v vd, (rs1), vs2, vd
+VI_AMO({ return vs3; }, uint, e16);
diff --git a/riscv/insns/vamoswape32_v.h b/riscv/insns/vamoswape32_v.h
new file mode 100644
index 0000000..a574192
--- /dev/null
+++ b/riscv/insns/vamoswape32_v.h
@@ -0,0 +1,2 @@
+//vamoswape.v vd, (rs1), vs2, vd
+VI_AMO({ return vs3; }, uint, e32);
diff --git a/riscv/insns/vamoswape64_v.h b/riscv/insns/vamoswape64_v.h
new file mode 100644
index 0000000..58bd035
--- /dev/null
+++ b/riscv/insns/vamoswape64_v.h
@@ -0,0 +1,2 @@
+//vamoswape.v vd, (rs1), vs2, vd
+VI_AMO({ return vs3; }, uint, e64);
diff --git a/riscv/insns/vamoswape8_v.h b/riscv/insns/vamoswape8_v.h
new file mode 100644
index 0000000..af37c8c
--- /dev/null
+++ b/riscv/insns/vamoswape8_v.h
@@ -0,0 +1,2 @@
+//vamoswape.v vd, (rs1), vs2, vd
+VI_AMO({ return vs3; }, uint, e8);
diff --git a/riscv/insns/vamoxore16_v.h b/riscv/insns/vamoxore16_v.h
new file mode 100644
index 0000000..61e8c32
--- /dev/null
+++ b/riscv/insns/vamoxore16_v.h
@@ -0,0 +1,2 @@
+//vamoore.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs ^ vs3; }, uint, e16);
diff --git a/riscv/insns/vamoxore32_v.h b/riscv/insns/vamoxore32_v.h
new file mode 100644
index 0000000..d48d951
--- /dev/null
+++ b/riscv/insns/vamoxore32_v.h
@@ -0,0 +1,2 @@
+//vamoore.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs ^ vs3; }, uint, e32);
diff --git a/riscv/insns/vamoxore64_v.h b/riscv/insns/vamoxore64_v.h
new file mode 100644
index 0000000..f7a3ca4
--- /dev/null
+++ b/riscv/insns/vamoxore64_v.h
@@ -0,0 +1,2 @@
+//vamoore.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs ^ vs3; }, uint, e64);
diff --git a/riscv/insns/vamoxore8_v.h b/riscv/insns/vamoxore8_v.h
new file mode 100644
index 0000000..4b6c798
--- /dev/null
+++ b/riscv/insns/vamoxore8_v.h
@@ -0,0 +1,2 @@
+//vamoore.v vd, (rs1), vs2, vd
+VI_AMO({ return lhs ^ vs3; }, uint, e8);
diff --git a/riscv/processor.cc b/riscv/processor.cc
index 123a8cc..2a0a561 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -257,6 +257,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);
@@ -282,6 +284,10 @@ 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('A') && supports_extension('V')))
+ bad_isa_string(str, "'Zvamo' extension requires 'A' and 'V'");
}
void state_t::reset(reg_t max_isa)
diff --git a/riscv/riscv.mk.in b/riscv/riscv.mk.in
index cbb6088..f63368d 100644
--- a/riscv/riscv.mk.in
+++ b/riscv/riscv.mk.in
@@ -614,6 +614,44 @@ riscv_insn_ext_v_alu_fp = \
vmfne_vf \
vmfne_vv \
+riscv_insn_ext_v_amo = \
+ vamoswape8_v \
+ vamoadde8_v \
+ vamoande8_v \
+ vamomaxe8_v \
+ vamomaxue8_v \
+ vamomine8_v \
+ vamominue8_v \
+ vamoore8_v \
+ vamoxore8_v \
+ vamoswape16_v \
+ vamoadde16_v \
+ vamoande16_v \
+ vamomaxe16_v \
+ vamomaxue16_v \
+ vamomine16_v \
+ vamominue16_v \
+ vamoore16_v \
+ vamoxore16_v \
+ vamoswape32_v \
+ vamoadde32_v \
+ vamoande32_v \
+ vamomaxe32_v \
+ vamomaxue32_v \
+ vamomine32_v \
+ vamominue32_v \
+ vamoore32_v \
+ vamoxore32_v \
+ vamoswape64_v \
+ vamoadde64_v \
+ vamoande64_v \
+ vamomaxe64_v \
+ vamomaxue64_v \
+ vamomine64_v \
+ vamominue64_v \
+ vamoore64_v \
+ vamoxore64_v \
+
riscv_insn_ext_v_ldst = \
vl1r_v \
vlb_v \
@@ -669,6 +707,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 975b5f7..eeeaff2 100644
--- a/spike_main/disasm.cc
+++ b/spike_main/disasm.cc
@@ -347,6 +347,18 @@ 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;
+ const char *fmt;
+ std::vector<const arg_t*>& arg;
+} custom_fmt_t;
std::string disassembler_t::disassemble(insn_t insn) const
{
@@ -366,6 +378,9 @@ 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_amoop = 0x1fUl << 27;
+ const uint32_t mask_width = 0x7Ul << 12;
#define DECLARE_INSN(code, match, mask) \
const uint32_t match_##code = match; \
@@ -1111,6 +1126,41 @@ disassembler_t::disassembler_t(int xlen)
#undef DISASM_OPIV_W__INSN
#undef DISASM_VFUNARY0_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 custom_fmt_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});
DISASM_INSN("c.flwsp", c_flwsp, 0, {&frd, &rvc_lwsp_address});