aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--riscv/decode.h4
-rw-r--r--riscv/insns/vfncvt_f_f_w.h6
-rw-r--r--riscv/insns/vfncvt_f_x_w.h6
-rw-r--r--riscv/insns/vfncvt_f_xu_w.h6
-rw-r--r--riscv/insns/vfncvt_rod_f_f_w.h6
-rw-r--r--riscv/insns/vfncvt_x_f_w.h6
-rw-r--r--riscv/insns/vfncvt_xu_f_w.h6
-rw-r--r--riscv/insns/vfwcvt_f_f_v.h5
-rw-r--r--riscv/insns/vfwcvt_f_x_v.h5
-rw-r--r--riscv/insns/vfwcvt_f_xu_v.h5
-rw-r--r--riscv/insns/vfwcvt_x_f_v.h5
-rw-r--r--riscv/insns/vfwcvt_xu_f_v.h5
-rw-r--r--spike_main/disasm.cc20
13 files changed, 60 insertions, 25 deletions
diff --git a/riscv/decode.h b/riscv/decode.h
index 256aca3..0076145 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 42c18c7..55a8eac 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<float64_t>(rs2_num, i);
P.VU.elt<float32_t>(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 80ebe00..daf2274 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<int64_t>(rs2_num, i);
P.VU.elt<float32_t>(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 013f57c..7f57ec5 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<uint64_t>(rs2_num, i);
P.VU.elt<float32_t>(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 77a3873..130c5b5 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<float64_t>(rs2_num, i);
P.VU.elt<float32_t>(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 8985f1b..cda2fe2 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<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
diff --git a/riscv/insns/vfncvt_xu_f_w.h b/riscv/insns/vfncvt_xu_f_w.h
index 2db8d82..a009105 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<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
diff --git a/riscv/insns/vfwcvt_f_f_v.h b/riscv/insns/vfwcvt_f_f_v.h
index 4d6b4fc..4bda2bc 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<float32_t>(rs2_num, i);
P.VU.elt<float64_t>(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 ab5d825..346db32 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<int32_t>(rs2_num, i);
P.VU.elt<float64_t>(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 8af8d7c..c963abb 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<uint32_t>(rs2_num, i);
P.VU.elt<float64_t>(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 06e81d4..9088a79 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<float32_t>(rs2_num, i);
P.VU.elt<int64_t>(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 cc82481..266cbca 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<float32_t>(rs2_num, i);
P.VU.elt<uint64_t>(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 373c6bb..5ecad58 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