The intersection of the Hauser FP and MIPS FP is implemented.
+ # Determine if this is a required or an optional subproject
+
+
+
+ # Determine if there is a group with the same name
+
+
+
+ # Create variations of the subproject name suitable for use as a CPP
+ # enabled define, a shell enabled variable, and a shell function
+
+
+
+
+
+
+
+
+
+
+
+ # Add subproject to our running list
+
+ subprojects="$subprojects softfloat"
+
+ # Process the subproject appropriately. If enabled add it to the
+ # $enabled_subprojects running shell variable, set a
+ # SUBPROJECT_ENABLED C define, and include the appropriate
+ # 'subproject.ac'.
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: configuring default subproject : softfloat" >&5
+$as_echo "$as_me: configuring default subproject : softfloat" >&6;}
+ ac_config_files="$ac_config_files softfloat.mk:softfloat/softfloat.mk.in"
+
+ enable_softfloat_sproj="yes"
+ subprojects_enabled="$subprojects_enabled softfloat"
+
+$as_echo "#define SOFTFLOAT_ENABLED /**/" >>confdefs.h
+
+
+
+
+
+
# Output make variables
do
case $ac_config_target in
"riscv.mk") CONFIG_FILES="$CONFIG_FILES riscv.mk:riscv/riscv.mk.in" ;;
+ "softfloat.mk") CONFIG_FILES="$CONFIG_FILES softfloat.mk:softfloat/softfloat.mk.in" ;;
"config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
# The '*' suffix indicates an optional subproject. The '**' suffix
# indicates an optional subproject which is also the name of a group.
-MCPPBS_SUBPROJECTS([ riscv ])
+MCPPBS_SUBPROJECTS([ riscv, softfloat ])
#-------------------------------------------------------------------------
# MCPPBS subproject groups
#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;
#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
#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)
{
}
#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"
}
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"
+require_fp;
+FRC = float64_add(FRA, FRB);
+set_fp_exceptions;
+require_fp;
+FRC = float32_add(FRA, FRB);
+set_fp_exceptions;
--- /dev/null
+require_fp;
+RC = float64_eq(FRA, FRB);
+set_fp_exceptions;
--- /dev/null
+require_fp;
+RC = float32_eq(FRA, FRB);
+set_fp_exceptions;
--- /dev/null
+require_fp;
+RC = float64_le(FRA, FRB);
+set_fp_exceptions;
--- /dev/null
+require_fp;
+RC = float32_le(FRA, FRB);
+set_fp_exceptions;
--- /dev/null
+require_fp;
+RC = float64_lt(FRA, FRB);
+set_fp_exceptions;
--- /dev/null
+require_fp;
+RC = float32_lt(FRA, FRB);
+set_fp_exceptions;
--- /dev/null
+require_fp;
+FRC = int64_to_float64(FRA);
+set_fp_exceptions;
--- /dev/null
+require_fp;
+FRC = float32_to_float64(FRA);
+set_fp_exceptions;
--- /dev/null
+require_fp;
+FRC = int32_to_float64(FRA);
+set_fp_exceptions;
--- /dev/null
+require_fp;
+FRC = float64_to_float32(FRA);
+set_fp_exceptions;
--- /dev/null
+require_fp;
+FRC = int64_to_float32(FRA);
+set_fp_exceptions;
--- /dev/null
+require_fp;
+FRC = int32_to_float32(FRA);
+set_fp_exceptions;
--- /dev/null
+require_fp;
+FRC = int64_to_float64(FRA);
+set_fp_exceptions;
--- /dev/null
+require_fp;
+FRC = int32_to_float64(FRA);
+set_fp_exceptions;
--- /dev/null
+require_fp;
+FRC = int64_to_float32(FRA);
+set_fp_exceptions;
--- /dev/null
+require_fp;
+FRC = int32_to_float32(FRA);
+set_fp_exceptions;
+require_fp;
+FRC = float64_div(FRA, FRB);
+set_fp_exceptions;
+require_fp;
+FRC = float32_div(FRA, FRB);
+set_fp_exceptions;
require_fp;
-FRA.bits = mmu.load_int64(RB+SIMM);
+FRA = mmu.load_int64(RB+SIMM);
require_fp;
-FRA.bits = mmu.load_int32(RB+SIMM);
+FRA = mmu.load_int32(RB+SIMM);
require64;
require_fp;
-RA = FRB.bits;
+RA = FRB;
require_fp;
-RA = sext32(FRB.bits);
+RA = sext32(FRB);
require64;
require_fp;
-FRA.bits = RB;
+FRA = RB;
require_fp;
-FRA.bits = RB;
+FRA = sext32(RB);
+require_fp;
+FRC = float64_mul(FRA, FRB);
+set_fp_exceptions;
+require_fp;
+FRC = float32_mul(FRA, FRB);
+set_fp_exceptions;
require_fp;
-mmu.store_uint64(RB+SIMM, FRA.bits);
+mmu.store_uint64(RB+SIMM, FRA);
require_fp;
-mmu.store_uint32(RB+SIMM, FRA.bits);
+mmu.store_uint32(RB+SIMM, FRA);
require_fp;
-FRC.bits = (FRA.bits &~ INT64_MIN) | (FRB.bits & INT64_MIN);
+FRC = (FRA &~ INT64_MIN) | (FRB & INT64_MIN);
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);
require_fp;
-FRC.bits = (FRA.bits &~ INT64_MIN) | ((~FRB.bits) & INT64_MIN);
+FRC = (FRA &~ INT64_MIN) | ((~FRB) & INT64_MIN);
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);
require_fp;
-FRC.bits = FRA.bits ^ (FRB.bits & INT64_MIN);
+FRC = FRA ^ (FRB & INT64_MIN);
require_fp;
-FRC.bits = FRA.bits ^ (FRB.bits & (uint32_t)INT32_MIN);
+FRC = FRA ^ (FRB & (uint32_t)INT32_MIN);
+require_fp;
+FRC = float64_sqrt(FRA);
+set_fp_exceptions;
+require_fp;
+FRC = float32_sqrt(FRA);
+set_fp_exceptions;
+require_fp;
+FRC = float64_sub(FRA, FRB);
+set_fp_exceptions;
+require_fp;
+FRC = float32_sub(FRA, FRB);
+set_fp_exceptions;
--- /dev/null
+require_fp;
+FRC = float64_to_int64_round_to_zero(FRA);
+set_fp_exceptions;
--- /dev/null
+require_fp;
+FRC = float32_to_int64_round_to_zero(FRA);
+set_fp_exceptions;
--- /dev/null
+require_fp;
+FRC = float64_to_int32_round_to_zero(FRA);
+set_fp_exceptions;
--- /dev/null
+require_fp;
+FRC = float32_to_int32_round_to_zero(FRA);
+set_fp_exceptions;
--- /dev/null
+require_fp;
+FRC = float64_to_int64_round_to_zero(FRA);
+set_fp_exceptions;
--- /dev/null
+require_fp;
+FRC = float32_to_int64_round_to_zero(FRA);
+set_fp_exceptions;
--- /dev/null
+require_fp;
+FRC = float64_to_int32_round_to_zero(FRA);
+set_fp_exceptions;
--- /dev/null
+require_fp;
+FRC = float32_to_int32_round_to_zero(FRA);
+set_fp_exceptions;
#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)
epc = 0;
badvaddr = 0;
set_sr(SR_S);
+ set_fsr(0);
memset(counters,0,sizeof(counters));
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;
reg_t ebase;
uint32_t id;
uint32_t sr;
+ uint32_t fsr;
int gprlen;
// shared memory
// 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);
-riscv_subproject_deps =
+riscv_subproject_deps = softfloat \
riscv_hdrs = \
applink.h \
--- /dev/null
+
+/*============================================================================
+
+This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
+Package, Release 2b.
+
+Written by John R. Hauser. This work was made possible in part by the
+International Computer Science Institute, located at Suite 600, 1947 Center
+Street, Berkeley, California 94704. Funding was partially provided by the
+National Science Foundation under grant MIP-9311980. The original version
+of this code was written as part of a project to build a fixed-point vector
+processor in collaboration with the University of California at Berkeley,
+overseen by Profs. Nelson Morgan and John Wawrzynek. More information
+is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
+arithmetic/SoftFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
+been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
+RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
+AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
+COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
+EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
+INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
+OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) the source code for the derivative work includes prominent notice that
+the work is derivative, and (2) the source code includes prominent notice with
+these four paragraphs for those parts of this code that are retained.
+
+=============================================================================*/
+
+/*----------------------------------------------------------------------------
+| The macro `FLOATX80' must be defined to enable the extended double-precision
+| floating-point format `floatx80'. If this macro is not defined, the
+| `floatx80' type will not be defined, and none of the functions that either
+| input or output the `floatx80' type will be defined. The same applies to
+| the `FLOAT128' macro and the quadruple-precision format `float128'.
+*----------------------------------------------------------------------------*/
+#define FLOATX80
+#define FLOAT128
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE floating-point types.
+*----------------------------------------------------------------------------*/
+typedef unsigned int float32;
+typedef unsigned long long float64;
+#ifdef FLOATX80
+typedef struct {
+ unsigned short high;
+ unsigned long long low;
+} floatx80;
+#endif
+#ifdef FLOAT128
+typedef struct {
+ unsigned long long high, low;
+} float128;
+#endif
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE floating-point underflow tininess-detection mode.
+*----------------------------------------------------------------------------*/
+extern int float_detect_tininess;
+enum {
+ float_tininess_after_rounding = 0,
+ float_tininess_before_rounding = 1
+};
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE floating-point rounding mode.
+*----------------------------------------------------------------------------*/
+extern int float_rounding_mode;
+enum {
+ float_round_nearest_even = 0,
+ float_round_to_zero = 1,
+ float_round_up = 2,
+ float_round_down = 3
+};
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE floating-point exception flags.
+*----------------------------------------------------------------------------*/
+extern int float_exception_flags;
+enum {
+ float_flag_inexact = 1,
+ float_flag_divbyzero = 2,
+ float_flag_underflow = 4,
+ float_flag_overflow = 8,
+ float_flag_invalid = 16
+};
+
+/*----------------------------------------------------------------------------
+| Routine to raise any or all of the software IEC/IEEE floating-point
+| exception flags.
+*----------------------------------------------------------------------------*/
+void float_raise( int );
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE integer-to-floating-point conversion routines.
+*----------------------------------------------------------------------------*/
+float32 int32_to_float32( int );
+float64 int32_to_float64( int );
+#ifdef FLOATX80
+floatx80 int32_to_floatx80( int );
+#endif
+#ifdef FLOAT128
+float128 int32_to_float128( int );
+#endif
+float32 int64_to_float32( long long );
+float64 int64_to_float64( long long );
+#ifdef FLOATX80
+floatx80 int64_to_floatx80( long long );
+#endif
+#ifdef FLOAT128
+float128 int64_to_float128( long long );
+#endif
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE single-precision conversion routines.
+*----------------------------------------------------------------------------*/
+int float32_to_int32( float32 );
+int float32_to_int32_round_to_zero( float32 );
+long long float32_to_int64( float32 );
+long long float32_to_int64_round_to_zero( float32 );
+float64 float32_to_float64( float32 );
+#ifdef FLOATX80
+floatx80 float32_to_floatx80( float32 );
+#endif
+#ifdef FLOAT128
+float128 float32_to_float128( float32 );
+#endif
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE single-precision operations.
+*----------------------------------------------------------------------------*/
+float32 float32_round_to_int( float32 );
+float32 float32_add( float32, float32 );
+float32 float32_sub( float32, float32 );
+float32 float32_mul( float32, float32 );
+float32 float32_div( float32, float32 );
+float32 float32_rem( float32, float32 );
+float32 float32_sqrt( float32 );
+int float32_eq( float32, float32 );
+int float32_le( float32, float32 );
+int float32_lt( float32, float32 );
+int float32_eq_signaling( float32, float32 );
+int float32_le_quiet( float32, float32 );
+int float32_lt_quiet( float32, float32 );
+int float32_is_signaling_nan( float32 );
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE double-precision conversion routines.
+*----------------------------------------------------------------------------*/
+int float64_to_int32( float64 );
+int float64_to_int32_round_to_zero( float64 );
+long long float64_to_int64( float64 );
+long long float64_to_int64_round_to_zero( float64 );
+float32 float64_to_float32( float64 );
+#ifdef FLOATX80
+floatx80 float64_to_floatx80( float64 );
+#endif
+#ifdef FLOAT128
+float128 float64_to_float128( float64 );
+#endif
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE double-precision operations.
+*----------------------------------------------------------------------------*/
+float64 float64_round_to_int( float64 );
+float64 float64_add( float64, float64 );
+float64 float64_sub( float64, float64 );
+float64 float64_mul( float64, float64 );
+float64 float64_div( float64, float64 );
+float64 float64_rem( float64, float64 );
+float64 float64_sqrt( float64 );
+int float64_eq( float64, float64 );
+int float64_le( float64, float64 );
+int float64_lt( float64, float64 );
+int float64_eq_signaling( float64, float64 );
+int float64_le_quiet( float64, float64 );
+int float64_lt_quiet( float64, float64 );
+int float64_is_signaling_nan( float64 );
+
+#ifdef FLOATX80
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE extended double-precision conversion routines.
+*----------------------------------------------------------------------------*/
+int floatx80_to_int32( floatx80 );
+int floatx80_to_int32_round_to_zero( floatx80 );
+long long floatx80_to_int64( floatx80 );
+long long floatx80_to_int64_round_to_zero( floatx80 );
+float32 floatx80_to_float32( floatx80 );
+float64 floatx80_to_float64( floatx80 );
+#ifdef FLOAT128
+float128 floatx80_to_float128( floatx80 );
+#endif
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE extended double-precision rounding precision. Valid
+| values are 32, 64, and 80.
+*----------------------------------------------------------------------------*/
+extern int floatx80_rounding_precision;
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE extended double-precision operations.
+*----------------------------------------------------------------------------*/
+floatx80 floatx80_round_to_int( floatx80 );
+floatx80 floatx80_add( floatx80, floatx80 );
+floatx80 floatx80_sub( floatx80, floatx80 );
+floatx80 floatx80_mul( floatx80, floatx80 );
+floatx80 floatx80_div( floatx80, floatx80 );
+floatx80 floatx80_rem( floatx80, floatx80 );
+floatx80 floatx80_sqrt( floatx80 );
+int floatx80_eq( floatx80, floatx80 );
+int floatx80_le( floatx80, floatx80 );
+int floatx80_lt( floatx80, floatx80 );
+int floatx80_eq_signaling( floatx80, floatx80 );
+int floatx80_le_quiet( floatx80, floatx80 );
+int floatx80_lt_quiet( floatx80, floatx80 );
+int floatx80_is_signaling_nan( floatx80 );
+
+#endif
+
+#ifdef FLOAT128
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE quadruple-precision conversion routines.
+*----------------------------------------------------------------------------*/
+int float128_to_int32( float128 );
+int float128_to_int32_round_to_zero( float128 );
+long long float128_to_int64( float128 );
+long long float128_to_int64_round_to_zero( float128 );
+float32 float128_to_float32( float128 );
+float64 float128_to_float64( float128 );
+#ifdef FLOATX80
+floatx80 float128_to_floatx80( float128 );
+#endif
+
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE quadruple-precision operations.
+*----------------------------------------------------------------------------*/
+float128 float128_round_to_int( float128 );
+float128 float128_add( float128, float128 );
+float128 float128_sub( float128, float128 );
+float128 float128_mul( float128, float128 );
+float128 float128_div( float128, float128 );
+float128 float128_rem( float128, float128 );
+float128 float128_sqrt( float128 );
+int float128_eq( float128, float128 );
+int float128_le( float128, float128 );
+int float128_lt( float128, float128 );
+int float128_eq_signaling( float128, float128 );
+int float128_le_quiet( float128, float128 );
+int float128_lt_quiet( float128, float128 );
+int float128_is_signaling_nan( float128 );
+
+#endif
+
sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 );\r
} while ( 0 <= (sbits64) aSig0 );\r
add128(\r
- aSig0, aSig1, alternateASig0, alternateASig1, &sigMean0, &sigMean1 );\r
+ aSig0, aSig1, alternateASig0, alternateASig1, (bits64*)&sigMean0, &sigMean1 );\r
if ( ( sigMean0 < 0 )\r
|| ( ( ( sigMean0 | sigMean1 ) == 0 ) && ( q & 1 ) ) ) {\r
aSig0 = alternateASig0;\r
--- /dev/null
+#include "softfloat.c"
-
-/*============================================================================
-
-This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
-Package, Release 2b.
-
-Written by John R. Hauser. This work was made possible in part by the
-International Computer Science Institute, located at Suite 600, 1947 Center
-Street, Berkeley, California 94704. Funding was partially provided by the
-National Science Foundation under grant MIP-9311980. The original version
-of this code was written as part of a project to build a fixed-point vector
-processor in collaboration with the University of California at Berkeley,
-overseen by Profs. Nelson Morgan and John Wawrzynek. More information
-is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
-arithmetic/SoftFloat.html'.
-
-THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
-been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
-RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
-AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
-COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
-EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
-INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
-OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
-
-Derivative works are acceptable, even for commercial purposes, so long as
-(1) the source code for the derivative work includes prominent notice that
-the work is derivative, and (2) the source code includes prominent notice with
-these four paragraphs for those parts of this code that are retained.
-
-=============================================================================*/
-
-/*----------------------------------------------------------------------------
-| The macro `FLOATX80' must be defined to enable the extended double-precision
-| floating-point format `floatx80'. If this macro is not defined, the
-| `floatx80' type will not be defined, and none of the functions that either
-| input or output the `floatx80' type will be defined. The same applies to
-| the `FLOAT128' macro and the quadruple-precision format `float128'.
-*----------------------------------------------------------------------------*/
-#define FLOATX80
-#define FLOAT128
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point types.
-*----------------------------------------------------------------------------*/
-typedef unsigned int float32;
-typedef unsigned long long float64;
-#ifdef FLOATX80
-typedef struct {
- unsigned short high;
- unsigned long long low;
-} floatx80;
-#endif
-#ifdef FLOAT128
-typedef struct {
- unsigned long long high, low;
-} float128;
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point underflow tininess-detection mode.
-*----------------------------------------------------------------------------*/
-extern int float_detect_tininess;
-enum {
- float_tininess_after_rounding = 0,
- float_tininess_before_rounding = 1
-};
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point rounding mode.
-*----------------------------------------------------------------------------*/
-extern int float_rounding_mode;
-enum {
- float_round_nearest_even = 0,
- float_round_to_zero = 1,
- float_round_up = 2,
- float_round_down = 3
-};
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE floating-point exception flags.
-*----------------------------------------------------------------------------*/
-extern int float_exception_flags;
-enum {
- float_flag_inexact = 1,
- float_flag_divbyzero = 2,
- float_flag_underflow = 4,
- float_flag_overflow = 8,
- float_flag_invalid = 16
-};
-
-/*----------------------------------------------------------------------------
-| Routine to raise any or all of the software IEC/IEEE floating-point
-| exception flags.
-*----------------------------------------------------------------------------*/
-void float_raise( int );
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE integer-to-floating-point conversion routines.
-*----------------------------------------------------------------------------*/
-float32 int32_to_float32( int );
-float64 int32_to_float64( int );
-#ifdef FLOATX80
-floatx80 int32_to_floatx80( int );
-#endif
-#ifdef FLOAT128
-float128 int32_to_float128( int );
-#endif
-float32 int64_to_float32( long long );
-float64 int64_to_float64( long long );
-#ifdef FLOATX80
-floatx80 int64_to_floatx80( long long );
-#endif
-#ifdef FLOAT128
-float128 int64_to_float128( long long );
+#ifdef __cplusplus
+extern "C" {
#endif
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE single-precision conversion routines.
-*----------------------------------------------------------------------------*/
-int float32_to_int32( float32 );
-int float32_to_int32_round_to_zero( float32 );
-long long float32_to_int64( float32 );
-long long float32_to_int64_round_to_zero( float32 );
-float64 float32_to_float64( float32 );
-#ifdef FLOATX80
-floatx80 float32_to_floatx80( float32 );
-#endif
-#ifdef FLOAT128
-float128 float32_to_float128( float32 );
-#endif
+#ifndef _SOFTFLOAT_H
+#define _SOFTFLOAT_H
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE single-precision operations.
-*----------------------------------------------------------------------------*/
-float32 float32_round_to_int( float32 );
-float32 float32_add( float32, float32 );
-float32 float32_sub( float32, float32 );
-float32 float32_mul( float32, float32 );
-float32 float32_div( float32, float32 );
-float32 float32_rem( float32, float32 );
-float32 float32_sqrt( float32 );
-int float32_eq( float32, float32 );
-int float32_le( float32, float32 );
-int float32_lt( float32, float32 );
-int float32_eq_signaling( float32, float32 );
-int float32_le_quiet( float32, float32 );
-int float32_lt_quiet( float32, float32 );
-int float32_is_signaling_nan( float32 );
+#include "softfloat-header"
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE double-precision conversion routines.
-*----------------------------------------------------------------------------*/
-int float64_to_int32( float64 );
-int float64_to_int32_round_to_zero( float64 );
-long long float64_to_int64( float64 );
-long long float64_to_int64_round_to_zero( float64 );
-float32 float64_to_float32( float64 );
-#ifdef FLOATX80
-floatx80 float64_to_floatx80( float64 );
#endif
-#ifdef FLOAT128
-float128 float64_to_float128( float64 );
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE double-precision operations.
-*----------------------------------------------------------------------------*/
-float64 float64_round_to_int( float64 );
-float64 float64_add( float64, float64 );
-float64 float64_sub( float64, float64 );
-float64 float64_mul( float64, float64 );
-float64 float64_div( float64, float64 );
-float64 float64_rem( float64, float64 );
-float64 float64_sqrt( float64 );
-int float64_eq( float64, float64 );
-int float64_le( float64, float64 );
-int float64_lt( float64, float64 );
-int float64_eq_signaling( float64, float64 );
-int float64_le_quiet( float64, float64 );
-int float64_lt_quiet( float64, float64 );
-int float64_is_signaling_nan( float64 );
-#ifdef FLOATX80
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE extended double-precision conversion routines.
-*----------------------------------------------------------------------------*/
-int floatx80_to_int32( floatx80 );
-int floatx80_to_int32_round_to_zero( floatx80 );
-long long floatx80_to_int64( floatx80 );
-long long floatx80_to_int64_round_to_zero( floatx80 );
-float32 floatx80_to_float32( floatx80 );
-float64 floatx80_to_float64( floatx80 );
-#ifdef FLOAT128
-float128 floatx80_to_float128( floatx80 );
+#ifdef __cplusplus
+}
#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE extended double-precision rounding precision. Valid
-| values are 32, 64, and 80.
-*----------------------------------------------------------------------------*/
-extern int floatx80_rounding_precision;
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE extended double-precision operations.
-*----------------------------------------------------------------------------*/
-floatx80 floatx80_round_to_int( floatx80 );
-floatx80 floatx80_add( floatx80, floatx80 );
-floatx80 floatx80_sub( floatx80, floatx80 );
-floatx80 floatx80_mul( floatx80, floatx80 );
-floatx80 floatx80_div( floatx80, floatx80 );
-floatx80 floatx80_rem( floatx80, floatx80 );
-floatx80 floatx80_sqrt( floatx80 );
-int floatx80_eq( floatx80, floatx80 );
-int floatx80_le( floatx80, floatx80 );
-int floatx80_lt( floatx80, floatx80 );
-int floatx80_eq_signaling( floatx80, floatx80 );
-int floatx80_le_quiet( floatx80, floatx80 );
-int floatx80_lt_quiet( floatx80, floatx80 );
-int floatx80_is_signaling_nan( floatx80 );
-
-#endif
-
-#ifdef FLOAT128
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE quadruple-precision conversion routines.
-*----------------------------------------------------------------------------*/
-int float128_to_int32( float128 );
-int float128_to_int32_round_to_zero( float128 );
-long long float128_to_int64( float128 );
-long long float128_to_int64_round_to_zero( float128 );
-float32 float128_to_float32( float128 );
-float64 float128_to_float64( float128 );
-#ifdef FLOATX80
-floatx80 float128_to_floatx80( float128 );
-#endif
-
-/*----------------------------------------------------------------------------
-| Software IEC/IEEE quadruple-precision operations.
-*----------------------------------------------------------------------------*/
-float128 float128_round_to_int( float128 );
-float128 float128_add( float128, float128 );
-float128 float128_sub( float128, float128 );
-float128 float128_mul( float128, float128 );
-float128 float128_div( float128, float128 );
-float128 float128_rem( float128, float128 );
-float128 float128_sqrt( float128 );
-int float128_eq( float128, float128 );
-int float128_le( float128, float128 );
-int float128_lt( float128, float128 );
-int float128_eq_signaling( float128, float128 );
-int float128_le_quiet( float128, float128 );
-int float128_lt_quiet( float128, float128 );
-int float128_is_signaling_nan( float128 );
-
-#endif
-