From ca648e6e24a8968f4e33ca1859d37a760004e953 Mon Sep 17 00:00:00 2001 From: Chih-Min Chao Date: Wed, 11 Dec 2019 00:26:01 -0800 Subject: [PATCH] rvv: fix vfwcvt/vfncvt for f32 -> f64 and f64 -> f32 1. fix disam 2. refine checking rule and move them out of loop 3. add missing exception keeping for each element Signed-off-by: Chih-Min Chao --- riscv/decode.h | 4 +--- riscv/insns/vfncvt_f_f_w.h | 6 +++++- riscv/insns/vfncvt_f_x_w.h | 6 +++++- riscv/insns/vfncvt_f_xu_w.h | 6 +++++- riscv/insns/vfncvt_rod_f_f_w.h | 6 +++++- riscv/insns/vfncvt_x_f_w.h | 6 +++++- riscv/insns/vfncvt_xu_f_w.h | 6 +++++- riscv/insns/vfwcvt_f_f_v.h | 5 ++++- riscv/insns/vfwcvt_f_x_v.h | 5 ++++- riscv/insns/vfwcvt_f_xu_v.h | 5 ++++- riscv/insns/vfwcvt_x_f_v.h | 5 ++++- riscv/insns/vfwcvt_xu_f_v.h | 5 ++++- spike_main/disasm.cc | 20 +++++++++----------- 13 files changed, 60 insertions(+), 25 deletions(-) diff --git a/riscv/decode.h b/riscv/decode.h index 256aca38..00761455 100644 --- a/riscv/decode.h +++ b/riscv/decode.h @@ -441,12 +441,10 @@ static inline bool is_overlapped(const int astart, const int asize, require(insn.rd() != 0); \ } -#define VI_CHECK_SD \ - require(!is_overlapped(insn.rd(), P.VU.vlmul, insn.rs2(), P.VU.vlmul * 2)); - #define VI_CHECK_DSS(is_vs1) \ VI_WIDE_CHECK_COMMON; \ require(!is_overlapped(insn.rd(), P.VU.vlmul * 2, insn.rs2(), P.VU.vlmul)); \ + require((insn.rd() & (P.VU.vlmul * 2 - 1)) == 0); \ require((insn.rs2() & (P.VU.vlmul - 1)) == 0); \ if (is_vs1) {\ require(!is_overlapped(insn.rd(), P.VU.vlmul * 2, insn.rs1(), P.VU.vlmul)); \ diff --git a/riscv/insns/vfncvt_f_f_w.h b/riscv/insns/vfncvt_f_f_w.h index 42c18c7a..55a8eac2 100644 --- a/riscv/insns/vfncvt_f_f_w.h +++ b/riscv/insns/vfncvt_f_f_w.h @@ -1,6 +1,10 @@ // vfncvt.f.f.v vd, vs2, vm -VI_CHECK_SD; +VI_CHECK_SDS(false); +if (P.VU.vsew == e32) + require(p->supports_extension('D')); + VI_VFP_LOOP_BASE auto vs2 = P.VU.elt(rs2_num, i); P.VU.elt(rd_num, i) = f64_to_f32(vs2); + set_fp_exceptions; VI_VFP_LOOP_END diff --git a/riscv/insns/vfncvt_f_x_w.h b/riscv/insns/vfncvt_f_x_w.h index 80ebe002..daf2274d 100644 --- a/riscv/insns/vfncvt_f_x_w.h +++ b/riscv/insns/vfncvt_f_x_w.h @@ -1,6 +1,10 @@ // vfncvt.f.x.v vd, vs2, vm -VI_CHECK_SD; +VI_CHECK_SDS(false); +if (P.VU.vsew == e32) + require(p->supports_extension('D')); + VI_VFP_LOOP_BASE auto vs2 = P.VU.elt(rs2_num, i); P.VU.elt(rd_num, i) = i64_to_f32(vs2); + set_fp_exceptions; VI_VFP_LOOP_END diff --git a/riscv/insns/vfncvt_f_xu_w.h b/riscv/insns/vfncvt_f_xu_w.h index 013f57c4..7f57ec5e 100644 --- a/riscv/insns/vfncvt_f_xu_w.h +++ b/riscv/insns/vfncvt_f_xu_w.h @@ -1,6 +1,10 @@ // vfncvt.f.xu.v vd, vs2, vm -VI_CHECK_SD; +VI_CHECK_SDS(false); +if (P.VU.vsew == e32) + require(p->supports_extension('D')); + VI_VFP_LOOP_BASE auto vs2 = P.VU.elt(rs2_num, i); P.VU.elt(rd_num, i) = ui64_to_f32(vs2); + set_fp_exceptions; VI_VFP_LOOP_END diff --git a/riscv/insns/vfncvt_rod_f_f_w.h b/riscv/insns/vfncvt_rod_f_f_w.h index 77a38738..130c5b50 100644 --- a/riscv/insns/vfncvt_rod_f_f_w.h +++ b/riscv/insns/vfncvt_rod_f_f_w.h @@ -1,7 +1,11 @@ // vfncvt.f.f.v vd, vs2, vm -VI_CHECK_SD; +VI_CHECK_SDS(false); +if (P.VU.vsew == e32) + require(p->supports_extension('D')); + VI_VFP_LOOP_BASE softfloat_roundingMode = softfloat_round_odd; auto vs2 = P.VU.elt(rs2_num, i); P.VU.elt(rd_num, i) = f64_to_f32(vs2); + set_fp_exceptions; VI_VFP_LOOP_END diff --git a/riscv/insns/vfncvt_x_f_w.h b/riscv/insns/vfncvt_x_f_w.h index 8985f1b5..cda2fe2c 100644 --- a/riscv/insns/vfncvt_x_f_w.h +++ b/riscv/insns/vfncvt_x_f_w.h @@ -1,6 +1,10 @@ // vfncvt.x.f.v vd, vs2, vm +VI_CHECK_SDS(false); +if (P.VU.vsew == e32) + require(p->supports_extension('D')); + VI_VFP_LOOP_BASE - VI_CHECK_SD; auto vs2 = P.VU.elt(rs2_num, i); P.VU.elt(rd_num, i) = f64_to_i32(vs2, STATE.frm, true); + set_fp_exceptions; VI_VFP_LOOP_END diff --git a/riscv/insns/vfncvt_xu_f_w.h b/riscv/insns/vfncvt_xu_f_w.h index 2db8d828..a0091050 100644 --- a/riscv/insns/vfncvt_xu_f_w.h +++ b/riscv/insns/vfncvt_xu_f_w.h @@ -1,6 +1,10 @@ // vfncvt.xu.f.v vd, vs2, vm +VI_CHECK_SDS(false); +if (P.VU.vsew == e32) + require(p->supports_extension('D')); + VI_VFP_LOOP_BASE - VI_CHECK_SD; auto vs2 = P.VU.elt(rs2_num, i); P.VU.elt(rd_num, i) = f64_to_ui32(vs2, STATE.frm, true); + set_fp_exceptions; VI_VFP_LOOP_END diff --git a/riscv/insns/vfwcvt_f_f_v.h b/riscv/insns/vfwcvt_f_f_v.h index 4d6b4fc3..4bda2bcb 100644 --- a/riscv/insns/vfwcvt_f_f_v.h +++ b/riscv/insns/vfwcvt_f_f_v.h @@ -1,6 +1,9 @@ // vfwcvt.f.f.v vd, vs2, vm +VI_CHECK_DSS(false); +if (P.VU.vsew == e32) + require(p->supports_extension('D')); + VI_VFP_LOOP_BASE - VI_CHECK_DSS(false); auto vs2 = P.VU.elt(rs2_num, i); P.VU.elt(rd_num, i) = f32_to_f64(vs2); set_fp_exceptions; diff --git a/riscv/insns/vfwcvt_f_x_v.h b/riscv/insns/vfwcvt_f_x_v.h index ab5d8256..346db322 100644 --- a/riscv/insns/vfwcvt_f_x_v.h +++ b/riscv/insns/vfwcvt_f_x_v.h @@ -1,6 +1,9 @@ // vfwcvt.f.x.v vd, vs2, vm +VI_CHECK_DSS(false); +if (P.VU.vsew == e32) + require(p->supports_extension('D')); + VI_VFP_LOOP_BASE - VI_CHECK_DSS(false); auto vs2 = P.VU.elt(rs2_num, i); P.VU.elt(rd_num, i) = i32_to_f64(vs2); set_fp_exceptions; diff --git a/riscv/insns/vfwcvt_f_xu_v.h b/riscv/insns/vfwcvt_f_xu_v.h index 8af8d7ce..c963abb3 100644 --- a/riscv/insns/vfwcvt_f_xu_v.h +++ b/riscv/insns/vfwcvt_f_xu_v.h @@ -1,6 +1,9 @@ // vfwcvt.f.xu.v vd, vs2, vm +VI_CHECK_DSS(false); +if (P.VU.vsew == e32) + require(p->supports_extension('D')); + VI_VFP_LOOP_BASE - VI_CHECK_DSS(false); auto vs2 = P.VU.elt(rs2_num, i); P.VU.elt(rd_num, i) = ui32_to_f64(vs2); set_fp_exceptions; diff --git a/riscv/insns/vfwcvt_x_f_v.h b/riscv/insns/vfwcvt_x_f_v.h index 06e81d42..9088a795 100644 --- a/riscv/insns/vfwcvt_x_f_v.h +++ b/riscv/insns/vfwcvt_x_f_v.h @@ -1,6 +1,9 @@ // vfwcvt.x.f.v vd, vs2, vm +VI_CHECK_DSS(false); +if (P.VU.vsew == e32) + require(p->supports_extension('D')); + VI_VFP_LOOP_BASE - VI_CHECK_DSS(false); auto vs2 = P.VU.elt(rs2_num, i); P.VU.elt(rd_num, i) = f32_to_i64(vs2, STATE.frm, true); set_fp_exceptions; diff --git a/riscv/insns/vfwcvt_xu_f_v.h b/riscv/insns/vfwcvt_xu_f_v.h index cc824812..266cbcaf 100644 --- a/riscv/insns/vfwcvt_xu_f_v.h +++ b/riscv/insns/vfwcvt_xu_f_v.h @@ -1,6 +1,9 @@ // vfwcvt.xu.f.v vd, vs2, vm +VI_CHECK_DSS(false); +if (P.VU.vsew == e32) + require(p->supports_extension('D')); + VI_VFP_LOOP_BASE - VI_CHECK_DSS(false); auto vs2 = P.VU.elt(rs2_num, i); P.VU.elt(rd_num, i) = f32_to_ui64(vs2, STATE.frm, true); set_fp_exceptions; diff --git a/spike_main/disasm.cc b/spike_main/disasm.cc index 373c6bba..5ecad58d 100644 --- a/spike_main/disasm.cc +++ b/spike_main/disasm.cc @@ -1037,23 +1037,19 @@ disassembler_t::disassembler_t(int xlen) add_insn(new disasm_insn_t(#name ".vf", match_##name##_vf, mask_##name##_vf, \ {&vd, &vs2, &frs1, &opt, &vm})); \ - #define DISASM_VFUNARY0_INSN(name, extra, suf) \ + #define DISASM_VFUNARY0_INSN(name, suf) \ add_insn(new disasm_insn_t(#name "cvt.xu.f." #suf, \ match_##name##cvt_xu_f_##suf, mask_##name##cvt_xu_f_##suf, \ {&vd, &vs2, &opt, &vm})); \ add_insn(new disasm_insn_t(#name "cvt.x.f." #suf, \ - match_##name##cvt_xu_f_##suf, mask_##name##cvt_xu_f_##suf, \ + match_##name##cvt_x_f_##suf, mask_##name##cvt_x_f_##suf, \ {&vd, &vs2, &opt, &vm})); \ add_insn(new disasm_insn_t(#name "cvt.f.xu." #suf, \ - match_##name##cvt_xu_f_##suf, mask_##name##cvt_xu_f_##suf, \ + match_##name##cvt_f_xu_##suf, mask_##name##cvt_f_xu_##suf, \ {&vd, &vs2, &opt, &vm})); \ add_insn(new disasm_insn_t(#name "cvt.f.x." #suf, \ - match_##name##cvt_xu_f_##suf, mask_##name##cvt_xu_f_##suf, \ + match_##name##cvt_f_x_##suf, mask_##name##cvt_f_x_##suf, \ {&vd, &vs2, &opt, &vm})); \ - if (extra) \ - add_insn(new disasm_insn_t(#name "cvt.f.f." #suf, \ - match_##name##cvt_xu_f_##suf, mask_##name##cvt_xu_f_##suf, \ - {&vd, &vs2, &opt, &vm})); \ //OPFVV/OPFVF //0b01_0000 @@ -1086,11 +1082,13 @@ disassembler_t::disassembler_t(int xlen) DISASM_OPIV__F_INSN(vfrdiv); //vfunary0 - DISASM_VFUNARY0_INSN(vf, 0, v); + DISASM_VFUNARY0_INSN(vf, v); - DISASM_VFUNARY0_INSN(vfw, 1, v); + DISASM_VFUNARY0_INSN(vfw, v); + DISASM_INSN("vfwcvt.f.f.v", vfwcvt_f_f_v, 0, {&vd, &vs2, &opt, &vm}); - DISASM_VFUNARY0_INSN(vfn, 1, w); + DISASM_VFUNARY0_INSN(vfn, w); + DISASM_INSN("vfncvt.f.f.w", vfncvt_rod_f_f_w, 0, {&vd, &vs2, &opt, &vm}); DISASM_INSN("vfncvt.rod.f.f.w", vfncvt_rod_f_f_w, 0, {&vd, &vs2, &opt, &vm}); //vfunary1