aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChih-Min Chao <chihmin.chao@sifive.com>2020-08-03 01:25:53 -0700
committerChih-Min Chao <chihmin.chao@sifive.com>2020-08-03 21:53:16 -0700
commit6e4977abdbe16dc7923a709cf3b3defb871c9061 (patch)
tree579ac656ad7c3aceef1265004ef9e094c9937074
parent959700ec11d5c5e8417533e6cddfada1a83c4770 (diff)
downloadspike-6e4977abdbe16dc7923a709cf3b3defb871c9061.zip
spike-6e4977abdbe16dc7923a709cf3b3defb871c9061.tar.gz
spike-6e4977abdbe16dc7923a709cf3b3defb871c9061.tar.bz2
rvv: add 'vstartalu" option to --varch arugment
except for load/store instructions 0 : all instruction can't have non-zero vstart not 0 : all instruction can have non-zero vstart if it is not required vstart must be zero in spec the default value is 1 Signed-off-by: Chih-Min Chao <chihmin.chao@sifive.com>
-rw-r--r--riscv/decode.h36
-rw-r--r--riscv/insns/vfirst_m.h2
-rw-r--r--riscv/insns/vfmv_f_s.h2
-rw-r--r--riscv/insns/vfmv_s_f.h2
-rw-r--r--riscv/insns/vid_v.h2
-rw-r--r--riscv/insns/viota_m.h2
-rw-r--r--riscv/insns/vmerge_vim.h2
-rw-r--r--riscv/insns/vmerge_vvm.h2
-rw-r--r--riscv/insns/vmerge_vxm.h2
-rw-r--r--riscv/insns/vmsbf_m.h2
-rw-r--r--riscv/insns/vmsif_m.h2
-rw-r--r--riscv/insns/vmsof_m.h2
-rw-r--r--riscv/insns/vmv_s_x.h2
-rw-r--r--riscv/insns/vmv_v_i.h2
-rw-r--r--riscv/insns/vmv_v_v.h2
-rw-r--r--riscv/insns/vmv_v_x.h2
-rw-r--r--riscv/insns/vmv_x_s.h2
-rw-r--r--riscv/insns/vmvnfr_v.h2
-rw-r--r--riscv/insns/vpopc_m.h2
-rw-r--r--riscv/insns/vsetvl.h2
-rw-r--r--riscv/insns/vsetvli.h2
-rw-r--r--riscv/processor.cc4
-rw-r--r--riscv/processor.h1
23 files changed, 45 insertions, 36 deletions
diff --git a/riscv/decode.h b/riscv/decode.h
index 9f8f786..c64cacc 100644
--- a/riscv/decode.h
+++ b/riscv/decode.h
@@ -240,18 +240,22 @@ private:
#define require_accelerator require((STATE.mstatus & MSTATUS_XS) != 0)
#define require_vector_vs require((STATE.mstatus & MSTATUS_VS) != 0);
-#define require_vector \
+#define require_vector(alu) \
do { \
require_vector_vs; \
require_extension('V'); \
require(!P.VU.vill); \
+ if (alu && !P.VU.vstart_alu) \
+ require(P.VU.vstart == 0); \
WRITE_VSTATUS; \
dirty_vs_state; \
} while (0);
-#define require_vector_novtype(is_log) \
+#define require_vector_novtype(is_log, alu) \
do { \
require_vector_vs; \
require_extension('V'); \
+ if (alu && !P.VU.vstart_alu) \
+ require(P.VU.vstart == 0); \
if (is_log) \
WRITE_VSTATUS; \
dirty_vs_state; \
@@ -468,7 +472,7 @@ static inline bool is_aligned(const unsigned val, const unsigned pos)
}
#define VI_NARROW_CHECK_COMMON \
- require_vector;\
+ require_vector(true);\
require(P.VU.vflmul <= 4); \
require(P.VU.vsew * 2 <= P.VU.ELEN); \
require_align(insn.rs2(), P.VU.vflmul * 2); \
@@ -476,14 +480,14 @@ static inline bool is_aligned(const unsigned val, const unsigned pos)
require_vm; \
#define VI_WIDE_CHECK_COMMON \
- require_vector;\
+ require_vector(true);\
require(P.VU.vflmul <= 4); \
require(P.VU.vsew * 2 <= P.VU.ELEN); \
require_align(insn.rd(), P.VU.vflmul * 2); \
require_vm; \
#define VI_CHECK_ST_INDEX(elt_width) \
- require_vector; \
+ require_vector(false); \
float vemul = ((float)elt_width / P.VU.vsew * P.VU.vflmul); \
require(vemul >= 0.125 && vemul <= 8); \
reg_t emul = vemul < 1 ? 1 : vemul; \
@@ -532,7 +536,7 @@ static inline bool is_aligned(const unsigned val, const unsigned pos)
}
#define VI_CHECK_STORE(elt_width) \
- require_vector; \
+ require_vector(false); \
reg_t veew = sizeof(elt_width##_t) * 8; \
float vemul = ((float)veew / P.VU.vsew * P.VU.vflmul); \
reg_t emul = vemul < 1 ? 1 : vemul; \
@@ -563,7 +567,7 @@ static inline bool is_aligned(const unsigned val, const unsigned pos)
}
#define VI_CHECK_QSS(is_vs1) \
- require_vector;\
+ require_vector(true);\
p->supports_extension(EXT_ZVQMAC); \
require(P.VU.vflmul <= 2); \
require(P.VU.vsew * 4 <= P.VU.ELEN); \
@@ -604,7 +608,7 @@ static inline bool is_aligned(const unsigned val, const unsigned pos)
require_align(insn.rs1(), P.VU.vflmul); \
#define VI_CHECK_REDUCTION(is_wide) \
- require_vector;\
+ require_vector(true);\
if (is_wide) {\
require(P.VU.vsew * 2 <= P.VU.ELEN); \
} \
@@ -624,7 +628,7 @@ static inline bool is_aligned(const unsigned val, const unsigned pos)
//
#define VI_GENERAL_LOOP_BASE \
require(P.VU.vsew >= e8 && P.VU.vsew <= e64); \
- require_vector;\
+ require_vector(true);\
reg_t vl = P.VU.vl; \
reg_t sew = P.VU.vsew; \
reg_t rd_num = insn.rd(); \
@@ -649,7 +653,7 @@ static inline bool is_aligned(const unsigned val, const unsigned pos)
#define VI_LOOP_CMP_BASE \
require(P.VU.vsew >= e8 && P.VU.vsew <= e64); \
- require_vector;\
+ require_vector(true);\
reg_t vl = P.VU.vl; \
reg_t sew = P.VU.vsew; \
reg_t rd_num = insn.rd(); \
@@ -668,7 +672,7 @@ static inline bool is_aligned(const unsigned val, const unsigned pos)
#define VI_LOOP_MASK(op) \
require(P.VU.vsew <= e64); \
- require_vector;\
+ require_vector(true);\
reg_t vl = P.VU.vl; \
for (reg_t i = P.VU.vstart; i < vl; ++i) { \
int midx = i / 64; \
@@ -1749,7 +1753,7 @@ 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); \
+ require_vector_novtype(true, false); \
const reg_t baseAddr = RS1; \
const reg_t vd = insn.rd(); \
const reg_t len = insn.v_nf() + 1; \
@@ -1780,7 +1784,7 @@ for (reg_t i = 0; i < P.VU.vlmax && P.VU.vl != 0; ++i) { \
P.VU.vstart = 0; \
#define VI_ST_WHOLE \
- require_vector_novtype(true); \
+ require_vector_novtype(true, false); \
const reg_t baseAddr = RS1; \
const reg_t vs3 = insn.rd(); \
const reg_t len = insn.v_nf() + 1; \
@@ -1812,7 +1816,7 @@ for (reg_t i = 0; i < P.VU.vlmax && P.VU.vl != 0; ++i) { \
// vector: amo
//
#define VI_AMO(op, type, idx_type) \
- require_vector; \
+ require_vector(false); \
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); \
@@ -1912,7 +1916,7 @@ for (reg_t i = 0; i < P.VU.vlmax && P.VU.vl != 0; ++i) { \
require((P.VU.vsew == e16 && p->supports_extension(EXT_ZFH)) || \
(P.VU.vsew == e32 && p->supports_extension('F')) || \
(P.VU.vsew == e64 && p->supports_extension('D'))); \
- require_vector;\
+ require_vector(true);\
reg_t vl = P.VU.vl; \
reg_t rd_num = insn.rd(); \
reg_t rs1_num = insn.rs1(); \
@@ -2295,7 +2299,7 @@ for (reg_t i = 0; i < P.VU.vlmax && P.VU.vl != 0; ++i) { \
#define VI_VFP_LOOP_SCALE_BASE \
require_fp; \
- require_vector;\
+ require_vector(true);\
require((P.VU.vsew == e8 && p->supports_extension(EXT_ZFH)) || \
(P.VU.vsew == e16 && p->supports_extension('F')) || \
(P.VU.vsew == e32 && p->supports_extension('D'))); \
diff --git a/riscv/insns/vfirst_m.h b/riscv/insns/vfirst_m.h
index 40e2f09..3095723 100644
--- a/riscv/insns/vfirst_m.h
+++ b/riscv/insns/vfirst_m.h
@@ -1,6 +1,6 @@
// vmfirst rd, vs2
require(P.VU.vsew >= e8 && P.VU.vsew <= e64);
-require_vector;
+require_vector(true);
reg_t vl = P.VU.vl;
reg_t sew = P.VU.vsew;
reg_t rd_num = insn.rd();
diff --git a/riscv/insns/vfmv_f_s.h b/riscv/insns/vfmv_f_s.h
index 2f82ce8..47e3c3b 100644
--- a/riscv/insns/vfmv_f_s.h
+++ b/riscv/insns/vfmv_f_s.h
@@ -1,5 +1,5 @@
// vfmv_f_s: rd = vs2[0] (rs1=0)
-require_vector;
+require_vector(true);
require_fp;
require((P.VU.vsew == e16 && p->supports_extension(EXT_ZFH)) ||
(P.VU.vsew == e32 && p->supports_extension('F')) ||
diff --git a/riscv/insns/vfmv_s_f.h b/riscv/insns/vfmv_s_f.h
index 17c85d3..4a4c105 100644
--- a/riscv/insns/vfmv_s_f.h
+++ b/riscv/insns/vfmv_s_f.h
@@ -1,5 +1,5 @@
// vfmv_s_f: vd[0] = rs1 (vs2=0)
-require_vector;
+require_vector(true);
require_fp;
require((P.VU.vsew == e16 && p->supports_extension(EXT_ZFH)) ||
(P.VU.vsew == e32 && p->supports_extension('F')) ||
diff --git a/riscv/insns/vid_v.h b/riscv/insns/vid_v.h
index 786432f..012d124 100644
--- a/riscv/insns/vid_v.h
+++ b/riscv/insns/vid_v.h
@@ -1,6 +1,6 @@
// vmpopc rd, vs2, vm
require(P.VU.vsew >= e8 && P.VU.vsew <= e64);
-require_vector;
+require_vector(true);
reg_t vl = P.VU.vl;
reg_t sew = P.VU.vsew;
reg_t rd_num = insn.rd();
diff --git a/riscv/insns/viota_m.h b/riscv/insns/viota_m.h
index 8b019aa..a436825 100644
--- a/riscv/insns/viota_m.h
+++ b/riscv/insns/viota_m.h
@@ -1,6 +1,6 @@
// vmpopc rd, vs2, vm
require(P.VU.vsew >= e8 && P.VU.vsew <= e64);
-require_vector;
+require_vector(true);
reg_t vl = P.VU.vl;
reg_t sew = P.VU.vsew;
reg_t rd_num = insn.rd();
diff --git a/riscv/insns/vmerge_vim.h b/riscv/insns/vmerge_vim.h
index b20bcde..fd6ae1c 100644
--- a/riscv/insns/vmerge_vim.h
+++ b/riscv/insns/vmerge_vim.h
@@ -1,5 +1,5 @@
// vmerge.vim vd, vs2, simm5
-require_vector;
+require_vector(true);
VI_CHECK_SSS(false);
VI_VVXI_MERGE_LOOP
({
diff --git a/riscv/insns/vmerge_vvm.h b/riscv/insns/vmerge_vvm.h
index d670554..df416b2 100644
--- a/riscv/insns/vmerge_vvm.h
+++ b/riscv/insns/vmerge_vvm.h
@@ -1,5 +1,5 @@
// vmerge.vvm vd, vs2, vs1
-require_vector;
+require_vector(true);
VI_CHECK_SSS(true);
VI_VVXI_MERGE_LOOP
({
diff --git a/riscv/insns/vmerge_vxm.h b/riscv/insns/vmerge_vxm.h
index 3fd68cb..122a7b7 100644
--- a/riscv/insns/vmerge_vxm.h
+++ b/riscv/insns/vmerge_vxm.h
@@ -1,5 +1,5 @@
// vmerge.vxm vd, vs2, rs1
-require_vector;
+require_vector(true);
VI_CHECK_SSS(false);
VI_VVXI_MERGE_LOOP
({
diff --git a/riscv/insns/vmsbf_m.h b/riscv/insns/vmsbf_m.h
index d90df5e..a4195cf 100644
--- a/riscv/insns/vmsbf_m.h
+++ b/riscv/insns/vmsbf_m.h
@@ -1,6 +1,6 @@
// vmsbf.m vd, vs2, vm
require(P.VU.vsew >= e8 && P.VU.vsew <= e64);
-require_vector;
+require_vector(true);
require(P.VU.vstart == 0);
require_vm;
require(insn.rd() != insn.rs2());
diff --git a/riscv/insns/vmsif_m.h b/riscv/insns/vmsif_m.h
index 6e941eb..a16ef68 100644
--- a/riscv/insns/vmsif_m.h
+++ b/riscv/insns/vmsif_m.h
@@ -1,6 +1,6 @@
// vmsif.m rd, vs2, vm
require(P.VU.vsew >= e8 && P.VU.vsew <= e64);
-require_vector;
+require_vector(true);
require(P.VU.vstart == 0);
require_vm;
require(insn.rd() != insn.rs2());
diff --git a/riscv/insns/vmsof_m.h b/riscv/insns/vmsof_m.h
index 9dd122d..5ef0bfd 100644
--- a/riscv/insns/vmsof_m.h
+++ b/riscv/insns/vmsof_m.h
@@ -1,6 +1,6 @@
// vmsof.m rd, vs2, vm
require(P.VU.vsew >= e8 && P.VU.vsew <= e64);
-require_vector;
+require_vector(true);
require(P.VU.vstart == 0);
require_vm;
require(insn.rd() != insn.rs2());
diff --git a/riscv/insns/vmv_s_x.h b/riscv/insns/vmv_s_x.h
index 74ab9e0..0e6a13e 100644
--- a/riscv/insns/vmv_s_x.h
+++ b/riscv/insns/vmv_s_x.h
@@ -1,5 +1,5 @@
// vmv_s_x: vd[0] = rs1
-require_vector;
+require_vector(true);
require(insn.v_vm() == 1);
require(P.VU.vsew >= e8 && P.VU.vsew <= e64);
reg_t vl = P.VU.vl;
diff --git a/riscv/insns/vmv_v_i.h b/riscv/insns/vmv_v_i.h
index f6b5b48..a760779 100644
--- a/riscv/insns/vmv_v_i.h
+++ b/riscv/insns/vmv_v_i.h
@@ -1,5 +1,5 @@
// vmv.v.i vd, simm5
-require_vector;
+require_vector(true);
VI_CHECK_SSS(false);
VI_VVXI_MERGE_LOOP
({
diff --git a/riscv/insns/vmv_v_v.h b/riscv/insns/vmv_v_v.h
index 523f2d9..d7f47d0 100644
--- a/riscv/insns/vmv_v_v.h
+++ b/riscv/insns/vmv_v_v.h
@@ -1,5 +1,5 @@
// vvmv.v.v vd, vs1
-require_vector;
+require_vector(true);
VI_CHECK_SSS(true);
VI_VVXI_MERGE_LOOP
({
diff --git a/riscv/insns/vmv_v_x.h b/riscv/insns/vmv_v_x.h
index 7528f41..fa7c920 100644
--- a/riscv/insns/vmv_v_x.h
+++ b/riscv/insns/vmv_v_x.h
@@ -1,5 +1,5 @@
// vmv.v.x vd, rs1
-require_vector;
+require_vector(true);
VI_CHECK_SSS(false);
VI_VVXI_MERGE_LOOP
({
diff --git a/riscv/insns/vmv_x_s.h b/riscv/insns/vmv_x_s.h
index 04cad1c..2c03e43 100644
--- a/riscv/insns/vmv_x_s.h
+++ b/riscv/insns/vmv_x_s.h
@@ -1,5 +1,5 @@
// vmv_x_s: rd = vs2[rs1]
-require_vector;
+require_vector(true);
require(insn.v_vm() == 1);
uint64_t xmask = UINT64_MAX >> (64 - P.get_max_xlen());
reg_t rs1 = RS1;
diff --git a/riscv/insns/vmvnfr_v.h b/riscv/insns/vmvnfr_v.h
index aedb521..96f0074 100644
--- a/riscv/insns/vmvnfr_v.h
+++ b/riscv/insns/vmvnfr_v.h
@@ -1,5 +1,5 @@
// vmv1r.v vd, vs2
-require_vector_novtype(true);
+require_vector_novtype(true, true);
const reg_t baseAddr = RS1;
const reg_t vd = insn.rd();
const reg_t vs2 = insn.rs2();
diff --git a/riscv/insns/vpopc_m.h b/riscv/insns/vpopc_m.h
index 9eaca1e..c204b2c 100644
--- a/riscv/insns/vpopc_m.h
+++ b/riscv/insns/vpopc_m.h
@@ -1,6 +1,6 @@
// vmpopc rd, vs2, vm
require(P.VU.vsew >= e8 && P.VU.vsew <= e64);
-require_vector;
+require_vector(true);
reg_t vl = P.VU.vl;
reg_t sew = P.VU.vsew;
reg_t rd_num = insn.rd();
diff --git a/riscv/insns/vsetvl.h b/riscv/insns/vsetvl.h
index 4d03542..2969edc 100644
--- a/riscv/insns/vsetvl.h
+++ b/riscv/insns/vsetvl.h
@@ -1,2 +1,2 @@
-require_vector_novtype(false);
+require_vector_novtype(false, false);
WRITE_RD(P.VU.set_vl(insn.rd(), insn.rs1(), RS1, RS2));
diff --git a/riscv/insns/vsetvli.h b/riscv/insns/vsetvli.h
index d1f43b5..7b1f1d7 100644
--- a/riscv/insns/vsetvli.h
+++ b/riscv/insns/vsetvli.h
@@ -1,2 +1,2 @@
-require_vector_novtype(false);
+require_vector_novtype(false, false);
WRITE_RD(P.VU.set_vl(insn.rd(), insn.rs1(), RS1, insn.v_zimm11()));
diff --git a/riscv/processor.cc b/riscv/processor.cc
index 50092c8..9f51a3f 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -119,6 +119,7 @@ void processor_t::parse_varch_string(const char* s)
int vlen = 0;
int elen = 0;
int slen = 0;
+ int vstart_alu = 1;
while (pos < len) {
std::string attr = get_string_token(str, ':', pos);
@@ -131,6 +132,8 @@ void processor_t::parse_varch_string(const char* s)
slen = get_int_token(str, ',', pos);
else if (attr == "elen")
elen = get_int_token(str, ',', pos);
+ else if (attr == "vstartalu")
+ vstart_alu = get_int_token(str, ',', pos);
else
bad_varch_string(s, "Unsupported token");
@@ -160,6 +163,7 @@ void processor_t::parse_varch_string(const char* s)
VU.VLEN = vlen;
VU.ELEN = elen;
VU.vlenb = vlen / 8;
+ VU.vstart_alu = vstart_alu;
}
static std::string strtolower(const char* str)
diff --git a/riscv/processor.h b/riscv/processor.h
index 6c16eb9..5d7baeb 100644
--- a/riscv/processor.h
+++ b/riscv/processor.h
@@ -477,6 +477,7 @@ public:
float vflmul;
reg_t ELEN, VLEN;
bool vill;
+ bool vstart_alu;
// vector element for varies SEW
template<class T>