[xcc,sim] implement FP using softfloat
authorAndrew Waterman <waterman@s141.Millennium.Berkeley.EDU>
Tue, 10 Aug 2010 03:51:44 +0000 (20:51 -0700)
committerAndrew Waterman <waterman@s141.Millennium.Berkeley.EDU>
Tue, 10 Aug 2010 03:51:44 +0000 (20:51 -0700)
The intersection of the Hauser FP and MIPS FP is implemented.

88 files changed:
configure
configure.ac
riscv/decode.h
riscv/execute.h
riscv/insns/add_d.h
riscv/insns/add_s.h
riscv/insns/c_eq_d.h [new file with mode: 0644]
riscv/insns/c_eq_fmt.h [deleted file]
riscv/insns/c_eq_s.h [new file with mode: 0644]
riscv/insns/c_f_fmt.h [deleted file]
riscv/insns/c_le_d.h [new file with mode: 0644]
riscv/insns/c_le_fmt.h [deleted file]
riscv/insns/c_le_s.h [new file with mode: 0644]
riscv/insns/c_lt_d.h [new file with mode: 0644]
riscv/insns/c_lt_fmt.h [deleted file]
riscv/insns/c_lt_s.h [new file with mode: 0644]
riscv/insns/c_nge_fmt.h [deleted file]
riscv/insns/c_ngl_fmt.h [deleted file]
riscv/insns/c_ngle_fmt.h [deleted file]
riscv/insns/c_ngt_fmt.h [deleted file]
riscv/insns/c_ole_fmt.h [deleted file]
riscv/insns/c_olt_fmt.h [deleted file]
riscv/insns/c_seq_fmt.h [deleted file]
riscv/insns/c_sf_fmt.h [deleted file]
riscv/insns/c_ueq_fmt.h [deleted file]
riscv/insns/c_ule_fmt.h [deleted file]
riscv/insns/c_ult_fmt.h [deleted file]
riscv/insns/c_un_fmt.h [deleted file]
riscv/insns/ceil_l_fmt.h [deleted file]
riscv/insns/ceil_w_fmt.h [deleted file]
riscv/insns/cvt_d_fmt.h [deleted file]
riscv/insns/cvt_d_l.h [new file with mode: 0644]
riscv/insns/cvt_d_s.h [new file with mode: 0644]
riscv/insns/cvt_d_w.h [new file with mode: 0644]
riscv/insns/cvt_l_fmt.h [deleted file]
riscv/insns/cvt_s_d.h [new file with mode: 0644]
riscv/insns/cvt_s_fmt.h [deleted file]
riscv/insns/cvt_s_l.h [new file with mode: 0644]
riscv/insns/cvt_s_w.h [new file with mode: 0644]
riscv/insns/cvt_w_fmt.h [deleted file]
riscv/insns/cvtu_d_l.h [new file with mode: 0644]
riscv/insns/cvtu_d_w.h [new file with mode: 0644]
riscv/insns/cvtu_s_l.h [new file with mode: 0644]
riscv/insns/cvtu_s_w.h [new file with mode: 0644]
riscv/insns/div_d.h
riscv/insns/div_s.h
riscv/insns/floor_l_fmt.h [deleted file]
riscv/insns/floor_w_fmt.h [deleted file]
riscv/insns/l_d.h
riscv/insns/l_s.h
riscv/insns/mff_d.h
riscv/insns/mff_s.h
riscv/insns/mtf_d.h
riscv/insns/mtf_s.h
riscv/insns/mul_d.h
riscv/insns/mul_s.h
riscv/insns/round_l_fmt.h [deleted file]
riscv/insns/round_w_fmt.h [deleted file]
riscv/insns/s_d.h
riscv/insns/s_s.h
riscv/insns/sgninj_d.h
riscv/insns/sgninj_s.h
riscv/insns/sgninjn_d.h
riscv/insns/sgninjn_s.h
riscv/insns/sgnmul_d.h
riscv/insns/sgnmul_s.h
riscv/insns/sqrt_d.h
riscv/insns/sqrt_s.h
riscv/insns/sub_d.h
riscv/insns/sub_s.h
riscv/insns/trunc_l_d.h [new file with mode: 0644]
riscv/insns/trunc_l_fmt.h [deleted file]
riscv/insns/trunc_l_s.h [new file with mode: 0644]
riscv/insns/trunc_w_d.h [new file with mode: 0644]
riscv/insns/trunc_w_fmt.h [deleted file]
riscv/insns/trunc_w_s.h [new file with mode: 0644]
riscv/insns/truncu_l_d.h [new file with mode: 0644]
riscv/insns/truncu_l_s.h [new file with mode: 0644]
riscv/insns/truncu_w_d.h [new file with mode: 0644]
riscv/insns/truncu_w_s.h [new file with mode: 0644]
riscv/processor.cc
riscv/processor.h
riscv/riscv.mk.in
softfloat/softfloat-header [new file with mode: 0644]
softfloat/softfloat.ac [new file with mode: 0644]
softfloat/softfloat.c
softfloat/softfloat.cc [new file with mode: 0644]
softfloat/softfloat.h

