Browse Source

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 <chihmin.chao@sifive.com>
pull/378/head
Chih-Min Chao 7 years ago
parent
commit
ca648e6e24
  1. 4
      riscv/decode.h
  2. 6
      riscv/insns/vfncvt_f_f_w.h
  3. 6
      riscv/insns/vfncvt_f_x_w.h
  4. 6
      riscv/insns/vfncvt_f_xu_w.h
  5. 6
      riscv/insns/vfncvt_rod_f_f_w.h
  6. 6
      riscv/insns/vfncvt_x_f_w.h
  7. 6
      riscv/insns/vfncvt_xu_f_w.h
  8. 5
      riscv/insns/vfwcvt_f_f_v.h
  9. 5
      riscv/insns/vfwcvt_f_x_v.h
  10. 5
      riscv/insns/vfwcvt_f_xu_v.h
  11. 5
      riscv/insns/vfwcvt_x_f_v.h
  12. 5
      riscv/insns/vfwcvt_xu_f_v.h
  13. 20
      spike_main/disasm.cc

4
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)); \

6
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<float64_t>(rs2_num, i);
P.VU.elt<float32_t>(rd_num, i) = f64_to_f32(vs2);
set_fp_exceptions;
VI_VFP_LOOP_END

6
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<int64_t>(rs2_num, i);
P.VU.elt<float32_t>(rd_num, i) = i64_to_f32(vs2);
set_fp_exceptions;
VI_VFP_LOOP_END

6
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<uint64_t>(rs2_num, i);
P.VU.elt<float32_t>(rd_num, i) = ui64_to_f32(vs2);
set_fp_exceptions;
VI_VFP_LOOP_END

6
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<float64_t>(rs2_num, i);
P.VU.elt<float32_t>(rd_num, i) = f64_to_f32(vs2);
set_fp_exceptions;
VI_VFP_LOOP_END

6
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<float64_t>(rs2_num, i);
P.VU.elt<int32_t>(rd_num, i) = f64_to_i32(vs2, STATE.frm, true);
set_fp_exceptions;
VI_VFP_LOOP_END

6
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<float64_t>(rs2_num, i);
P.VU.elt<uint32_t>(rd_num, i) = f64_to_ui32(vs2, STATE.frm, true);
set_fp_exceptions;
VI_VFP_LOOP_END

5
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<float32_t>(rs2_num, i);
P.VU.elt<float64_t>(rd_num, i) = f32_to_f64(vs2);
set_fp_exceptions;

5
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<int32_t>(rs2_num, i);
P.VU.elt<float64_t>(rd_num, i) = i32_to_f64(vs2);
set_fp_exceptions;

5
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<uint32_t>(rs2_num, i);
P.VU.elt<float64_t>(rd_num, i) = ui32_to_f64(vs2);
set_fp_exceptions;

5
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<float32_t>(rs2_num, i);
P.VU.elt<int64_t>(rd_num, i) = f32_to_i64(vs2, STATE.frm, true);
set_fp_exceptions;

5
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<float32_t>(rs2_num, i);
P.VU.elt<uint64_t>(rd_num, i) = f32_to_ui64(vs2, STATE.frm, true);
set_fp_exceptions;

20
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

Loading…
Cancel
Save