diff options
author | Andrew Waterman <waterman@s141.Millennium.Berkeley.EDU> | 2010-08-09 20:51:44 -0700 |
---|---|---|
committer | Andrew Waterman <waterman@s141.Millennium.Berkeley.EDU> | 2010-08-09 20:51:44 -0700 |
commit | 2d75bf71bb3990f5a718ddca3c99f9139c03c10b (patch) | |
tree | 029a524ddc8c98c00bf0ef2d25993649b3644ae6 /riscv | |
parent | d9170d6002c684acdfca1ba124dba2235081b578 (diff) | |
download | spike-2d75bf71bb3990f5a718ddca3c99f9139c03c10b.zip spike-2d75bf71bb3990f5a718ddca3c99f9139c03c10b.tar.gz spike-2d75bf71bb3990f5a718ddca3c99f9139c03c10b.tar.bz2 |
[xcc,sim] implement FP using softfloat
The intersection of the Hauser FP and MIPS FP is implemented.
Diffstat (limited to 'riscv')
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 \ |