index d6adcf26970fd0acce478a9e8197a12a7e018d14..5e9e2a394b1151e9508d81f319b950a3790ba711 100755 (executable)
--- a/configure
+++ b/configure
@@ -4124,6 +4124,51 @@ fi
 
 
 
+    # 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
 
 
@@ -4830,6 +4875,7 @@ for ac_config_target in $ac_config_targets
 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" ;;
 
index c7c3a16a4918a6db0833461604c60098d4d5c221..967e7c44f97fa7bb16ffa8e8583b661f5d5f5ca6 100644 (file)
@@ -81,7 +81,7 @@ AC_SUBST([CXXFLAGS],["-Wall -O2"])
 # 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
index 7bdfb1895e88e3474cfbced026271fdb21173dde..424ad7fdfe85fbe6ec6f9c063e0f74238f7634ae 100644 (file)
@@ -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)
 {
index ad655ac3d3951d9876ed8e8d71231d3c6ff7b53a..f5b83af9897e27b815646523f0295f4afab007a4 100644 (file)
@@ -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"
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..bd0f55a9e12fedd05188bfa430a69b8e8a4304da 100644 (file)
@@ -0,0 +1,3 @@
+require_fp;
+FRC = float64_add(FRA, FRB);
+set_fp_exceptions;
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..b4f98f63355a7ffbfeec85ff9403bd00799447de 100644 (file)
@@ -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 (file)
index 0000000..4387ea3
--- /dev/null
@@ -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 (file)
index e69de29..0000000
diff --git a/riscv/insns/c_eq_s.h b/riscv/insns/c_eq_s.h
new file mode 100644 (file)
index 0000000..062fb74
--- /dev/null
@@ -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 (file)
index e69de29..0000000
diff --git a/riscv/insns/c_le_d.h b/riscv/insns/c_le_d.h
new file mode 100644 (file)
index 0000000..24ea657
--- /dev/null
@@ -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 (file)
index e69de29..0000000
diff --git a/riscv/insns/c_le_s.h b/riscv/insns/c_le_s.h
new file mode 100644 (file)
index 0000000..107622f
--- /dev/null
@@ -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 (file)
index 0000000..3d42500
--- /dev/null
@@ -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 (file)
index e69de29..0000000
diff --git a/riscv/insns/c_lt_s.h b/riscv/insns/c_lt_s.h
new file mode 100644 (file)
index 0000000..1f7a0e1
--- /dev/null
@@ -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 (file)
index e69de29..0000000
diff --git a/riscv/insns/c_ngl_fmt.h b/riscv/insns/c_ngl_fmt.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/riscv/insns/c_ngle_fmt.h b/riscv/insns/c_ngle_fmt.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/riscv/insns/c_ngt_fmt.h b/riscv/insns/c_ngt_fmt.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/riscv/insns/c_ole_fmt.h b/riscv/insns/c_ole_fmt.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/riscv/insns/c_olt_fmt.h b/riscv/insns/c_olt_fmt.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/riscv/insns/c_seq_fmt.h b/riscv/insns/c_seq_fmt.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/riscv/insns/c_sf_fmt.h b/riscv/insns/c_sf_fmt.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/riscv/insns/c_ueq_fmt.h b/riscv/insns/c_ueq_fmt.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/riscv/insns/c_ule_fmt.h b/riscv/insns/c_ule_fmt.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/riscv/insns/c_ult_fmt.h b/riscv/insns/c_ult_fmt.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/riscv/insns/c_un_fmt.h b/riscv/insns/c_un_fmt.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/riscv/insns/ceil_l_fmt.h b/riscv/insns/ceil_l_fmt.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/riscv/insns/ceil_w_fmt.h b/riscv/insns/ceil_w_fmt.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/riscv/insns/cvt_d_fmt.h b/riscv/insns/cvt_d_fmt.h
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/riscv/insns/cvt_d_l.h b/riscv/insns/cvt_d_l.h
new file mode 100644 (file)
index 0000000..5246f6f
--- /dev/null
@@ -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 (file)
index 0000000..481a4d1
--- /dev/null
@@ -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 (file)
index 0000000..67702a2
--- /dev/null
@@ -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 (file)
index e69de29..0000000
diff --git a/riscv/insns/cvt_s_d.h b/riscv/insns/cvt_s_d.h
new file mode 100644 (file)
index 0000000..528f11c
--- /dev/null
@@ -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 (file)
index e69de29..0000000
diff --git a/riscv/insns/cvt_s_l.h b/riscv/insns/cvt_s_l.h
new file mode 100644 (file)
index 0000000..2d1f93a
--- /dev/null
@@ -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 (file)
index 0000000..c2d583f
--- /dev/null
@@ -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 (file)
index e69de29..0000000
diff --git a/riscv/insns/cvtu_d_l.h b/riscv/insns/cvtu_d_l.h
new file mode 100644 (file)
index 0000000..5246f6f
--- /dev/null
@@ -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 (file)
index 0000000..67702a2
--- /dev/null
@@ -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 (file)
index 0000000..2d1f93a
--- /dev/null
@@ -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 (file)
index 0000000..c2d583f
--- /dev/null
@@ -0,0 +1,3 @@
+require_fp;
+FRC = int32_to_float32(FRA);
+set_fp_exceptions;
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..3b4756337f00e7cba76c24bcdc6caa6d7d71d498 100644 (file)
@@ -0,0 +1,3 @@
+require_fp;
+FRC = float64_div(FRA, FRB);
+set_fp_exceptions;
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..cb5c9bdbed74f11988cec08c88566aef38d2a7a1 100644 (file)
@@ -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 (file)
index e69de29..0000000
diff --git a/riscv/insns/floor_w_fmt.h b/riscv/insns/floor_w_fmt.h
deleted file mode 100644 (file)
index e69de29..0000000
index 279fff2f92f93765aa5289e99ca1aa2e3592534e..760cf98e44cf619473beb307226503d4ed80384f 100644 (file)
@@ -1,2 +1,2 @@
 require_fp;
-FRA.bits = mmu.load_int64(RB+SIMM);
+FRA = mmu.load_int64(RB+SIMM);
index 11cdf182ea2259d1a4f5ddeb6be7feda6559e566..1637fed438a3108ef6cdfe0ab60f7b9e7867ac55 100644 (file)
@@ -1,2 +1,2 @@
 require_fp;
-FRA.bits = mmu.load_int32(RB+SIMM);
+FRA = mmu.load_int32(RB+SIMM);
index f1bb205c45ff8d5d6823d39bc4117a45666e608a..eaece440b27eb579dd68dc00cf01a43ef0057fa6 100644 (file)
@@ -1,3 +1,3 @@
 require64;
 require_fp;
-RA = FRB.bits;
+RA = FRB;
index 9e3b9c4ce36362baa6f6620e54a08b4d316a8f1c..6233a3f5944be54ebe76f0ec2bc32c30e0dc6eed 100644 (file)
@@ -1,2 +1,2 @@
 require_fp;
-RA = sext32(FRB.bits);
+RA = sext32(FRB);
index b0eeca993e84d88a4c2b014660008bbb34ef4c7f..fcee6a1ae9d0ac2ff6dce7e71b324823873f4703 100644 (file)
@@ -1,3 +1,3 @@
 require64;
 require_fp;
-FRA.bits = RB;
+FRA = RB;
index 04f33fe3bda7d8387a9e35f0284d12e71bbb054d..a3b77376472965b2e632c21f4673d3c6db7e3740 100644 (file)
@@ -1,2 +1,2 @@
 require_fp;
-FRA.bits = RB;
+FRA = sext32(RB);
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..b2a0dbf74db784073e114baf573e6b2546aba0fd 100644 (file)
@@ -0,0 +1,3 @@
+require_fp;
+FRC = float64_mul(FRA, FRB);
+set_fp_exceptions;
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e7d4f3f3e9030d59af9853b89f9c67536cf01385 100644 (file)
@@ -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 (file)
index e69de29..0000000
diff --git a/riscv/insns/round_w_fmt.h b/riscv/insns/round_w_fmt.h
deleted file mode 100644 (file)
index e69de29..0000000
index 2d2f9c342b4c4745b77c4f3623f728f75fa1f063..d1c80377b6cebfd04e0372a5403410ebb7ef1c21 100644 (file)
@@ -1,2 +1,2 @@
 require_fp;
-mmu.store_uint64(RB+SIMM, FRA.bits);
+mmu.store_uint64(RB+SIMM, FRA);
index 6c3006ecfa7fd3fd3fb6f5deccd841f52c712e04..837c2585766655008155dd8e2f70a8db668ab0ac 100644 (file)
@@ -1,2 +1,2 @@
 require_fp;
-mmu.store_uint32(RB+SIMM, FRA.bits);
+mmu.store_uint32(RB+SIMM, FRA);
index a87ca632a171d8410ee925497d60e33d17230715..8bca56a8614b639125f03f0dbc903cb927739f31 100644 (file)
@@ -1,2 +1,2 @@
 require_fp;
-FRC.bits = (FRA.bits &~ INT64_MIN) | (FRB.bits & INT64_MIN);
+FRC = (FRA &~ INT64_MIN) | (FRB & INT64_MIN);
index db56f497f9a3cadc2a7bb118089250f1523afda4..b68817711c0ed9cf60270b5d7d8c6d7e293b4d88 100644 (file)
@@ -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);
index 5fad072d844b27cda2532d14f944106ca725b71d..c526735a3806161e1ad2339de3a46e4d50738ff7 100644 (file)
@@ -1,2 +1,2 @@
 require_fp;
