diff options
author | Chih-Min Chao <chihmin.chao@sifive.com> | 2019-10-23 01:36:48 -0700 |
---|---|---|
committer | Chih-Min Chao <chihmin.chao@sifive.com> | 2019-11-11 19:02:35 -0800 |
commit | 4808f84a1833de2bbd87a92355f75991c4697312 (patch) | |
tree | 464a74599559173af989a150973a76539d1ba663 | |
parent | e289b996c6ef60693b394b57bb53034c38eff4e4 (diff) | |
download | riscv-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.h | 5 | ||||
-rw-r--r-- | riscv/insns/vcompress_vm.h | 23 | ||||
-rw-r--r-- | riscv/insns/vfcvt_f_x_v.h | 2 | ||||
-rw-r--r-- | riscv/insns/vfcvt_f_xu_v.h | 2 | ||||
-rw-r--r-- | riscv/insns/vfcvt_x_f_v.h | 2 | ||||
-rw-r--r-- | riscv/insns/vfmerge_vfm.h | 11 | ||||
-rw-r--r-- | riscv/insns/vfmv_f_s.h | 1 | ||||
-rw-r--r-- | riscv/insns/vfmv_v_f.h | 13 | ||||
-rw-r--r-- | riscv/insns/vid_v.h | 3 | ||||
-rw-r--r-- | riscv/insns/viota_m.h | 4 | ||||
-rw-r--r-- | riscv/insns/vmv_v_v.h | 1 | ||||
-rw-r--r-- | riscv/insns/vrgather_vi.h | 18 | ||||
-rw-r--r-- | riscv/insns/vrgather_vv.h | 24 | ||||
-rw-r--r-- | riscv/insns/vrgather_vx.h | 21 |
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; |