aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChih-Min Chao <chihmin.chao@sifive.com>2020-07-15 03:39:00 -0700
committerChih-Min Chao <chihmin.chao@sifive.com>2020-07-29 21:38:43 -0700
commiteffb92a5ecca543e27bb0ae3d7c42eee34d4ddf4 (patch)
tree744bd308e8c7dd38ea31c5203c4fffa78483b648
parent3075210b4948fb1b0a6772384c6e2ea103d75511 (diff)
downloadspike-effb92a5ecca543e27bb0ae3d7c42eee34d4ddf4.zip
spike-effb92a5ecca543e27bb0ae3d7c42eee34d4ddf4.tar.gz
spike-effb92a5ecca543e27bb0ae3d7c42eee34d4ddf4.tar.bz2
rvv: add new whole reg load/store instructions
Signed-off-by: Chih-Min Chao <chihmin.chao@sifive.com>
-rw-r--r--riscv/decode.h60
-rw-r--r--riscv/encoding.h72
-rw-r--r--riscv/insns/vl1r_v.h9
-rw-r--r--riscv/insns/vl1re16_v.h2
-rw-r--r--riscv/insns/vl1re32_v.h2
-rw-r--r--riscv/insns/vl1re64_v.h2
-rw-r--r--riscv/insns/vl1re8_v.h2
-rw-r--r--riscv/insns/vl2re16_v.h2
-rw-r--r--riscv/insns/vl2re32_v.h2
-rw-r--r--riscv/insns/vl2re64_v.h2
-rw-r--r--riscv/insns/vl2re8_v.h2
-rw-r--r--riscv/insns/vl4re16_v.h2
-rw-r--r--riscv/insns/vl4re32_v.h2
-rw-r--r--riscv/insns/vl4re64_v.h2
-rw-r--r--riscv/insns/vl4re8_v.h2
-rw-r--r--riscv/insns/vl8re16_v.h2
-rw-r--r--riscv/insns/vl8re32_v.h2
-rw-r--r--riscv/insns/vl8re64_v.h2
-rw-r--r--riscv/insns/vl8re8_v.h2
-rw-r--r--riscv/insns/vs1r_v.h9
-rw-r--r--riscv/insns/vs2r_v.h2
-rw-r--r--riscv/insns/vs4r_v.h2
-rw-r--r--riscv/insns/vs8r_v.h2
-rw-r--r--riscv/riscv.mk.in20
-rw-r--r--spike_main/disasm.cc27
25 files changed, 212 insertions, 23 deletions
diff --git a/riscv/decode.h b/riscv/decode.h
index e7642e6..bf7757a 100644
--- a/riscv/decode.h
+++ b/riscv/decode.h
@@ -1753,6 +1753,66 @@ for (reg_t i = 0; i < P.VU.vlmax && P.VU.vl != 0; ++i) { \
} \
p->VU.vstart = 0;
+#define VI_LD_WHOLE(elt_width) \
+ require_vector_novtype(true); \
+ const reg_t baseAddr = RS1; \
+ const reg_t vd = insn.rd(); \
+ const reg_t len = insn.v_nf() + 1; \
+ require_align(vd, len); \
+ const reg_t elt_per_reg = P.VU.vlenb / sizeof(elt_width ## _t); \
+ const reg_t size = len * elt_per_reg; \
+ if (P.VU.vstart < size) { \
+ reg_t i = P.VU.vstart / elt_per_reg; \
+ reg_t off = P.VU.vstart % elt_per_reg; \
+ if (off) { \
+ for (reg_t pos = off; pos < elt_per_reg; ++pos) { \
+ auto val = MMU.load_## elt_width(baseAddr + \
+ P.VU.vstart * sizeof(elt_width ## _t)); \
+ P.VU.elt<elt_width ## _t>(vd + i, pos, true) = val; \
+ P.VU.vstart++; \
+ } \
+ ++i; \
+ } \
+ for (; i < len; ++i) { \
+ for (reg_t pos = 0; pos < elt_per_reg; ++pos) { \
+ auto val = MMU.load_## elt_width(baseAddr + \
+ P.VU.vstart * sizeof(elt_width ## _t)); \
+ P.VU.elt<elt_width ## _t>(vd + i, pos, true) = val; \
+ P.VU.vstart++; \
+ } \
+ } \
+ } \
+ P.VU.vstart = 0; \
+
+#define VI_ST_WHOLE \
+ require_vector_novtype(true); \
+ const reg_t baseAddr = RS1; \
+ const reg_t vs3 = insn.rd(); \
+ const reg_t len = insn.v_nf() + 1; \
+ require_align(vs3, len); \
+ const reg_t size = len * P.VU.vlenb; \
+ \
+ if (P.VU.vstart < size) { \
+ reg_t i = P.VU.vstart / P.VU.vlenb; \
+ reg_t off = P.VU.vstart % P.VU.vlenb; \
+ if (off) { \
+ for (reg_t pos = off; pos < P.VU.vlenb; ++pos) { \
+ auto val = P.VU.elt<uint8_t>(vs3 + i, pos); \
+ MMU.store_uint8(baseAddr + P.VU.vstart, val); \
+ P.VU.vstart++; \
+ } \
+ i++; \
+ } \
+ for (; i < len; ++i) { \
+ for (reg_t pos = 0; pos < P.VU.vlenb; ++pos) { \
+ auto val = P.VU.elt<uint8_t>(vs3 + i, pos); \
+ MMU.store_uint8(baseAddr + P.VU.vstart, val); \
+ P.VU.vstart++; \
+ } \
+ } \
+ } \
+ P.VU.vstart = 0;
+
//
// vector: amo
//
diff --git a/riscv/encoding.h b/riscv/encoding.h
index 0f83171..2e18963 100644
--- a/riscv/encoding.h
+++ b/riscv/encoding.h
@@ -1092,10 +1092,46 @@
#define MASK_VLE512FF_V 0x1df0707f
#define MATCH_VLE1024FF_V 0x11007007
#define MASK_VLE1024FF_V 0x1df0707f
-#define MATCH_VL1R_V 0x2800007
-#define MASK_VL1R_V 0xfff0707f
+#define MATCH_VL1RE8_V 0x2800007
+#define MASK_VL1RE8_V 0xfff0707f
+#define MATCH_VL1RE16_V 0x2805007
+#define MASK_VL1RE16_V 0xfff0707f
+#define MATCH_VL1RE32_V 0x2806007
+#define MASK_VL1RE32_V 0xfff0707f
+#define MATCH_VL1RE64_V 0x2807007
+#define MASK_VL1RE64_V 0xfff0707f
+#define MATCH_VL2RE8_V 0x22800007
+#define MASK_VL2RE8_V 0xfff0707f
+#define MATCH_VL2RE16_V 0x22805007
+#define MASK_VL2RE16_V 0xfff0707f
+#define MATCH_VL2RE32_V 0x22806007
+#define MASK_VL2RE32_V 0xfff0707f
+#define MATCH_VL2RE64_V 0x22807007
+#define MASK_VL2RE64_V 0xfff0707f
+#define MATCH_VL4RE8_V 0x62800007
+#define MASK_VL4RE8_V 0xfff0707f
+#define MATCH_VL4RE16_V 0x62805007
+#define MASK_VL4RE16_V 0xfff0707f
+#define MATCH_VL4RE32_V 0x62806007
+#define MASK_VL4RE32_V 0xfff0707f
+#define MATCH_VL4RE64_V 0x62807007
+#define MASK_VL4RE64_V 0xfff0707f
+#define MATCH_VL8RE8_V 0xe2800007
+#define MASK_VL8RE8_V 0xfff0707f
+#define MATCH_VL8RE16_V 0xe2805007
+#define MASK_VL8RE16_V 0xfff0707f
+#define MATCH_VL8RE32_V 0xe2806007
+#define MASK_VL8RE32_V 0xfff0707f
+#define MATCH_VL8RE64_V 0xe2807007
+#define MASK_VL8RE64_V 0xfff0707f
#define MATCH_VS1R_V 0x2800027
#define MASK_VS1R_V 0xfff0707f
+#define MATCH_VS2R_V 0x22800027
+#define MASK_VS2R_V 0xfff0707f
+#define MATCH_VS4R_V 0x62800027
+#define MASK_VS4R_V 0xfff0707f
+#define MATCH_VS8R_V 0xe2800027
+#define MASK_VS8R_V 0xfff0707f
#define MATCH_VFADD_VF 0x5057
#define MASK_VFADD_VF 0xfc00707f
#define MATCH_VFSUB_VF 0x8005057
@@ -1802,6 +1838,14 @@
#define MASK_VAMOMAXUEI64_V 0xf800707f
#define MATCH_VMVNFR_V 0x9e003057
#define MASK_VMVNFR_V 0xfe00707f
+#define MATCH_VL1R_V 0x2800007
+#define MASK_VL1R_V 0xfff0707f
+#define MATCH_VL2R_V 0x2805007
+#define MASK_VL2R_V 0xfff0707f
+#define MATCH_VL4R_V 0x2806007
+#define MASK_VL4R_V 0xfff0707f
+#define MATCH_VL8R_V 0x2807007
+#define MASK_VL8R_V 0xfff0707f
#define CSR_FFLAGS 0x1
#define CSR_FRM 0x2
#define CSR_FCSR 0x3
@@ -2503,8 +2547,26 @@ DECLARE_INSN(vle128ff_v, MATCH_VLE128FF_V, MASK_VLE128FF_V)
DECLARE_INSN(vle256ff_v, MATCH_VLE256FF_V, MASK_VLE256FF_V)
DECLARE_INSN(vle512ff_v, MATCH_VLE512FF_V, MASK_VLE512FF_V)
DECLARE_INSN(vle1024ff_v, MATCH_VLE1024FF_V, MASK_VLE1024FF_V)
-DECLARE_INSN(vl1r_v, MATCH_VL1R_V, MASK_VL1R_V)
+DECLARE_INSN(vl1re8_v, MATCH_VL1RE8_V, MASK_VL1RE8_V)
+DECLARE_INSN(vl1re16_v, MATCH_VL1RE16_V, MASK_VL1RE16_V)
+DECLARE_INSN(vl1re32_v, MATCH_VL1RE32_V, MASK_VL1RE32_V)
+DECLARE_INSN(vl1re64_v, MATCH_VL1RE64_V, MASK_VL1RE64_V)
+DECLARE_INSN(vl2re8_v, MATCH_VL2RE8_V, MASK_VL2RE8_V)
+DECLARE_INSN(vl2re16_v, MATCH_VL2RE16_V, MASK_VL2RE16_V)
+DECLARE_INSN(vl2re32_v, MATCH_VL2RE32_V, MASK_VL2RE32_V)
+DECLARE_INSN(vl2re64_v, MATCH_VL2RE64_V, MASK_VL2RE64_V)
+DECLARE_INSN(vl4re8_v, MATCH_VL4RE8_V, MASK_VL4RE8_V)
+DECLARE_INSN(vl4re16_v, MATCH_VL4RE16_V, MASK_VL4RE16_V)
+DECLARE_INSN(vl4re32_v, MATCH_VL4RE32_V, MASK_VL4RE32_V)
+DECLARE_INSN(vl4re64_v, MATCH_VL4RE64_V, MASK_VL4RE64_V)
+DECLARE_INSN(vl8re8_v, MATCH_VL8RE8_V, MASK_VL8RE8_V)
+DECLARE_INSN(vl8re16_v, MATCH_VL8RE16_V, MASK_VL8RE16_V)
+DECLARE_INSN(vl8re32_v, MATCH_VL8RE32_V, MASK_VL8RE32_V)
+DECLARE_INSN(vl8re64_v, MATCH_VL8RE64_V, MASK_VL8RE64_V)
DECLARE_INSN(vs1r_v, MATCH_VS1R_V, MASK_VS1R_V)
+DECLARE_INSN(vs2r_v, MATCH_VS2R_V, MASK_VS2R_V)
+DECLARE_INSN(vs4r_v, MATCH_VS4R_V, MASK_VS4R_V)
+DECLARE_INSN(vs8r_v, MATCH_VS8R_V, MASK_VS8R_V)
DECLARE_INSN(vfadd_vf, MATCH_VFADD_VF, MASK_VFADD_VF)
DECLARE_INSN(vfsub_vf, MATCH_VFSUB_VF, MASK_VFSUB_VF)
DECLARE_INSN(vfmin_vf, MATCH_VFMIN_VF, MASK_VFMIN_VF)
@@ -2858,6 +2920,10 @@ DECLARE_INSN(vamomaxei64_v, MATCH_VAMOMAXEI64_V, MASK_VAMOMAXEI64_V)
DECLARE_INSN(vamominuei64_v, MATCH_VAMOMINUEI64_V, MASK_VAMOMINUEI64_V)
DECLARE_INSN(vamomaxuei64_v, MATCH_VAMOMAXUEI64_V, MASK_VAMOMAXUEI64_V)
DECLARE_INSN(vmvnfr_v, MATCH_VMVNFR_V, MASK_VMVNFR_V)
+DECLARE_INSN(vl1r_v, MATCH_VL1R_V, MASK_VL1R_V)
+DECLARE_INSN(vl2r_v, MATCH_VL2R_V, MASK_VL2R_V)
+DECLARE_INSN(vl4r_v, MATCH_VL4R_V, MASK_VL4R_V)
+DECLARE_INSN(vl8r_v, MATCH_VL8R_V, MASK_VL8R_V)
#endif
#ifdef DECLARE_CSR
DECLARE_CSR(fflags, CSR_FFLAGS)
diff --git a/riscv/insns/vl1r_v.h b/riscv/insns/vl1r_v.h
deleted file mode 100644
index 9289634..0000000
--- a/riscv/insns/vl1r_v.h
+++ /dev/null
@@ -1,9 +0,0 @@
-// vl1r.v vd, (rs1)
-require_vector_novtype(true);
-const reg_t baseAddr = RS1;
-const reg_t vd = insn.rd();
-for (reg_t i = P.VU.vstart; i < P.VU.vlenb; ++i) {
- auto val = MMU.load_uint8(baseAddr + i);
- P.VU.elt<uint8_t>(vd, i, true) = val;
-}
-P.VU.vstart = 0;
diff --git a/riscv/insns/vl1re16_v.h b/riscv/insns/vl1re16_v.h
new file mode 100644
index 0000000..220e83e
--- /dev/null
+++ b/riscv/insns/vl1re16_v.h
@@ -0,0 +1,2 @@
+// vl1re16.v vd, (rs1)
+VI_LD_WHOLE(uint16);
diff --git a/riscv/insns/vl1re32_v.h b/riscv/insns/vl1re32_v.h
new file mode 100644
index 0000000..e72ca02
--- /dev/null
+++ b/riscv/insns/vl1re32_v.h
@@ -0,0 +1,2 @@
+// vl1re32.v vd, (rs1)
+VI_LD_WHOLE(uint32);
diff --git a/riscv/insns/vl1re64_v.h b/riscv/insns/vl1re64_v.h
new file mode 100644
index 0000000..265701a
--- /dev/null
+++ b/riscv/insns/vl1re64_v.h
@@ -0,0 +1,2 @@
+// vl1re64.v vd, (rs1)
+VI_LD_WHOLE(uint64);
diff --git a/riscv/insns/vl1re8_v.h b/riscv/insns/vl1re8_v.h
new file mode 100644
index 0000000..b4ce661
--- /dev/null
+++ b/riscv/insns/vl1re8_v.h
@@ -0,0 +1,2 @@
+// vl1re8.v vd, (rs1)
+VI_LD_WHOLE(uint8);
diff --git a/riscv/insns/vl2re16_v.h b/riscv/insns/vl2re16_v.h
new file mode 100644
index 0000000..2846edd
--- /dev/null
+++ b/riscv/insns/vl2re16_v.h
@@ -0,0 +1,2 @@
+// vl2e16.v vd, (rs1)
+VI_LD_WHOLE(uint16);
diff --git a/riscv/insns/vl2re32_v.h b/riscv/insns/vl2re32_v.h
new file mode 100644
index 0000000..5cea835
--- /dev/null
+++ b/riscv/insns/vl2re32_v.h
@@ -0,0 +1,2 @@
+// vl2re32.v vd, (rs1)
+VI_LD_WHOLE(uint32);
diff --git a/riscv/insns/vl2re64_v.h b/riscv/insns/vl2re64_v.h
new file mode 100644
index 0000000..efdf2ce
--- /dev/null
+++ b/riscv/insns/vl2re64_v.h
@@ -0,0 +1,2 @@
+// vl2re64.v vd, (rs1)
+VI_LD_WHOLE(uint64);
diff --git a/riscv/insns/vl2re8_v.h b/riscv/insns/vl2re8_v.h
new file mode 100644
index 0000000..fcc3c4c
--- /dev/null
+++ b/riscv/insns/vl2re8_v.h
@@ -0,0 +1,2 @@
+// vl2re8.v vd, (rs1)
+VI_LD_WHOLE(uint8);
diff --git a/riscv/insns/vl4re16_v.h b/riscv/insns/vl4re16_v.h
new file mode 100644
index 0000000..0363418
--- /dev/null
+++ b/riscv/insns/vl4re16_v.h
@@ -0,0 +1,2 @@
+// vl4re16.v vd, (rs1)
+VI_LD_WHOLE(uint16);
diff --git a/riscv/insns/vl4re32_v.h b/riscv/insns/vl4re32_v.h
new file mode 100644
index 0000000..e37cc1a
--- /dev/null
+++ b/riscv/insns/vl4re32_v.h
@@ -0,0 +1,2 @@
+// vl4re32.v vd, (rs1)
+VI_LD_WHOLE(uint32);
diff --git a/riscv/insns/vl4re64_v.h b/riscv/insns/vl4re64_v.h
new file mode 100644
index 0000000..11486f5
--- /dev/null
+++ b/riscv/insns/vl4re64_v.h
@@ -0,0 +1,2 @@
+// vl4re64.v vd, (rs1)
+VI_LD_WHOLE(uint64);
diff --git a/riscv/insns/vl4re8_v.h b/riscv/insns/vl4re8_v.h
new file mode 100644
index 0000000..f9ce3ff
--- /dev/null
+++ b/riscv/insns/vl4re8_v.h
@@ -0,0 +1,2 @@
+// vl4re8.v vd, (rs1)
+VI_LD_WHOLE(uint8);
diff --git a/riscv/insns/vl8re16_v.h b/riscv/insns/vl8re16_v.h
new file mode 100644
index 0000000..0b3f141
--- /dev/null
+++ b/riscv/insns/vl8re16_v.h
@@ -0,0 +1,2 @@
+// vl8re16.v vd, (rs1)
+VI_LD_WHOLE(uint16);
diff --git a/riscv/insns/vl8re32_v.h b/riscv/insns/vl8re32_v.h
new file mode 100644
index 0000000..3372b89
--- /dev/null
+++ b/riscv/insns/vl8re32_v.h
@@ -0,0 +1,2 @@
+// vl8re32.v vd, (rs1)
+VI_LD_WHOLE(uint32);
diff --git a/riscv/insns/vl8re64_v.h b/riscv/insns/vl8re64_v.h
new file mode 100644
index 0000000..f9a9ca9
--- /dev/null
+++ b/riscv/insns/vl8re64_v.h
@@ -0,0 +1,2 @@
+// vl8re64.v vd, (rs1)
+VI_LD_WHOLE(uint64);
diff --git a/riscv/insns/vl8re8_v.h b/riscv/insns/vl8re8_v.h
new file mode 100644
index 0000000..ee05e81
--- /dev/null
+++ b/riscv/insns/vl8re8_v.h
@@ -0,0 +1,2 @@
+// vl8re8.v vd, (rs1)
+VI_LD_WHOLE(uint8);
diff --git a/riscv/insns/vs1r_v.h b/riscv/insns/vs1r_v.h
index 5ccbd5f..1932ec0 100644
--- a/riscv/insns/vs1r_v.h
+++ b/riscv/insns/vs1r_v.h
@@ -1,9 +1,2 @@
// vs1r.v vs3, (rs1)
-require_vector_novtype(true);
-const reg_t baseAddr = RS1;
-const reg_t vs3 = insn.rd();
-for (reg_t i = P.VU.vstart; i < P.VU.vlenb; ++i) {
- auto val = P.VU.elt<uint8_t>(vs3, i);
- MMU.store_uint8(baseAddr + i, val);
-}
-P.VU.vstart = 0;
+VI_ST_WHOLE
diff --git a/riscv/insns/vs2r_v.h b/riscv/insns/vs2r_v.h
new file mode 100644
index 0000000..2e515b4
--- /dev/null
+++ b/riscv/insns/vs2r_v.h
@@ -0,0 +1,2 @@
+// vs2r.v vs3, (rs1)
+VI_ST_WHOLE
diff --git a/riscv/insns/vs4r_v.h b/riscv/insns/vs4r_v.h
new file mode 100644
index 0000000..161bf89
--- /dev/null
+++ b/riscv/insns/vs4r_v.h
@@ -0,0 +1,2 @@
+// vs4r.v vs3, (rs1)
+VI_ST_WHOLE
diff --git a/riscv/insns/vs8r_v.h b/riscv/insns/vs8r_v.h
new file mode 100644
index 0000000..1ad2575
--- /dev/null
+++ b/riscv/insns/vs8r_v.h
@@ -0,0 +1,2 @@
+// vs8r.v vs3, (rs1)
+VI_ST_WHOLE
diff --git a/riscv/riscv.mk.in b/riscv/riscv.mk.in
index 0ac77f2..ad1c886 100644
--- a/riscv/riscv.mk.in
+++ b/riscv/riscv.mk.in
@@ -709,6 +709,22 @@ riscv_insn_ext_v_ldst = \
vle16ff_v \
vle32ff_v \
vle64ff_v \
+ vl1re8_v \
+ vl2re8_v \
+ vl4re8_v \
+ vl8re8_v \
+ vl1re16_v \
+ vl2re16_v \
+ vl4re16_v \
+ vl8re16_v \
+ vl1re32_v \
+ vl2re32_v \
+ vl4re32_v \
+ vl8re32_v \
+ vl1re64_v \
+ vl2re64_v \
+ vl4re64_v \
+ vl8re64_v \
vse8_v \
vse16_v \
vse32_v \
@@ -725,8 +741,10 @@ riscv_insn_ext_v_ldst = \
vsuxei16_v \
vsuxei32_v \
vsuxei64_v \
- vl1r_v \
vs1r_v \
+ vs2r_v \
+ vs4r_v \
+ vs8r_v \
riscv_insn_ext_v_ctrl = \
vsetvli \
diff --git a/spike_main/disasm.cc b/spike_main/disasm.cc
index e30ff52..5125b17 100644
--- a/spike_main/disasm.cc
+++ b/spike_main/disasm.cc
@@ -794,10 +794,33 @@ disassembler_t::disassembler_t(int xlen)
));
}
}
+
+ const custom_fmt_t template_insn2[] = {
+ {match_vl1re8_v, mask_vl1re8_v, "vl%dre%d.v", v_ld_unit},
+ };
+
+ for (reg_t i = 0, nf = 7; nf < 4; i++, nf >>= 1) {
+ 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, item.mask | mask_nf, item.arg
+ ));
+ }
+ }
}
- DISASM_INSN("vl1r.v", vl1r_v, 0, {&vd, &v_address});
- DISASM_INSN("vs1r.v", vs1r_v, 0, {&vs3, &v_address});
+ #define DISASM_ST_WHOLE_INSN(name, nf) \
+ add_insn(new disasm_insn_t(#name, match_vs1r_v | (nf << 29), \
+ mask_vs1r_v | mask_nf, \
+ {&vs3, &v_address}));
+ DISASM_ST_WHOLE_INSN(vs1r.v, 0);
+ DISASM_ST_WHOLE_INSN(vs2r.v, 1);
+ DISASM_ST_WHOLE_INSN(vs4r.v, 3);
+ DISASM_ST_WHOLE_INSN(vs8r.v, 7);
+
+ #undef DISASM_ST_WHOLE_INSN
#define DISASM_OPIV_VXI_INSN(name, sign, suf) \
add_insn(new disasm_insn_t(#name "." #suf "v", \