-FRC.bits = (FRA.bits &~ INT64_MIN) | ((~FRB.bits) & INT64_MIN);
+FRC = (FRA &~ INT64_MIN) | ((~FRB) & INT64_MIN);
index c50967b396a73f66d9a73833e5fdad29c7ac8005..80dd7e875396276a6581b30759c4a9790c94f2b6 100644 (file)
@@ -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);
index 47d950f4db2361203ff6e6db4cd6944bc2a12dfe..c30dcea5b9d2fad8e1d557785d0d0d95e93926c1 100644 (file)
@@ -1,2 +1,2 @@
 require_fp;
-FRC.bits = FRA.bits ^ (FRB.bits & INT64_MIN);
+FRC = FRA ^ (FRB & INT64_MIN);
index 2a9ae11b354b158e1c87f60e1e088b3e9228af72..6640b3126ebe372ce4deeace18b9e6c40d612427 100644 (file)
@@ -1,2 +1,2 @@
 require_fp;
-FRC.bits = FRA.bits ^ (FRB.bits & (uint32_t)INT32_MIN);
+FRC = FRA ^ (FRB & (uint32_t)INT32_MIN);
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..3f831f545238c1edb708f0822c827f80548937eb 100644 (file)
@@ -0,0 +1,3 @@
+require_fp;
+FRC = float64_sqrt(FRA);
+set_fp_exceptions;
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..51b589200467c0da7173e806769cae58a52efc08 100644 (file)
@@ -0,0 +1,3 @@
+require_fp;
+FRC = float32_sqrt(FRA);
+set_fp_exceptions;
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..55d0e86212a4c196e5edc6f9874ad906d4d1891e 100644 (file)
@@ -0,0 +1,3 @@
+require_fp;
+FRC = float64_sub(FRA, FRB);
+set_fp_exceptions;
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..4a359bfc5a428f4a152fec47a1a110b59a22f09e 100644 (file)
@@ -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 (file)
index 0000000..ecca8cd
--- /dev/null
@@ -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 (file)
index e69de29..0000000
diff --git a/riscv/insns/trunc_l_s.h b/riscv/insns/trunc_l_s.h
new file mode 100644 (file)
index 0000000..9dd0e51
--- /dev/null
@@ -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 (file)
index 0000000..9b7cdb0
--- /dev/null
@@ -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 (file)
index e69de29..0000000
diff --git a/riscv/insns/trunc_w_s.h b/riscv/insns/trunc_w_s.h
new file mode 100644 (file)
index 0000000..147ec8b
--- /dev/null
@@ -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 (file)
index 0000000..ecca8cd
--- /dev/null
@@ -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 (file)
index 0000000..9dd0e51
--- /dev/null
@@ -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 (file)
index 0000000..9b7cdb0
--- /dev/null
@@ -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 (file)
index 0000000..147ec8b
--- /dev/null
@@ -0,0 +1,3 @@
+require_fp;
+FRC = float32_to_int32_round_to_zero(FRA);
+set_fp_exceptions;
index 5751c70006e2f2dc02d62857ea4bdbf12b14caff..7ca015d765eab95ccf58aff43de81a90aaaf3220 100644 (file)
@@ -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;
index 652fa07c6a4cc5b4ee2aaf8d06cc25f21a279140..8c64d6d04de3743b7ab655e1d92a31a906d0a180 100644 (file)
@@ -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);
 
