aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChih-Min Chao <chihmin.chao@sifive.com>2019-10-23 01:36:48 -0700
committerChih-Min Chao <chihmin.chao@sifive.com>2019-11-11 19:02:35 -0800
commit4808f84a1833de2bbd87a92355f75991c4697312 (patch)
tree464a74599559173af989a150973a76539d1ba663
parente289b996c6ef60693b394b57bb53034c38eff4e4 (diff)
downloadriscv-isa-sim-4808f84a1833de2bbd87a92355f75991c4697312.zip
riscv-isa-sim-4808f84a1833de2bbd87a92355f75991c4697312.tar.gz
riscv-isa-sim-4808f84a1833de2bbd87a92355f75991c4697312.tar.bz2
rvv: add reg checking for specifial instructions
Signed-off-by: Chih-Min Chao <chihmin.chao@sifive.com>
-rw-r--r--riscv/decode.h5
-rw-r--r--riscv/insns/vcompress_vm.h23
-rw-r--r--riscv/insns/vfcvt_f_x_v.h2
-rw-r--r--riscv/insns/vfcvt_f_xu_v.h2
-rw-r--r--riscv/insns/vfcvt_x_f_v.h2
-rw-r--r--riscv/insns/vfmerge_vfm.h11
-rw-r--r--riscv/insns/vfmv_f_s.h1
-rw-r--r--riscv/insns/vfmv_v_f.h13
-rw-r--r--riscv/insns/vid_v.h3
-rw-r--r--riscv/insns/viota_m.h4
-rw-r--r--riscv/insns/vmv_v_v.h1
-rw-r--r--riscv/insns/vrgather_vi.h18
-rw-r--r--riscv/insns/vrgather_vv.h24
-rw-r--r--riscv/insns/vrgather_vx.h21
14 files changed, 51 insertions, 79 deletions
diff --git a/riscv/decode.h b/riscv/decode.h
index dd98f8b..e19dffa 100644
--- a/riscv/decode.h
+++ b/riscv/decode.h
@@ -381,11 +381,6 @@ static inline bool is_overlapped(const int astart, const int asize,
if (insn.v_vm() == 0) \
require(insn.rd() != 0);
-#define VI_CHECK_VREG_OVERLAP(v1, v2) \
- require(!is_overlapped(v1, P.VU.vlmul, v2, P.VU.vlmul));
-
-#define VI_CHECK_SS \
- require(!is_overlapped(insn.rd(), P.VU.vlmul, insn.rs2(), P.VU.vlmul));
#define VI_CHECK_MSS(is_vs1) \
if (P.VU.vlmul > 1) { \
require(!is_overlapped(insn.rd(), 1, insn.rs2(), P.VU.vlmul)); \
diff --git a/riscv/insns/vcompress_vm.h b/riscv/insns/vcompress_vm.h
index 91d6e90..77e91bf 100644
--- a/riscv/insns/vcompress_vm.h
+++ b/riscv/insns/vcompress_vm.h
@@ -1,14 +1,13 @@
// vcompress vd, vs2, vs1
-require(P.VU.vsew >= e8 && P.VU.vsew <= e64);
-require_vector;
require(P.VU.vstart == 0);
-reg_t sew = P.VU.vsew;
-reg_t vl = P.VU.vl;
-reg_t rd_num = insn.rd();
-reg_t rs1_num = insn.rs1();
-reg_t rs2_num = insn.rs2();
+require((insn.rd() & (P.VU.vlmul - 1)) == 0);
+require((insn.rs2() & (P.VU.vlmul - 1)) == 0);
+require(insn.rd() != insn.rs2());
+require(!is_overlapped(insn.rd(), P.VU.vlmul, insn.rs1(), 1));
+
reg_t pos = 0;
-for (reg_t i = P.VU.vstart ; i < vl; ++i) {
+
+VI_GENERAL_LOOP_BASE
const int mlen = P.VU.vmlen;
const int midx = (mlen * i) / 64;
const int mpos = (mlen * i) % 64;
@@ -32,10 +31,4 @@ for (reg_t i = P.VU.vstart ; i < vl; ++i) {
++pos;
}
-}
-
-if (vl > 0 && P.VU.TZ) {
- uint8_t *tail = &P.VU.elt<uint8_t>(rd_num, pos * ((sew >> 3) * 1));
- memset(tail, 0, (P.VU.vlmax - pos) * ((sew >> 3) * 1));
-}
-
+VI_LOOP_END;
diff --git a/riscv/insns/vfcvt_f_x_v.h b/riscv/insns/vfcvt_f_x_v.h
index 311f875..f6604fb 100644
--- a/riscv/insns/vfcvt_f_x_v.h
+++ b/riscv/insns/vfcvt_f_x_v.h
@@ -1,5 +1,5 @@
// vfcvt.f.x.v vd, vd2, vm
-VI_VFP_VV_LOOP
+VI_VFP_VF_LOOP
({
auto vs2_i = P.VU.elt<int32_t>(rs2_num, i);
vd = i32_to_f32(vs2_i);
diff --git a/riscv/insns/vfcvt_f_xu_v.h b/riscv/insns/vfcvt_f_xu_v.h
index ceabea3..2c845ac 100644
--- a/riscv/insns/vfcvt_f_xu_v.h
+++ b/riscv/insns/vfcvt_f_xu_v.h
@@ -1,5 +1,5 @@
// vfcvt.f.xu.v vd, vd2, vm
-VI_VFP_VV_LOOP
+VI_VFP_VF_LOOP
({
auto vs2_u = P.VU.elt<uint32_t>(rs2_num, i);
vd = ui32_to_f32(vs2_u);
diff --git a/riscv/insns/vfcvt_x_f_v.h b/riscv/insns/vfcvt_x_f_v.h
index ee53c6d..a9eedc4 100644
--- a/riscv/insns/vfcvt_x_f_v.h
+++ b/riscv/insns/vfcvt_x_f_v.h
@@ -1,5 +1,5 @@
// vfcvt.x.f.v vd, vd2, vm
-VI_VFP_VV_LOOP
+VI_VFP_VF_LOOP
({
P.VU.elt<int32_t>(rd_num, i) = f32_to_i32(vs2, STATE.frm, true);
})
diff --git a/riscv/insns/vfmerge_vfm.h b/riscv/insns/vfmerge_vfm.h
index e8601fe..ea78165 100644
--- a/riscv/insns/vfmerge_vfm.h
+++ b/riscv/insns/vfmerge_vfm.h
@@ -1,13 +1,7 @@
// vfmerge_vf vd, vs2, vs1, vm
-require_extension('F');
-require_fp;
-require(P.VU.vsew == 32);
-require_vector;
-reg_t vl = P.VU.vl;
+VI_CHECK_SSS(false);
+VI_VFP_COMMON;
reg_t sew = P.VU.vsew;
-reg_t rd_num = insn.rd();
-reg_t rs1_num = insn.rs1();
-reg_t rs2_num = insn.rs2();
for (reg_t i=P.VU.vstart; i<vl; ++i) {
auto &vd = P.VU.elt<float32_t>(rd_num, i);
auto rs1 = f32(READ_FREG(rs1_num));
@@ -21,4 +15,3 @@ for (reg_t i=P.VU.vstart; i<vl; ++i) {
}
P.VU.vstart = 0;
-set_fp_exceptions;
diff --git a/riscv/insns/vfmv_f_s.h b/riscv/insns/vfmv_f_s.h
index c6dbaff..066db80 100644
--- a/riscv/insns/vfmv_f_s.h
+++ b/riscv/insns/vfmv_f_s.h
@@ -1,6 +1,5 @@
// vfmv_f_s: rd = vs2[0] (rs1=0)
require_vector;
-require(insn.v_vm() == 1);
require_fp;
require_extension('F');
require(P.VU.vsew == e8 || P.VU.vsew == e16 || P.VU.vsew == e32 || P.VU.vsew == e64);
diff --git a/riscv/insns/vfmv_v_f.h b/riscv/insns/vfmv_v_f.h
index 150298b..f323263 100644
--- a/riscv/insns/vfmv_v_f.h
+++ b/riscv/insns/vfmv_v_f.h
@@ -1,13 +1,7 @@
-// vfmerge_vf vd, vs2, vs1, vm
-require_extension('F');
-require_fp;
-require(P.VU.vsew == 32);
-require_vector;
-reg_t vl = P.VU.vl;
+// vfmv_vf vd, vs1
+require((insn.rd() & (P.VU.vlmul - 1)) == 0);
+VI_VFP_COMMON
reg_t sew = P.VU.vsew;
-reg_t rd_num = insn.rd();
-reg_t rs1_num = insn.rs1();
-reg_t rs2_num = insn.rs2();
for (reg_t i=P.VU.vstart; i<vl; ++i) {
auto &vd = P.VU.elt<float32_t>(rd_num, i);
auto rs1 = f32(READ_FREG(rs1_num));
@@ -16,4 +10,3 @@ for (reg_t i=P.VU.vstart; i<vl; ++i) {
}
P.VU.vstart = 0;
-set_fp_exceptions;
diff --git a/riscv/insns/vid_v.h b/riscv/insns/vid_v.h
index 2291495..25422d6 100644
--- a/riscv/insns/vid_v.h
+++ b/riscv/insns/vid_v.h
@@ -6,6 +6,9 @@ reg_t sew = P.VU.vsew;
reg_t rd_num = insn.rd();
reg_t rs1_num = insn.rs1();
reg_t rs2_num = insn.rs2();
+require((rd_num & (P.VU.vlmul - 1)) == 0);
+if (insn.v_vm() == 0 && P.VU.vlmul >= 2) \
+ require(insn.rd() != 0);
for (reg_t i = P.VU.vstart ; i < P.VU.vl; ++i) {
VI_LOOP_ELEMENT_SKIP();
diff --git a/riscv/insns/viota_m.h b/riscv/insns/viota_m.h
index 55d8df1..04bfcd8 100644
--- a/riscv/insns/viota_m.h
+++ b/riscv/insns/viota_m.h
@@ -7,6 +7,10 @@ reg_t rd_num = insn.rd();
reg_t rs1_num = insn.rs1();
reg_t rs2_num = insn.rs2();
require(P.VU.vstart == 0);
+require(!is_overlapped(rd_num, P.VU.vlmul, rs2_num, 1));
+if (insn.v_vm() == 0)
+ require(!is_overlapped(rd_num, P.VU.vlmul, 0, 1));
+require((rd_num & (P.VU.vlmul - 1)) == 0);
int cnt = 0;
for (reg_t i = 0; i < vl; ++i) {
diff --git a/riscv/insns/vmv_v_v.h b/riscv/insns/vmv_v_v.h
index 734010b..a4f9a5c 100644
--- a/riscv/insns/vmv_v_v.h
+++ b/riscv/insns/vmv_v_v.h
@@ -1,4 +1,5 @@
// vvmv.v.v vd, vs1
+require((insn.rs1() & (P.VU.vlmul - 1)) == 0);
VI_VVXI_MERGE_LOOP
({
vd = vs1;
diff --git a/riscv/insns/vrgather_vi.h b/riscv/insns/vrgather_vi.h
index eff67b8..cab4a78 100644
--- a/riscv/insns/vrgather_vi.h
+++ b/riscv/insns/vrgather_vi.h
@@ -1,11 +1,14 @@
// vrgather.vi vd, vs2, zimm5 vm # vd[i] = (zimm5 >= VLMAX) ? 0 : vs2[zimm5];
-require(P.VU.vsew >= e8 && P.VU.vsew <= e64);
-require_vector;
-reg_t vl = P.VU.vl;
-reg_t sew = P.VU.vsew;
-reg_t rd_num = insn.rd();
-reg_t rs2_num = insn.rs2();
+require((insn.rd() & (P.VU.vlmul - 1)) == 0);
+require((insn.rs2() & (P.VU.vlmul - 1)) == 0);
+require(insn.rd() != insn.rs2());
+if (insn.v_vm() == 0)
+ require(insn.rd() != 0);
+
reg_t zimm5 = insn.v_zimm5();
+
+VI_LOOP_BASE
+
for (reg_t i = P.VU.vstart; i < vl; ++i) {
VI_LOOP_ELEMENT_SKIP();
@@ -25,5 +28,4 @@ for (reg_t i = P.VU.vstart; i < vl; ++i) {
}
}
-VI_TAIL_ZERO(1);
-P.VU.vstart = 0;
+VI_LOOP_END;
diff --git a/riscv/insns/vrgather_vv.h b/riscv/insns/vrgather_vv.h
index ce0c2a6..8266c95 100644
--- a/riscv/insns/vrgather_vv.h
+++ b/riscv/insns/vrgather_vv.h
@@ -1,15 +1,12 @@
// vrgather.vv vd, vs2, vs1, vm # vd[i] = (vs1[i] >= VLMAX) ? 0 : vs2[vs1[i]];
-require(P.VU.vsew >= e8 && P.VU.vsew <= e64);
-require_vector;
-reg_t vl = P.VU.vl;
-reg_t sew = P.VU.vsew;
-reg_t rd_num = insn.rd();
-reg_t rs1_num = insn.rs1();
-reg_t rs2_num = insn.rs2();
-for (reg_t i = P.VU.vstart; i < vl; ++i) {
- VI_LOOP_ELEMENT_SKIP();
- VI_CHECK_VREG_OVERLAP(rd_num, rs1_num);
- VI_CHECK_VREG_OVERLAP(rd_num, rs2_num);
+require((insn.rd() & (P.VU.vlmul - 1)) == 0);
+require((insn.rs2() & (P.VU.vlmul - 1)) == 0);
+require((insn.rs1() & (P.VU.vlmul - 1)) == 0);
+require(insn.rd() != insn.rs2() && insn.rd() != insn.rs1());
+if (insn.v_vm() == 0)
+ require(insn.rd() != 0);
+
+VI_LOOP_BASE
switch (sew) {
case e8: {
auto vs1 = P.VU.elt<uint8_t>(rs1_num, i);
@@ -33,7 +30,4 @@ for (reg_t i = P.VU.vstart; i < vl; ++i) {
break;
}
}
-}
-
-VI_TAIL_ZERO(1);
-P.VU.vstart = 0;
+VI_LOOP_END;
diff --git a/riscv/insns/vrgather_vx.h b/riscv/insns/vrgather_vx.h
index e9ff3b1..15e16b7 100644
--- a/riscv/insns/vrgather_vx.h
+++ b/riscv/insns/vrgather_vx.h
@@ -1,15 +1,13 @@
// vrgather.vx vd, vs2, rs1, vm # vd[i] = (rs1 >= VLMAX) ? 0 : vs2[rs1];
-require(P.VU.vsew >= e8 && P.VU.vsew <= e64);
-require_vector;
-reg_t vl = P.VU.vl;
-reg_t sew = P.VU.vsew;
-reg_t rd_num = insn.rd();
-reg_t rs1_num = insn.rs1();
-reg_t rs2_num = insn.rs2();
+require((insn.rd() & (P.VU.vlmul - 1)) == 0);
+require((insn.rs2() & (P.VU.vlmul - 1)) == 0);
+require(insn.rd() != insn.rs2());
+if (insn.v_vm() == 0)
+ require(insn.rd() != 0);
+
reg_t rs1 = RS1;
-for (reg_t i = P.VU.vstart; i < vl; ++i) {
- VI_LOOP_ELEMENT_SKIP();
+VI_LOOP_BASE
switch (sew) {
case e8:
P.VU.elt<uint8_t>(rd_num, i) = rs1 >= P.VU.vlmax ? 0 : P.VU.elt<uint8_t>(rs2_num, rs1);
@@ -24,7 +22,4 @@ for (reg_t i = P.VU.vstart; i < vl; ++i) {
P.VU.elt<uint64_t>(rd_num, i) = rs1 >= P.VU.vlmax ? 0 : P.VU.elt<uint64_t>(rs2_num, rs1);
break;
}
-}
-
-VI_TAIL_ZERO(1);
-P.VU.vstart = 0;
+VI_LOOP_END;