aboutsummaryrefslogtreecommitdiff
path: root/riscv
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@s141.Millennium.Berkeley.EDU>2010-08-09 20:51:44 -0700
committerAndrew Waterman <waterman@s141.Millennium.Berkeley.EDU>2010-08-09 20:51:44 -0700
commit2d75bf71bb3990f5a718ddca3c99f9139c03c10b (patch)
tree029a524ddc8c98c00bf0ef2d25993649b3644ae6 /riscv
parentd9170d6002c684acdfca1ba124dba2235081b578 (diff)
downloadriscv-isa-sim-2d75bf71bb3990f5a718ddca3c99f9139c03c10b.zip
riscv-isa-sim-2d75bf71bb3990f5a718ddca3c99f9139c03c10b.tar.gz
riscv-isa-sim-2d75bf71bb3990f5a718ddca3c99f9139c03c10b.tar.bz2
[xcc,sim] implement FP using softfloat
The intersection of the Hauser FP and MIPS FP is implemented.
Diffstat (limited to 'riscv')
-rw-r--r--riscv/decode.h45
-rw-r--r--riscv/execute.h284
-rw-r--r--riscv/insns/add_d.h3
-rw-r--r--riscv/insns/add_s.h3
-rw-r--r--riscv/insns/c_eq_d.h3
-rw-r--r--riscv/insns/c_eq_fmt.h0
-rw-r--r--riscv/insns/c_eq_s.h3
-rw-r--r--riscv/insns/c_f_fmt.h0
-rw-r--r--riscv/insns/c_le_d.h3
-rw-r--r--riscv/insns/c_le_fmt.h0
-rw-r--r--riscv/insns/c_le_s.h3
-rw-r--r--riscv/insns/c_lt_d.h3
-rw-r--r--riscv/insns/c_lt_fmt.h0
-rw-r--r--riscv/insns/c_lt_s.h3
-rw-r--r--riscv/insns/c_nge_fmt.h0
-rw-r--r--riscv/insns/c_ngl_fmt.h0
-rw-r--r--riscv/insns/c_ngle_fmt.h0
-rw-r--r--riscv/insns/c_ngt_fmt.h0
-rw-r--r--riscv/insns/c_ole_fmt.h0
-rw-r--r--riscv/insns/c_olt_fmt.h0
-rw-r--r--riscv/insns/c_seq_fmt.h0
-rw-r--r--riscv/insns/c_sf_fmt.h0
-rw-r--r--riscv/insns/c_ueq_fmt.h0
-rw-r--r--riscv/insns/c_ule_fmt.h0
-rw-r--r--riscv/insns/c_ult_fmt.h0
-rw-r--r--riscv/insns/c_un_fmt.h0
-rw-r--r--riscv/insns/ceil_l_fmt.h0
-rw-r--r--riscv/insns/ceil_w_fmt.h0
-rw-r--r--riscv/insns/cvt_d_fmt.h0
-rw-r--r--riscv/insns/cvt_d_l.h3
-rw-r--r--riscv/insns/cvt_d_s.h3
-rw-r--r--riscv/insns/cvt_d_w.h3
-rw-r--r--riscv/insns/cvt_l_fmt.h0
-rw-r--r--riscv/insns/cvt_s_d.h3
-rw-r--r--riscv/insns/cvt_s_fmt.h0
-rw-r--r--riscv/insns/cvt_s_l.h3
-rw-r--r--riscv/insns/cvt_s_w.h3
-rw-r--r--riscv/insns/cvt_w_fmt.h0
-rw-r--r--riscv/insns/cvtu_d_l.h3
-rw-r--r--riscv/insns/cvtu_d_w.h3
-rw-r--r--riscv/insns/cvtu_s_l.h3
-rw-r--r--riscv/insns/cvtu_s_w.h3
-rw-r--r--riscv/insns/div_d.h3
-rw-r--r--riscv/insns/div_s.h3
-rw-r--r--riscv/insns/floor_l_fmt.h0
-rw-r--r--riscv/insns/floor_w_fmt.h0
-rw-r--r--riscv/insns/l_d.h2
-rw-r--r--riscv/insns/l_s.h2
-rw-r--r--riscv/insns/mff_d.h2
-rw-r--r--riscv/insns/mff_s.h2
-rw-r--r--riscv/insns/mtf_d.h2
-rw-r--r--riscv/insns/mtf_s.h2
-rw-r--r--riscv/insns/mul_d.h3
-rw-r--r--riscv/insns/mul_s.h3
-rw-r--r--riscv/insns/round_l_fmt.h0
-rw-r--r--riscv/insns/round_w_fmt.h0
-rw-r--r--riscv/insns/s_d.h2
-rw-r--r--riscv/insns/s_s.h2
-rw-r--r--riscv/insns/sgninj_d.h2
-rw-r--r--riscv/insns/sgninj_s.h2
-rw-r--r--riscv/insns/sgninjn_d.h2
-rw-r--r--riscv/insns/sgninjn_s.h2
-rw-r--r--riscv/insns/sgnmul_d.h2
-rw-r--r--riscv/insns/sgnmul_s.h2
-rw-r--r--riscv/insns/sqrt_d.h3
-rw-r--r--riscv/insns/sqrt_s.h3
-rw-r--r--riscv/insns/sub_d.h3
-rw-r--r--riscv/insns/sub_s.h3
-rw-r--r--riscv/insns/trunc_l_d.h3
-rw-r--r--riscv/insns/trunc_l_fmt.h0
-rw-r--r--riscv/insns/trunc_l_s.h3
-rw-r--r--riscv/insns/trunc_w_d.h3
-rw-r--r--riscv/insns/trunc_w_fmt.h0
-rw-r--r--riscv/insns/trunc_w_s.h3
-rw-r--r--riscv/insns/truncu_l_d.h3
-rw-r--r--riscv/insns/truncu_l_s.h3
-rw-r--r--riscv/insns/truncu_w_d.h3
-rw-r--r--riscv/insns/truncu_w_s.h3
-rw-r--r--riscv/processor.cc8
-rw-r--r--riscv/processor.h2
-rw-r--r--riscv/riscv.mk.in2
81 files changed, 222 insertions, 249 deletions
diff --git a/riscv/decode.h b/riscv/decode.h
index 7bdfb18..424ad7f 100644
--- a/riscv/decode.h
+++ b/riscv/decode.h
@@ -9,13 +9,7 @@ typedef unsigned int uint128_t __attribute__((mode(TI)));
#define support_64bit 1
typedef int64_t sreg_t;
typedef uint64_t reg_t;
-
-union freg_t
-{
- float sp;
- double dp;
- uint64_t bits;
-};
+typedef uint64_t freg_t;
const int OPCODE_BITS = 7;
const int JTYPE_OPCODE_BITS = 5;
@@ -42,7 +36,38 @@ const int BIGIMM_BITS = 20;
#define SR_UX 0x0000000000000020ULL
#define SR_KX 0x0000000000000040ULL
#define SR_IM 0x000000000000FF00ULL
-#define SR_ZERO 0xFFFFFFFFFFFF0082ULL
+#define SR_ZERO ~(SR_ET | SR_PS | SR_S | SR_EF | SR_UX | SR_KX | SR_IM)
+
+#define FP_RD_NE 0
+#define FP_RD_0 1
+#define FP_RD_UP 2
+#define FP_RD_DN 3
+#define FSR_RD_SHIFT 10
+#define FSR_RD (0x3 << FSR_RD_SHIFT)
+
+#define FPEXC_NV 0x10
+#define FPEXC_OF 0x08
+#define FPEXC_UF 0x04
+#define FPEXC_DZ 0x02
+#define FPEXC_NX 0x01
+
+#define FSR_AEXC_SHIFT 5
+#define FSR_NVA (FPEXC_NV << FSR_AEXC_SHIFT)
+#define FSR_OFA (FPEXC_OF << FSR_AEXC_SHIFT)
+#define FSR_UFA (FPEXC_UF << FSR_AEXC_SHIFT)
+#define FSR_DZA (FPEXC_DZ << FSR_AEXC_SHIFT)
+#define FSR_NXA (FPEXC_NX << FSR_AEXC_SHIFT)
+#define FSR_AEXC (FSR_NVA | FSR_OFA | FSR_UFA | FSR_DZA | FSR_NXA)
+
+#define FSR_CEXC_SHIFT 0
+#define FSR_NVC (FPEXC_NV << FSR_AEXC_SHIFT)
+#define FSR_OFC (FPEXC_OF << FSR_AEXC_SHIFT)
+#define FSR_UFC (FPEXC_UF << FSR_AEXC_SHIFT)
+#define FSR_DZC (FPEXC_DZ << FSR_AEXC_SHIFT)
+#define FSR_NXC (FPEXC_NX << FSR_AEXC_SHIFT)
+#define FSR_CEXC (FSR_NVC | FSR_OFC | FSR_UFC | FSR_DZC | FSR_NXC)
+
+#define FSR_ZERO ~(FSR_RD | FSR_AEXC | FSR_CEXC)
// note: bit fields are in little-endian order
struct itype_t
@@ -118,6 +143,10 @@ union insn_t
#define require64 if(gprlen != 64) throw trap_illegal_instruction
#define require_fp if(!(sr & SR_EF)) throw trap_fp_disabled
#define cmp_trunc(reg) (reg_t(reg) << (64-gprlen))
+#define set_fp_exceptions ({ set_fsr((fsr & ~FSR_CEXC) | \
+ (float_exception_flags << FSR_AEXC_SHIFT) | \
+ (float_exception_flags << FSR_CEXC_SHIFT)); \
+ float_exception_flags = 0; })
static inline sreg_t sext32(int32_t arg)
{
diff --git a/riscv/execute.h b/riscv/execute.h
index ad655ac..f5b83af 100644
--- a/riscv/execute.h
+++ b/riscv/execute.h
@@ -149,262 +149,130 @@ switch((insn.bits >> 0x19) & 0x7f)
}
#include "insns/unimp.h"
}
- default:
- {
- #include "insns/unimp.h"
- }
- }
- break;
- }
- case 0x69:
- {
- switch((insn.bits >> 0xc) & 0x7)
- {
- case 0x0:
+ case 0x1:
{
- if((insn.bits & 0xfe0ffc00) == 0xd2000000)
+ if((insn.bits & 0xfe0fffe0) == 0xd00010c0)
{
- #include "insns/round_l_fmt.h"
+ #include "insns/cvt_s_w.h"
break;
}
- #include "insns/unimp.h"
- }
- case 0x1:
- {
- if((insn.bits & 0xfe0ffc00) == 0xd2001000)
+ if((insn.bits & 0xfe0fffe0) == 0xd0001ca0)
{
- #include "insns/trunc_l_fmt.h"
+ #include "insns/cvtu_d_l.h"
break;
}
- #include "insns/unimp.h"
- }
- case 0x2:
- {
- if((insn.bits & 0xfe0ffc00) == 0xd2002000)
+ if((insn.bits & 0xfe0fffe0) == 0xd0001c40)
{
- #include "insns/ceil_l_fmt.h"
+ #include "insns/trunc_w_d.h"
break;
}
- #include "insns/unimp.h"
- }
- case 0x3:
- {
- if((insn.bits & 0xfe0ffc00) == 0xd2003000)
+ if((insn.bits & 0xfe0fffe0) == 0xd0001040)
{
- #include "insns/floor_l_fmt.h"
+ #include "insns/trunc_w_s.h"
break;
}
- #include "insns/unimp.h"
- }
- case 0x4:
- {
- if((insn.bits & 0xfe0ffc00) == 0xd2004000)
+ if((insn.bits & 0xfe0fffe0) == 0xd0001ce0)
{
- #include "insns/round_w_fmt.h"
+ #include "insns/cvtu_d_w.h"
break;
}
- #include "insns/unimp.h"
- }
- case 0x5:
- {
- if((insn.bits & 0xfe0ffc00) == 0xd2005000)
+ if((insn.bits & 0xfe0fffe0) == 0xd0001e00)
{
- #include "insns/trunc_w_fmt.h"
+ #include "insns/cvt_d_s.h"
break;
}
- #include "insns/unimp.h"
- }
- case 0x6:
- {
- if((insn.bits & 0xfe0ffc00) == 0xd2006000)
+ if((insn.bits & 0xfe0fffe0) == 0xd0001000)
{
- #include "insns/ceil_w_fmt.h"
+ #include "insns/trunc_l_s.h"
break;
}
- #include "insns/unimp.h"
- }
- case 0x7:
- {
- if((insn.bits & 0xfe0ffc00) == 0xd2007000)
+ if((insn.bits & 0xfe0fffe0) == 0xd0001c00)
{
- #include "insns/floor_w_fmt.h"
+ #include "insns/trunc_l_d.h"
break;
}
- #include "insns/unimp.h"
- }
- default:
- {
- #include "insns/unimp.h"
- }
- }
- break;
- }
- case 0x6a:
- {
- switch((insn.bits >> 0xc) & 0x7)
- {
- case 0x0:
- {
- if((insn.bits & 0xfe007fff) == 0xd4000000)
+ if((insn.bits & 0xfe0fffe0) == 0xd00010e0)
{
- #include "insns/mff_s.h"
+ #include "insns/cvtu_s_w.h"
break;
}
- #include "insns/unimp.h"
- }
- case 0x1:
- {
- if((insn.bits & 0xfe007fff) == 0xd4001000)
+ if((insn.bits & 0xfe0fffe0) == 0xd0001020)
{
- #include "insns/mff_d.h"
+ #include "insns/truncu_l_s.h"
break;
}
- #include "insns/unimp.h"
- }
- case 0x4:
- {
- if((insn.bits & 0xfe007fff) == 0xd4004000)
+ if((insn.bits & 0xfe0fffe0) == 0xd0001c20)
{
- #include "insns/mtf_s.h"
+ #include "insns/truncu_l_d.h"
break;
}
- #include "insns/unimp.h"
- }
- case 0x5:
- {
- if((insn.bits & 0xfe007fff) == 0xd4005000)
+ if((insn.bits & 0xfe0fffe0) == 0xd00010a0)
{
- #include "insns/mtf_d.h"
+ #include "insns/cvtu_s_l.h"
break;
}
- #include "insns/unimp.h"
- }
- default:
- {
- #include "insns/unimp.h"
- }
- }
- break;
- }
- case 0x6b:
- {
- switch((insn.bits >> 0xc) & 0x7)
- {
- case 0x0:
- {
- if((insn.bits & 0xfe0ffc00) == 0xd6000000)
+ if((insn.bits & 0xfe0fffe0) == 0xd0001080)
{
- #include "insns/cvt_s_fmt.h"
+ #include "insns/cvt_s_l.h"
break;
}
- #include "insns/unimp.h"
- }
- case 0x1:
- {
- if((insn.bits & 0xfe0ffc00) == 0xd6001000)
+ if((insn.bits & 0xfe0fffe0) == 0xd0001260)
{
- #include "insns/cvt_d_fmt.h"
+ #include "insns/cvt_s_d.h"
break;
}
- #include "insns/unimp.h"
- }
- case 0x4:
- {
- if((insn.bits & 0xfe0ffc00) == 0xd6004000)
+ if((insn.bits & 0xfe0fffe0) == 0xd0001060)
{
- #include "insns/cvt_w_fmt.h"
+ #include "insns/truncu_w_s.h"
break;
}
- #include "insns/unimp.h"
- }
- case 0x5:
- {
- if((insn.bits & 0xfe0ffc00) == 0xd6005000)
+ if((insn.bits & 0xfe0fffe0) == 0xd0001cc0)
{
- #include "insns/cvt_l_fmt.h"
+ #include "insns/cvt_d_w.h"
break;
}
- #include "insns/unimp.h"
- }
- default:
- {
- #include "insns/unimp.h"
- }
- }
- break;
- }
- case 0x6c:
- {
- switch((insn.bits >> 0xc) & 0x7)
- {
- case 0x0:
- {
- if((insn.bits & 0xfe007c00) == 0xd8000000)
+ if((insn.bits & 0xfe0fffe0) == 0xd0001c80)
{
- #include "insns/c_f_fmt.h"
+ #include "insns/cvt_d_l.h"
break;
}
- #include "insns/unimp.h"
- }
- case 0x1:
- {
- if((insn.bits & 0xfe007c00) == 0xd8001000)
+ if((insn.bits & 0xfe0fffe0) == 0xd0001c60)
{
- #include "insns/c_un_fmt.h"
+ #include "insns/truncu_w_d.h"
break;
}
#include "insns/unimp.h"
}
case 0x2:
{
- if((insn.bits & 0xfe007c00) == 0xd8002000)
+ if((insn.bits & 0xfe007fe0) == 0xd0002c20)
{
- #include "insns/c_eq_fmt.h"
+ #include "insns/c_eq_d.h"
break;
}
- #include "insns/unimp.h"
- }
- case 0x3:
- {
- if((insn.bits & 0xfe007c00) == 0xd8003000)
+ if((insn.bits & 0xfe007fe0) == 0xd0002020)
{
- #include "insns/c_ueq_fmt.h"
+ #include "insns/c_eq_s.h"
break;
}
- #include "insns/unimp.h"
- }
- case 0x4:
- {
- if((insn.bits & 0xfe007c00) == 0xd8004000)
+ if((insn.bits & 0xfe007fe0) == 0xd0002c60)
{
- #include "insns/c_olt_fmt.h"
+ #include "insns/c_le_d.h"
break;
}
- #include "insns/unimp.h"
- }
- case 0x5:
- {
- if((insn.bits & 0xfe007c00) == 0xd8005000)
+ if((insn.bits & 0xfe007fe0) == 0xd0002040)
{
- #include "insns/c_ult_fmt.h"
+ #include "insns/c_lt_s.h"
break;
}
- #include "insns/unimp.h"
- }
- case 0x6:
- {
- if((insn.bits & 0xfe007c00) == 0xd8006000)
+ if((insn.bits & 0xfe007fe0) == 0xd0002060)
{
- #include "insns/c_ole_fmt.h"
+ #include "insns/c_le_s.h"
break;
}
- #include "insns/unimp.h"
- }
- case 0x7:
- {
- if((insn.bits & 0xfe007c00) == 0xd8007000)
+ if((insn.bits & 0xfe007fe0) == 0xd0002c40)
{
- #include "insns/c_ule_fmt.h"
+ #include "insns/c_lt_d.h"
break;
}
#include "insns/unimp.h"
@@ -416,78 +284,42 @@ switch((insn.bits >> 0x19) & 0x7f)
}
break;
}
- case 0x6d:
+ case 0x6a:
{
switch((insn.bits >> 0xc) & 0x7)
{
case 0x0:
{
- if((insn.bits & 0xfe007c00) == 0xda000000)
+ if((insn.bits & 0xfe007fff) == 0xd4000000)
{
- #include "insns/c_sf_fmt.h"
+ #include "insns/mff_s.h"
break;
}
#include "insns/unimp.h"
}
case 0x1:
{
- if((insn.bits & 0xfe007c00) == 0xda001000)
- {
- #include "insns/c_ngle_fmt.h"
- break;
- }
- #include "insns/unimp.h"
- }
- case 0x2:
- {
- if((insn.bits & 0xfe007c00) == 0xda002000)
- {
- #include "insns/c_seq_fmt.h"
- break;
- }
- #include "insns/unimp.h"
- }
- case 0x3:
- {
- if((insn.bits & 0xfe007c00) == 0xda003000)
+ if((insn.bits & 0xfe007fff) == 0xd4001000)
{
- #include "insns/c_ngl_fmt.h"
+ #include "insns/mff_d.h"
break;
}
#include "insns/unimp.h"
}
case 0x4:
{
- if((insn.bits & 0xfe007c00) == 0xda004000)
+ if((insn.bits & 0xfe007fff) == 0xd4004000)
{
- #include "insns/c_lt_fmt.h"
+ #include "insns/mtf_s.h"
break;
}
#include "insns/unimp.h"
}
case 0x5:
{
- if((insn.bits & 0xfe007c00) == 0xda005000)
- {
- #include "insns/c_nge_fmt.h"
- break;
- }
- #include "insns/unimp.h"
- }
- case 0x6:
- {
- if((insn.bits & 0xfe007c00) == 0xda006000)
- {
- #include "insns/c_le_fmt.h"
- break;
- }
- #include "insns/unimp.h"
- }
- case 0x7:
- {
- if((insn.bits & 0xfe007c00) == 0xda007000)
+ if((insn.bits & 0xfe007fff) == 0xd4005000)
{
- #include "insns/c_ngt_fmt.h"
+ #include "insns/mtf_d.h"
break;
}
#include "insns/unimp.h"
diff --git a/riscv/insns/add_d.h b/riscv/insns/add_d.h
index e69de29..bd0f55a 100644
--- a/riscv/insns/add_d.h
+++ b/riscv/insns/add_d.h
@@ -0,0 +1,3 @@
+require_fp;
+FRC = float64_add(FRA, FRB);
+set_fp_exceptions;
diff --git a/riscv/insns/add_s.h b/riscv/insns/add_s.h
index e69de29..b4f98f6 100644
--- a/riscv/insns/add_s.h
+++ b/riscv/insns/add_s.h
@@ -0,0 +1,3 @@
+require_fp;
+FRC = float32_add(FRA, FRB);
+set_fp_exceptions;
diff --git a/riscv/insns/c_eq_d.h b/riscv/insns/c_eq_d.h
new file mode 100644
index 0000000..4387ea3
--- /dev/null
+++ b/riscv/insns/c_eq_d.h
@@ -0,0 +1,3 @@
+require_fp;
+RC = float64_eq(FRA, FRB);
+set_fp_exceptions;
diff --git a/riscv/insns/c_eq_fmt.h b/riscv/insns/c_eq_fmt.h
deleted file mode 100644
index e69de29..0000000
--- a/riscv/insns/c_eq_fmt.h
+++ /dev/null
diff --git a/riscv/insns/c_eq_s.h b/riscv/insns/c_eq_s.h
new file mode 100644
index 0000000..062fb74
--- /dev/null
+++ b/riscv/insns/c_eq_s.h
@@ -0,0 +1,3 @@
+require_fp;
+RC = float32_eq(FRA, FRB);
+set_fp_exceptions;
diff --git a/riscv/insns/c_f_fmt.h b/riscv/insns/c_f_fmt.h
deleted file mode 100644
index e69de29..0000000
--- a/riscv/insns/c_f_fmt.h
+++ /dev/null
diff --git a/riscv/insns/c_le_d.h b/riscv/insns/c_le_d.h
new file mode 100644
index 0000000..24ea657
--- /dev/null
+++ b/riscv/insns/c_le_d.h
@@ -0,0 +1,3 @@
+require_fp;
+RC = float64_le(FRA, FRB);
+set_fp_exceptions;
diff --git a/riscv/insns/c_le_fmt.h b/riscv/insns/c_le_fmt.h
deleted file mode 100644
index e69de29..0000000
--- a/riscv/insns/c_le_fmt.h
+++ /dev/null
diff --git a/riscv/insns/c_le_s.h b/riscv/insns/c_le_s.h
new file mode 100644
index 0000000..107622f
--- /dev/null
+++ b/riscv/insns/c_le_s.h
@@ -0,0 +1,3 @@
+require_fp;
+RC = float32_le(FRA, FRB);
+set_fp_exceptions;
diff --git a/riscv/insns/c_lt_d.h b/riscv/insns/c_lt_d.h
new file mode 100644
index 0000000..3d42500
--- /dev/null
+++ b/riscv/insns/c_lt_d.h
@@ -0,0 +1,3 @@
+require_fp;
+RC = float64_lt(FRA, FRB);
+set_fp_exceptions;
diff --git a/riscv/insns/c_lt_fmt.h b/riscv/insns/c_lt_fmt.h
deleted file mode 100644
index e69de29..0000000
--- a/riscv/insns/c_lt_fmt.h
+++ /dev/null
diff --git a/riscv/insns/c_lt_s.h b/riscv/insns/c_lt_s.h
new file mode 100644
index 0000000..1f7a0e1
--- /dev/null
+++ b/riscv/insns/c_lt_s.h
@@ -0,0 +1,3 @@
+require_fp;
+RC = float32_lt(FRA, FRB);
+set_fp_exceptions;
diff --git a/riscv/insns/c_nge_fmt.h b/riscv/insns/c_nge_fmt.h
deleted file mode 100644
index e69de29..0000000
--- a/riscv/insns/c_nge_fmt.h
+++ /dev/null
diff --git a/riscv/insns/c_ngl_fmt.h b/riscv/insns/c_ngl_fmt.h
deleted file mode 100644
index e69de29..0000000
--- a/riscv/insns/c_ngl_fmt.h
+++ /dev/null
diff --git a/riscv/insns/c_ngle_fmt.h b/riscv/insns/c_ngle_fmt.h
deleted file mode 100644
index e69de29..0000000
--- a/riscv/insns/c_ngle_fmt.h
+++ /dev/null
diff --git a/riscv/insns/c_ngt_fmt.h b/riscv/insns/c_ngt_fmt.h
deleted file mode 100644
index e69de29..0000000
--- a/riscv/insns/c_ngt_fmt.h
+++ /dev/null
diff --git a/riscv/insns/c_ole_fmt.h b/riscv/insns/c_ole_fmt.h
deleted file mode 100644
index e69de29..0000000
--- a/riscv/insns/c_ole_fmt.h
+++ /dev/null
diff --git a/riscv/insns/c_olt_fmt.h b/riscv/insns/c_olt_fmt.h
deleted file mode 100644
index e69de29..0000000
--- a/riscv/insns/c_olt_fmt.h
+++ /dev/null
diff --git a/riscv/insns/c_seq_fmt.h b/riscv/insns/c_seq_fmt.h
deleted file mode 100644
index e69de29..0000000
--- a/riscv/insns/c_seq_fmt.h
+++ /dev/null
diff --git a/riscv/insns/c_sf_fmt.h b/riscv/insns/c_sf_fmt.h
deleted file mode 100644
index e69de29..0000000
--- a/riscv/insns/c_sf_fmt.h
+++ /dev/null
diff --git a/riscv/insns/c_ueq_fmt.h b/riscv/insns/c_ueq_fmt.h
deleted file mode 100644
index e69de29..0000000
--- a/riscv/insns/c_ueq_fmt.h
+++ /dev/null
diff --git a/riscv/insns/c_ule_fmt.h b/riscv/insns/c_ule_fmt.h
deleted file mode 100644
index e69de29..0000000
--- a/riscv/insns/c_ule_fmt.h
+++ /dev/null
diff --git a/riscv/insns/c_ult_fmt.h b/riscv/insns/c_ult_fmt.h
deleted file mode 100644
index e69de29..0000000
--- a/riscv/insns/c_ult_fmt.h
+++ /dev/null
diff --git a/riscv/insns/c_un_fmt.h b/riscv/insns/c_un_fmt.h
deleted file mode 100644
index e69de29..0000000
--- a/riscv/insns/c_un_fmt.h
+++ /dev/null
diff --git a/riscv/insns/ceil_l_fmt.h b/riscv/insns/ceil_l_fmt.h
deleted file mode 100644
index e69de29..0000000
--- a/riscv/insns/ceil_l_fmt.h
+++ /dev/null
diff --git a/riscv/insns/ceil_w_fmt.h b/riscv/insns/ceil_w_fmt.h
deleted file mode 100644
index e69de29..0000000
--- a/riscv/insns/ceil_w_fmt.h
+++ /dev/null
diff --git a/riscv/insns/cvt_d_fmt.h b/riscv/insns/cvt_d_fmt.h
deleted file mode 100644
index e69de29..0000000
--- a/riscv/insns/cvt_d_fmt.h
+++ /dev/null
diff --git a/riscv/insns/cvt_d_l.h b/riscv/insns/cvt_d_l.h
new file mode 100644
index 0000000..5246f6f
--- /dev/null
+++ b/riscv/insns/cvt_d_l.h
@@ -0,0 +1,3 @@
+require_fp;
+FRC = int64_to_float64(FRA);
+set_fp_exceptions;
diff --git a/riscv/insns/cvt_d_s.h b/riscv/insns/cvt_d_s.h
new file mode 100644
index 0000000..481a4d1
--- /dev/null
+++ b/riscv/insns/cvt_d_s.h
@@ -0,0 +1,3 @@
+require_fp;
+FRC = float32_to_float64(FRA);
+set_fp_exceptions;
diff --git a/riscv/insns/cvt_d_w.h b/riscv/insns/cvt_d_w.h
new file mode 100644
index 0000000..67702a2
--- /dev/null
+++ b/riscv/insns/cvt_d_w.h
@@ -0,0 +1,3 @@
+require_fp;
+FRC = int32_to_float64(FRA);
+set_fp_exceptions;
diff --git a/riscv/insns/cvt_l_fmt.h b/riscv/insns/cvt_l_fmt.h
deleted file mode 100644
index e69de29..0000000
--- a/riscv/insns/cvt_l_fmt.h
+++ /dev/null
diff --git a/riscv/insns/cvt_s_d.h b/riscv/insns/cvt_s_d.h
new file mode 100644
index 0000000..528f11c
--- /dev/null
+++ b/riscv/insns/cvt_s_d.h
@@ -0,0 +1,3 @@
+require_fp;
+FRC = float64_to_float32(FRA);
+set_fp_exceptions;
diff --git a/riscv/insns/cvt_s_fmt.h b/riscv/insns/cvt_s_fmt.h
deleted file mode 100644
index e69de29..0000000
--- a/riscv/insns/cvt_s_fmt.h
+++ /dev/null
diff --git a/riscv/insns/cvt_s_l.h b/riscv/insns/cvt_s_l.h
new file mode 100644
index 0000000..2d1f93a
--- /dev/null
+++ b/riscv/insns/cvt_s_l.h
@@ -0,0 +1,3 @@
+require_fp;
+FRC = int64_to_float32(FRA);
+set_fp_exceptions;
diff --git a/riscv/insns/cvt_s_w.h b/riscv/insns/cvt_s_w.h
new file mode 100644
index 0000000..c2d583f
--- /dev/null
+++ b/riscv/insns/cvt_s_w.h
@@ -0,0 +1,3 @@
+require_fp;
+FRC = int32_to_float32(FRA);
+set_fp_exceptions;
diff --git a/riscv/insns/cvt_w_fmt.h b/riscv/insns/cvt_w_fmt.h
deleted file mode 100644
index e69de29..0000000
--- a/riscv/insns/cvt_w_fmt.h
+++ /dev/null
diff --git a/riscv/insns/cvtu_d_l.h b/riscv/insns/cvtu_d_l.h
new file mode 100644
index 0000000..5246f6f
--- /dev/null
+++ b/riscv/insns/cvtu_d_l.h
@@ -0,0 +1,3 @@
+require_fp;
+FRC = int64_to_float64(FRA);
+set_fp_exceptions;
diff --git a/riscv/insns/cvtu_d_w.h b/riscv/insns/cvtu_d_w.h
new file mode 100644
index 0000000..67702a2
--- /dev/null
+++ b/riscv/insns/cvtu_d_w.h
@@ -0,0 +1,3 @@
+require_fp;
+FRC = int32_to_float64(FRA);
+set_fp_exceptions;
diff --git a/riscv/insns/cvtu_s_l.h b/riscv/insns/cvtu_s_l.h
new file mode 100644
index 0000000..2d1f93a
--- /dev/null
+++ b/riscv/insns/cvtu_s_l.h
@@ -0,0 +1,3 @@
+require_fp;
+FRC = int64_to_float32(FRA);
+set_fp_exceptions;
diff --git a/riscv/insns/cvtu_s_w.h b/riscv/insns/cvtu_s_w.h
new file mode 100644
index 0000000..c2d583f
--- /dev/null
+++ b/riscv/insns/cvtu_s_w.h
@@ -0,0 +1,3 @@
+require_fp;
+FRC = int32_to_float32(FRA);
+set_fp_exceptions;
diff --git a/riscv/insns/div_d.h b/riscv/insns/div_d.h
index e69de29..3b47563 100644
--- a/riscv/insns/div_d.h
+++ b/riscv/insns/div_d.h
@@ -0,0 +1,3 @@
+require_fp;
+FRC = float64_div(FRA, FRB);
+set_fp_exceptions;
diff --git a/riscv/insns/div_s.h b/riscv/insns/div_s.h
index e69de29..cb5c9bd 100644
--- a/riscv/insns/div_s.h
+++ b/riscv/insns/div_s.h
@@ -0,0 +1,3 @@
+require_fp;
+FRC = float32_div(FRA, FRB);
+set_fp_exceptions;
diff --git a/riscv/insns/floor_l_fmt.h b/riscv/insns/floor_l_fmt.h
deleted file mode 100644
index e69de29..0000000
--- a/riscv/insns/floor_l_fmt.h
+++ /dev/null
diff --git a/riscv/insns/floor_w_fmt.h b/riscv/insns/floor_w_fmt.h
deleted file mode 100644
index e69de29..0000000
--- a/riscv/insns/floor_w_fmt.h
+++ /dev/null
diff --git a/riscv/insns/l_d.h b/riscv/insns/l_d.h
index 279fff2..760cf98 100644
--- a/riscv/insns/l_d.h
+++ b/riscv/insns/l_d.h
@@ -1,2 +1,2 @@
require_fp;
-FRA.bits = mmu.load_int64(RB+SIMM);
+FRA = mmu.load_int64(RB+SIMM);
diff --git a/riscv/insns/l_s.h b/riscv/insns/l_s.h
index 11cdf18..1637fed 100644
--- a/riscv/insns/l_s.h
+++ b/riscv/insns/l_s.h
@@ -1,2 +1,2 @@
require_fp;
-FRA.bits = mmu.load_int32(RB+SIMM);
+FRA = mmu.load_int32(RB+SIMM);
diff --git a/riscv/insns/mff_d.h b/riscv/insns/mff_d.h
index f1bb205..eaece44 100644
--- a/riscv/insns/mff_d.h
+++ b/riscv/insns/mff_d.h
@@ -1,3 +1,3 @@
require64;
require_fp;
-RA = FRB.bits;
+RA = FRB;
diff --git a/riscv/insns/mff_s.h b/riscv/insns/mff_s.h
index 9e3b9c4..6233a3f 100644
--- a/riscv/insns/mff_s.h
+++ b/riscv/insns/mff_s.h
@@ -1,2 +1,2 @@
require_fp;
-RA = sext32(FRB.bits);
+RA = sext32(FRB);
diff --git a/riscv/insns/mtf_d.h b/riscv/insns/mtf_d.h
index b0eeca9..fcee6a1 100644
--- a/riscv/insns/mtf_d.h
+++ b/riscv/insns/mtf_d.h
@@ -1,3 +1,3 @@
require64;
require_fp;
-FRA.bits = RB;
+FRA = RB;
diff --git a/riscv/insns/mtf_s.h b/riscv/insns/mtf_s.h
index 04f33fe..a3b7737 100644
--- a/riscv/insns/mtf_s.h
+++ b/riscv/insns/mtf_s.h
@@ -1,2 +1,2 @@
require_fp;
-FRA.bits = RB;
+FRA = sext32(RB);
diff --git a/riscv/insns/mul_d.h b/riscv/insns/mul_d.h
index e69de29..b2a0dbf 100644
--- a/riscv/insns/mul_d.h
+++ b/riscv/insns/mul_d.h
@@ -0,0 +1,3 @@
+require_fp;
+FRC = float64_mul(FRA, FRB);
+set_fp_exceptions;
diff --git a/riscv/insns/mul_s.h b/riscv/insns/mul_s.h
index e69de29..e7d4f3f 100644
--- a/riscv/insns/mul_s.h
+++ b/riscv/insns/mul_s.h
@@ -0,0 +1,3 @@
+require_fp;
+FRC = float32_mul(FRA, FRB);
+set_fp_exceptions;
diff --git a/riscv/insns/round_l_fmt.h b/riscv/insns/round_l_fmt.h
deleted file mode 100644
index e69de29..0000000
--- a/riscv/insns/round_l_fmt.h
+++ /dev/null
diff --git a/riscv/insns/round_w_fmt.h b/riscv/insns/round_w_fmt.h
deleted file mode 100644
index e69de29..0000000
--- a/riscv/insns/round_w_fmt.h
+++ /dev/null
diff --git a/riscv/insns/s_d.h b/riscv/insns/s_d.h
index 2d2f9c3..d1c8037 100644
--- a/riscv/insns/s_d.h
+++ b/riscv/insns/s_d.h
@@ -1,2 +1,2 @@
require_fp;
-mmu.store_uint64(RB+SIMM, FRA.bits);
+mmu.store_uint64(RB+SIMM, FRA);
diff --git a/riscv/insns/s_s.h b/riscv/insns/s_s.h
index 6c3006e..837c258 100644
--- a/riscv/insns/s_s.h
+++ b/riscv/insns/s_s.h
@@ -1,2 +1,2 @@
require_fp;
-mmu.store_uint32(RB+SIMM, FRA.bits);
+mmu.store_uint32(RB+SIMM, FRA);
diff --git a/riscv/insns/sgninj_d.h b/riscv/insns/sgninj_d.h
index a87ca63..8bca56a 100644
--- a/riscv/insns/sgninj_d.h
+++ b/riscv/insns/sgninj_d.h
@@ -1,2 +1,2 @@
require_fp;
-FRC.bits = (FRA.bits &~ INT64_MIN) | (FRB.bits & INT64_MIN);
+FRC = (FRA &~ INT64_MIN) | (FRB & INT64_MIN);
diff --git a/riscv/insns/sgninj_s.h b/riscv/insns/sgninj_s.h
index db56f49..b688177 100644
--- a/riscv/insns/sgninj_s.h
+++ b/riscv/insns/sgninj_s.h
@@ -1,2 +1,2 @@
require_fp;
-FRC.bits = (FRA.bits &~ (uint32_t)INT32_MIN) | (FRB.bits & (uint32_t)INT32_MIN);
+FRC = (FRA &~ (uint32_t)INT32_MIN) | (FRB & (uint32_t)INT32_MIN);
diff --git a/riscv/insns/sgninjn_d.h b/riscv/insns/sgninjn_d.h
index 5fad072..c526735 100644
--- a/riscv/insns/sgninjn_d.h
+++ b/riscv/insns/sgninjn_d.h
@@ -1,2 +1,2 @@
require_fp;
-FRC.bits = (FRA.bits &~ INT64_MIN) | ((~FRB.bits) & INT64_MIN);
+FRC = (FRA &~ INT64_MIN) | ((~FRB) & INT64_MIN);
diff --git a/riscv/insns/sgninjn_s.h b/riscv/insns/sgninjn_s.h
index c50967b..80dd7e8 100644
--- a/riscv/insns/sgninjn_s.h
+++ b/riscv/insns/sgninjn_s.h
@@ -1,2 +1,2 @@
require_fp;
-FRC.bits = (FRA.bits &~ (uint32_t)INT32_MIN) | ((~FRB.bits) & (uint32_t)INT32_MIN);
+FRC = (FRA &~ (uint32_t)INT32_MIN) | ((~FRB) & (uint32_t)INT32_MIN);
diff --git a/riscv/insns/sgnmul_d.h b/riscv/insns/sgnmul_d.h
index 47d950f..c30dcea 100644
--- a/riscv/insns/sgnmul_d.h
+++ b/riscv/insns/sgnmul_d.h
@@ -1,2 +1,2 @@
require_fp;
-FRC.bits = FRA.bits ^ (FRB.bits & INT64_MIN);
+FRC = FRA ^ (FRB & INT64_MIN);
diff --git a/riscv/insns/sgnmul_s.h b/riscv/insns/sgnmul_s.h
index 2a9ae11..6640b31 100644
--- a/riscv/insns/sgnmul_s.h
+++ b/riscv/insns/sgnmul_s.h
@@ -1,2 +1,2 @@
require_fp;
-FRC.bits = FRA.bits ^ (FRB.bits & (uint32_t)INT32_MIN);
+FRC = FRA ^ (FRB & (uint32_t)INT32_MIN);
diff --git a/riscv/insns/sqrt_d.h b/riscv/insns/sqrt_d.h
index e69de29..3f831f5 100644
--- a/riscv/insns/sqrt_d.h
+++ b/riscv/insns/sqrt_d.h
@@ -0,0 +1,3 @@
+require_fp;
+FRC = float64_sqrt(FRA);
+set_fp_exceptions;
diff --git a/riscv/insns/sqrt_s.h b/riscv/insns/sqrt_s.h
index e69de29..51b5892 100644
--- a/riscv/insns/sqrt_s.h
+++ b/riscv/insns/sqrt_s.h
@@ -0,0 +1,3 @@
+require_fp;
+FRC = float32_sqrt(FRA);
+set_fp_exceptions;
diff --git a/riscv/insns/sub_d.h b/riscv/insns/sub_d.h
index e69de29..55d0e86 100644
--- a/riscv/insns/sub_d.h
+++ b/riscv/insns/sub_d.h
@@ -0,0 +1,3 @@
+require_fp;
+FRC = float64_sub(FRA, FRB);
+set_fp_exceptions;
diff --git a/riscv/insns/sub_s.h b/riscv/insns/sub_s.h
index e69de29..4a359bf 100644
--- a/riscv/insns/sub_s.h
+++ b/riscv/insns/sub_s.h
@@ -0,0 +1,3 @@
+require_fp;
+FRC = float32_sub(FRA, FRB);
+set_fp_exceptions;
diff --git a/riscv/insns/trunc_l_d.h b/riscv/insns/trunc_l_d.h
new file mode 100644
index 0000000..ecca8cd
--- /dev/null
+++ b/riscv/insns/trunc_l_d.h
@@ -0,0 +1,3 @@
+require_fp;
+FRC = float64_to_int64_round_to_zero(FRA);
+set_fp_exceptions;
diff --git a/riscv/insns/trunc_l_fmt.h b/riscv/insns/trunc_l_fmt.h
deleted file mode 100644
index e69de29..0000000
--- a/riscv/insns/trunc_l_fmt.h
+++ /dev/null
diff --git a/riscv/insns/trunc_l_s.h b/riscv/insns/trunc_l_s.h
new file mode 100644
index 0000000..9dd0e51
--- /dev/null
+++ b/riscv/insns/trunc_l_s.h
@@ -0,0 +1,3 @@
+require_fp;
+FRC = float32_to_int64_round_to_zero(FRA);
+set_fp_exceptions;
diff --git a/riscv/insns/trunc_w_d.h b/riscv/insns/trunc_w_d.h
new file mode 100644
index 0000000..9b7cdb0
--- /dev/null
+++ b/riscv/insns/trunc_w_d.h
@@ -0,0 +1,3 @@
+require_fp;
+FRC = float64_to_int32_round_to_zero(FRA);
+set_fp_exceptions;
diff --git a/riscv/insns/trunc_w_fmt.h b/riscv/insns/trunc_w_fmt.h
deleted file mode 100644
index e69de29..0000000
--- a/riscv/insns/trunc_w_fmt.h
+++ /dev/null
diff --git a/riscv/insns/trunc_w_s.h b/riscv/insns/trunc_w_s.h
new file mode 100644
index 0000000..147ec8b
--- /dev/null
+++ b/riscv/insns/trunc_w_s.h
@@ -0,0 +1,3 @@
+require_fp;
+FRC = float32_to_int32_round_to_zero(FRA);
+set_fp_exceptions;
diff --git a/riscv/insns/truncu_l_d.h b/riscv/insns/truncu_l_d.h
new file mode 100644
index 0000000..ecca8cd
--- /dev/null
+++ b/riscv/insns/truncu_l_d.h
@@ -0,0 +1,3 @@
+require_fp;
+FRC = float64_to_int64_round_to_zero(FRA);
+set_fp_exceptions;
diff --git a/riscv/insns/truncu_l_s.h b/riscv/insns/truncu_l_s.h
new file mode 100644
index 0000000..9dd0e51
--- /dev/null
+++ b/riscv/insns/truncu_l_s.h
@@ -0,0 +1,3 @@
+require_fp;
+FRC = float32_to_int64_round_to_zero(FRA);
+set_fp_exceptions;
diff --git a/riscv/insns/truncu_w_d.h b/riscv/insns/truncu_w_d.h
new file mode 100644
index 0000000..9b7cdb0
--- /dev/null
+++ b/riscv/insns/truncu_w_d.h
@@ -0,0 +1,3 @@
+require_fp;
+FRC = float64_to_int32_round_to_zero(FRA);
+set_fp_exceptions;
diff --git a/riscv/insns/truncu_w_s.h b/riscv/insns/truncu_w_s.h
new file mode 100644
index 0000000..147ec8b
--- /dev/null
+++ b/riscv/insns/truncu_w_s.h
@@ -0,0 +1,3 @@
+require_fp;
+FRC = float32_to_int32_round_to_zero(FRA);
+set_fp_exceptions;
diff --git a/riscv/processor.cc b/riscv/processor.cc
index 5751c70..7ca015d 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -1,11 +1,13 @@
#include <bfd.h>
#include <dis-asm.h>
+#include <cmath>
#include <cstdlib>
#include <iostream>
#include "processor.h"
#include "common.h"
#include "config.h"
#include "sim.h"
+#include "softfloat.h"
processor_t::processor_t(sim_t* _sim, char* _mem, size_t _memsz)
: sim(_sim), mmu(_mem,_memsz)
@@ -17,6 +19,7 @@ processor_t::processor_t(sim_t* _sim, char* _mem, size_t _memsz)
epc = 0;
badvaddr = 0;
set_sr(SR_S);
+ set_fsr(0);
memset(counters,0,sizeof(counters));
@@ -45,6 +48,11 @@ void processor_t::set_sr(uint32_t val)
gprlen = ((sr & SR_S) ? (sr & SR_KX) : (sr & SR_UX)) ? 64 : 32;
}
+void processor_t::set_fsr(uint32_t val)
+{
+ fsr = val & ~FSR_ZERO;
+}
+
void processor_t::step(size_t n, bool noisy)
{
size_t i = 0;
diff --git a/riscv/processor.h b/riscv/processor.h
index 652fa07..8c64d6d 100644
--- a/riscv/processor.h
+++ b/riscv/processor.h
@@ -27,6 +27,7 @@ private:
reg_t ebase;
uint32_t id;
uint32_t sr;
+ uint32_t fsr;
int gprlen;
// shared memory
@@ -37,6 +38,7 @@ private:
// functions
void set_sr(uint32_t val);
+ void set_fsr(uint32_t val);
void take_trap(trap_t t);
void disasm(insn_t insn, reg_t pc);
diff --git a/riscv/riscv.mk.in b/riscv/riscv.mk.in
index bd806cc..3f6427d 100644
--- a/riscv/riscv.mk.in
+++ b/riscv/riscv.mk.in
@@ -1,4 +1,4 @@
-riscv_subproject_deps =
+riscv_subproject_deps = softfloat \
riscv_hdrs = \
applink.h \