index bd806ccdb726795233709a991de5e836dbeaa1b0..3f6427dc292bd22012f766106740ae67a4baf47d 100644 (file)
@@ -1,4 +1,4 @@
-riscv_subproject_deps =
+riscv_subproject_deps = softfloat \
 
 riscv_hdrs = \
     applink.h \
diff --git a/softfloat/softfloat-header b/softfloat/softfloat-header
new file mode 100644 (file)
index 0000000..eb5303a
--- /dev/null
@@ -0,0 +1,259 @@
+
+/*============================================================================
+
+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
+
diff --git a/softfloat/softfloat.ac b/softfloat/softfloat.ac
new file mode 100644 (file)
index 0000000..e69de29
index 3c31f0e739ab16612c6f182171330f4c68d1639e..0d09b4033afcb6de560ba46e24a024532ca8518a 100644 (file)
@@ -4909,7 +4909,7 @@ float128 float128_rem( float128 a, float128 b )
         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
diff --git a/softfloat/softfloat.cc b/softfloat/softfloat.cc
new file mode 100644 (file)
index 0000000..c44e828
--- /dev/null
@@ -0,0 +1 @@
+#include "softfloat.c"
index eb5303a0c0041a9a8a3f57280acd606054468f5d..fc3f9dc6fb5c36a7ea98cbd7283d884fa574f09e 100644 (file)
-
-/*============================================================================
-
-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
-