fixed and cleaned up fp support, optimisation yet to come
authorjohanknol <johanknol@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sat, 10 Nov 2001 17:50:51 +0000 (17:50 +0000)
committerjohanknol <johanknol@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sat, 10 Nov 2001 17:50:51 +0000 (17:50 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@1556 4a8a32a2-be11-0410-ad9d-d568d2c75423

21 files changed:
device/include/float.h
device/lib/_fs2schar.c
device/lib/_fs2sint.c
device/lib/_fs2slong.c
device/lib/_fs2uchar.c
device/lib/_fs2uint.c
device/lib/_fs2ulong.c
device/lib/_fsadd.c
device/lib/_fsdiv.c
device/lib/_fseq.c
device/lib/_fsgt.c
device/lib/_fslt.c
device/lib/_fsmul.c
device/lib/_fsneq.c
device/lib/_fssub.c
device/lib/_schar2fs.c
device/lib/_sint2fs.c
device/lib/_slong2fs.c
device/lib/_uchar2fs.c
device/lib/_uint2fs.c
device/lib/_ulong2fs.c

index f76ba54c0af5780f27a3e2f6affafa989c2f70e3..328fccd89615195e043b7b8d75dcfb807da30146 100644 (file)
@@ -24,6 +24,9 @@
 
 #ifndef __SDC51_FLOAT_H
 #define __SDC51_FLOAT_H 1
+
+#include <limits.h>
+
 #define FLT_RADIX       2
 #define FLT_MANT_DIG    24
 #define FLT_EPSILON     1.192092896E-07F
 #define FLT_MAX         3.402823466E+38F
 #define FLT_MAX_10_EXP  (+38)
 
+/* the following deal with IEEE single-precision numbers */
+#define EXCESS         126
+#define SIGNBIT                ((unsigned long)0x80000000)
+#define HIDDEN         (unsigned long)(1 << 23)
+#define SIGN(fp)       ((fp >> (8*sizeof(fp)-1)) & 1)
+#define EXP(fp)                (((fp) >> 23) & (unsigned int) 0x00FF)
+#define MANT(fp)       (((fp) & (unsigned long)0x007FFFFF) | HIDDEN)
+#define NORM            0xff000000
+#define PACK(s,e,m)    ((s) | ((e) << 23) | (m))
+
+float _uchar2fs (unsigned char);
+float _schar2fs (signed char);
+float _uint2fs (unsigned int);
+float _sint2fs (signed int);
+float _ulong2fs (unsigned long);
+float _slong2fs (signed long);
+unsigned char _fs2uchar (float);
+signed char _fs2schar (float);
+unsigned int _fs2uint (float);
+signed int _fs2sint (float);
+unsigned long _fs2ulong (float);
+signed long _fs2slong (float);
+
+float _fsadd (float, float);
+float _fssub (float, float);
+float _fsmul (float, float);
+float _fsdiv (float, float);
+
+char _fslt (float, float);
+char _fseq (float, float);
+char _fsqt (float, float);
+
 #endif
 
 
index b783ea595d71da2a64e064a16c47e724c3a8abe9..8ccf1ebd4db58848b5976677a8c6e81e0cb3ddb1 100644 (file)
@@ -1,6 +1,4 @@
-#include <limits.h>
-
-signed long __fs2slong (float f);
+#include <float.h>
 
 /* convert float to signed char */
 signed char __fs2schar (float f) {
index dd49c4e799974e27c66d10f876cac8cb1d23f539..78c179838f39071ce3e6eab383400e39e925c744 100644 (file)
@@ -1,6 +1,4 @@
-#include <limits.h>
-
-signed long __fs2slong (float f);
+#include <float.h>
 
 /* convert float to signed int */
 signed int __fs2sint (float f) {
index 1c3aec8c8f7d49a2dee2042d9256972010a14819..236ef878789d91600cf3be43e5d70236c4d3680e 100644 (file)
@@ -1,6 +1,4 @@
-#include <limits.h>
-
-unsigned long __fs2ulong (float a1);
+#include <float.h>
 
 /* convert float to signed long */
 signed long __fs2slong (float f) {
@@ -9,12 +7,8 @@ signed long __fs2slong (float f) {
     return 0;
 
   if (f<0) {
-    if (f<=LONG_MIN)
-      return LONG_MIN;
     return -__fs2ulong(-f);
   } else {
-    if (f>=LONG_MAX)
-      return LONG_MAX;
     return __fs2ulong(f);
   }
 }
index 68e4c6799df0ea114254b44b37f3eb232c998222..ce4a927203ea58cd805b023b4a76ddf822224c10 100644 (file)
@@ -1,6 +1,4 @@
-#include <limits.h>
-
-unsigned long __fs2ulong (float a1);
+#include <float.h>
 
 /* convert float to unsigned char */
 unsigned char __fs2uchar (float f) {
index 464a729e24649d5ba08588506695b78fee8d8899..186b7f37a9e7f21797b61e75c5cac4717d1206b2 100644 (file)
@@ -1,4 +1,4 @@
-#include <limits.h>
+#include <float.h>
 
 unsigned long __fs2ulong (float a1);
 
index 01f55a49cb259ad3075fcf940acc66d9e0f277a7..0b7461435b163c45e7afaba146c0d8f0ee4cd2bc 100644 (file)
 ** uunet!motown!pipeline!phw
 */
 
-/* (c)2000: hacked a little by johan.knol@iduna.nl for sdcc */
+/* (c)2000/2001: hacked a little by johan.knol@iduna.nl for sdcc */
 
-#include <limits.h>
-
-/* the following deal with IEEE single-precision numbers */
-#define EXCESS         126
-#define SIGNBIT                ((unsigned long)0x80000000)
-#define HIDDEN         (unsigned long)(1 << 23)
-#define SIGN(fp)       ((fp >> (8*sizeof(fp)-1)) & 1)
-#define EXP(fp)                (((fp) >> 23) & (unsigned int) 0x00FF)
-#define MANT(fp)       (((fp) & (unsigned long) 0x007FFFFF) | HIDDEN)
-#define PACK(s,e,m)    ((s) | ((e) << 23) | (m))
+#include <float.h>
 
 union float_long
 {
@@ -46,9 +37,6 @@ __fs2ulong (float a1)
   if (!fl1.l || SIGN(fl1.l))
     return (0);
 
-  if (a1>=ULONG_MAX)
-    return ULONG_MAX;
-
   exp = EXP (fl1.l) - EXCESS - 24;
   l = MANT (fl1.l);
   
index a4273d9abbdb5aaec208bf5535247c0117b3b639..fa0970ae45c2abafef3c4a371622c61e8574cb45 100644 (file)
@@ -1,20 +1,31 @@
-/* the following deal with IEEE single-precision numbers */
-#define EXCESS          126
-#define SIGNBIT         ((unsigned long)0x80000000)
-#define HIDDEN          (unsigned long)(1 << 23)
-#define SIGN(fp)        ((fp >> (8*sizeof(fp)-1)) & 1) 
-#define EXP(fp)         (((fp) >> 23) & (unsigned int)0x00FF)
-#define MANT(fp)        (((fp) & (unsigned long)0x007FFFFF) | HIDDEN)
-#define PACK(s,e,m)     ((s) | ((e) << 23) | (m))
+/*
+** libgcc support for software floating point.
+** Copyright (C) 1991 by Pipeline Associates, Inc.  All rights reserved.
+** Permission is granted to do *anything* you want with this file,
+** commercial or otherwise, provided this message remains intact.  So there!
+** I would appreciate receiving any updates/patches/changes that anyone
+** makes, and am willing to be the repository for said changes (am I
+** making a big mistake?).
+**
+** Pat Wood
+** Pipeline Associates, Inc.
+** pipeline!phw@motown.com or
+** sun!pipeline!phw or
+** uunet!motown!pipeline!phw
+*/
+
+/* (c)2000/2001: hacked a little by johan.knol@iduna.nl for sdcc */
+
+#include <float.h>
 
 union float_long
   {
     float f;
-    long l;
+    unsigned long l;
   };
+
 /* add two floats */
-float
-__fsadd (float a1, float a2)
+float __fsadd (float a1, float a2)
 {
   volatile long mant1, mant2;
   volatile union float_long fl1, fl2;
@@ -38,9 +49,8 @@ __fsadd (float a1, float a2)
   if (exp2 > exp1 + 25)
     return (fl2.f);
 
-  /* do everything in excess precision so's we can round later */
-  mant1 = MANT (fl1.l) << 6;
-  mant2 = MANT (fl2.l) << 6;
+  mant1 = MANT (fl1.l);
+  mant2 = MANT (fl2.l);
 
   if (SIGN (fl1.l))
     mant1 = -mant1;
@@ -66,37 +76,27 @@ __fsadd (float a1, float a2)
   else if (!mant1)
     return (0);
 
-  /* normalize up */
-  while (!((unsigned long)mant1 & (unsigned long) 0xE0000000))
-    {
-      mant1 <<= 1;
-      exp1--;
-    }
-
-  /* normalize down? */
-  if ((unsigned long)mant1 & (unsigned long)(1 << 30))
-    {
-      mant1 >>= 1 ;
-      exp1++;
-    }
-
-  /* round to even */
-  mant1 += (mant1 & (unsigned long)0x40) ? (unsigned long) 0x20 : (unsigned long) 0x1F;
-
-  /* normalize down? */
-  if (mant1 & (unsigned long)(1 << 30))
-    {
-      mant1 >>= 1;
-      exp1++;
-    }
-
-  /* lose extra precision */
-  mant1 >>= 6;
+  /* normalize */
+  /* jwk: TODO: changing the next two whiles in nested ifs 
+     seriously breaks it. Why?????????????????? */ 
+  while (mant1<HIDDEN) {
+    mant1 <<= 1;
+    exp1--;
+  }
+
+  while (mant1 & 0xff000000) {
+    // round off
+    if (mant1&1)
+      mant1 += 2;
+    mant1 >>= 1 ;
+    exp1++;
+  }
 
   /* turn off hidden bit */
-  mant1 = (unsigned long)mant1 & ~HIDDEN;
+  mant1 &= ~HIDDEN;
 
   /* pack up and go home */
   fl1.l = PACK (sign, (unsigned long) exp1, mant1);
+
   return (fl1.f);
 }
index f597027f167c7bbffaef119fc356ec91fd931080..93a5f86d43f79574e62ac73effc2ba449cd9d309 100644 (file)
@@ -6,61 +6,17 @@
 ** I would appreciate receiving any updates/patches/changes that anyone
 ** makes, and am willing to be the repository for said changes (am I
 ** making a big mistake?).
-
-Warning! Only single-precision is actually implemented.  This file
-won't really be much use until double-precision is supported.
-
-However, once that is done, this file might eventually become a
-replacement for libgcc1.c.  It might also make possible
-cross-compilation for an IEEE target machine from a non-IEEE
-host such as a VAX.
-
-If you'd like to work on completing this, please talk to rms@gnu.ai.mit.edu.
-
-
 **
 ** Pat Wood
 ** Pipeline Associates, Inc.
 ** pipeline!phw@motown.com or
 ** sun!pipeline!phw or
 ** uunet!motown!pipeline!phw
-**
-** 05/01/91 -- V1.0 -- first release to gcc mailing lists
-** 05/04/91 -- V1.1 -- added float and double prototypes and return values
-**                  -- fixed problems with adding and subtracting zero
-**                  -- fixed rounding in truncdfsf2
-**                  -- fixed SWAP define and tested on 386
 */
 
-/*
-** The following are routines that replace the libgcc soft floating point
-** routines that are called automatically when -msoft-float is selected.
-** The support single and double precision IEEE format, with provisions
-** for byte-swapped machines (tested on 386).  Some of the double-precision
-** routines work at full precision, but most of the hard ones simply punt
-** and call the single precision routines, producing a loss of accuracy.
-** long long support is not assumed or included.
-** Overall accuracy is close to IEEE (actually 68882) for single-precision
-** arithmetic.  I think there may still be a 1 in 1000 chance of a bit
-** being rounded the wrong way during a multiply.  I'm not fussy enough to
-** bother with it, but if anyone is, knock yourself out.
-**
-** Efficiency has only been addressed where it was obvious that something
-** would make a big difference.  Anyone who wants to do this right for
-** best speed should go in and rewrite in assembler.
-**
-** I have tested this only on a 68030 workstation and 386/ix integrated
-** in with -msoft-float.
-*/
+/* (c)2000/2001: hacked a little by johan.knol@iduna.nl for sdcc */
 
-/* the following deal with IEEE single-precision numbers */
-#define EXCESS         126
-#define SIGNBIT                ((unsigned long)0x80000000)
-#define HIDDEN         (unsigned long)(1 << 23)
-#define SIGN(fp)       ((fp >> (8*sizeof(fp)-1)) & 1)
-#define EXP(fp)                (((fp) >> 23) & (unsigned int)0x00FF)
-#define MANT(fp)       (((fp) & (unsigned long)0x007FFFFF) | HIDDEN)
-#define PACK(s,e,m)    ((s) | ((e) << 23) | (m))
+#include <float.h>
 
 union float_long
   {
@@ -69,8 +25,7 @@ union float_long
   };
 
 /* divide two floats */
-float
-__fsdiv (float a1, float a2)
+float __fsdiv (float a1, float a2)
 {
   volatile union float_long fl1, fl2;
   volatile long result;
@@ -134,6 +89,7 @@ __fsdiv (float a1, float a2)
   result &= ~HIDDEN;
 
   /* pack up and go home */
-  fl1.l = PACK (sign, (unsigned long) exp, result);
+  fl1.l = PACK (sign ? 1<<31 : 0, (unsigned long) exp, result);
   return (fl1.f);
 }
+
index fd2e8fe72545c2e8bc71e0765149aed08730843f..b73cd060f76c598fc177f91c4db0eb55bade3b87 100644 (file)
@@ -6,61 +6,17 @@
 ** I would appreciate receiving any updates/patches/changes that anyone
 ** makes, and am willing to be the repository for said changes (am I
 ** making a big mistake?).
-
-Warning! Only single-precision is actually implemented.  This file
-won't really be much use until double-precision is supported.
-
-However, once that is done, this file might eventually become a
-replacement for libgcc1.c.  It might also make possible
-cross-compilation for an IEEE target machine from a non-IEEE
-host such as a VAX.
-
-If you'd like to work on completing this, please talk to rms@gnu.ai.mit.edu.
-
-
 **
 ** Pat Wood
 ** Pipeline Associates, Inc.
 ** pipeline!phw@motown.com or
 ** sun!pipeline!phw or
 ** uunet!motown!pipeline!phw
-**
-** 05/01/91 -- V1.0 -- first release to gcc mailing lists
-** 05/04/91 -- V1.1 -- added float and double prototypes and return values
-**                  -- fixed problems with adding and subtracting zero
-**                  -- fixed rounding in truncdfsf2
-**                  -- fixed SWAP define and tested on 386
 */
 
-/*
-** The following are routines that replace the libgcc soft floating point
-** routines that are called automatically when -msoft-float is selected.
-** The support single and double precision IEEE format, with provisions
-** for byte-swapped machines (tested on 386).  Some of the double-precision
-** routines work at full precision, but most of the hard ones simply punt
-** and call the single precision routines, producing a loss of accuracy.
-** long long support is not assumed or included.
-** Overall accuracy is close to IEEE (actually 68882) for single-precision
-** arithmetic.  I think there may still be a 1 in 1000 chance of a bit
-** being rounded the wrong way during a multiply.  I'm not fussy enough to
-** bother with it, but if anyone is, knock yourself out.
-**
-** Efficiency has only been addressed where it was obvious that something
-** would make a big difference.  Anyone who wants to do this right for
-** best speed should go in and rewrite in assembler.
-**
-** I have tested this only on a 68030 workstation and 386/ix integrated
-** in with -msoft-float.
-*/
+/* (c)2000/2001: hacked a little by johan.knol@iduna.nl for sdcc */
 
-/* the following deal with IEEE single-precision numbers */
-#define EXCESS         126
-#define SIGNBIT                ((unsigned long)0x80000000)
-#define HIDDEN         (unsgined long)(1 << 23)
-#define SIGN(fp)       ((fp >> (8*sizeof(fp)-1)) & 1)
-#define EXP(fp)                (((fp) >> 23) & (unsigned int)0x00FF)
-#define MANT(fp)       (((fp) & (unsigned long)0x007FFFFF) | HIDDEN)
-#define PACK(s,e,m)    ((s) | ((e) << 23) | (m))
+#include <float.h>
 
 union float_long
   {
@@ -77,12 +33,8 @@ __fseq (float a1, float a2)
   fl1.f = a1;
   fl2.f = a2;
 
-  if (SIGN (fl1.l) && SIGN (fl2.l))
-    {
-      fl1.l ^= SIGNBIT;
-      fl2.l ^= SIGNBIT;
-    }
   if (fl1.l == fl2.l)
     return (1);
   return (0);
 }
+
index 106df0c0b5532e8002ab57d6d9d0cf7a60cbd896..2fbbda2772631328ccd14e63e99e30d9ad05d391 100644 (file)
@@ -6,61 +6,17 @@
 ** I would appreciate receiving any updates/patches/changes that anyone
 ** makes, and am willing to be the repository for said changes (am I
 ** making a big mistake?).
-
-Warning! Only single-precision is actually implemented.  This file
-won't really be much use until double-precision is supported.
-
-However, once that is done, this file might eventually become a
-replacement for libgcc1.c.  It might also make possible
-cross-compilation for an IEEE target machine from a non-IEEE
-host such as a VAX.
-
-If you'd like to work on completing this, please talk to rms@gnu.ai.mit.edu.
-
-
 **
 ** Pat Wood
 ** Pipeline Associates, Inc.
 ** pipeline!phw@motown.com or
 ** sun!pipeline!phw or
 ** uunet!motown!pipeline!phw
-**
-** 05/01/91 -- V1.0 -- first release to gcc mailing lists
-** 05/04/91 -- V1.1 -- added float and double prototypes and return values
-**                  -- fixed problems with adding and subtracting zero
-**                  -- fixed rounding in truncdfsf2
-**                  -- fixed SWAP define and tested on 386
 */
 
-/*
-** The following are routines that replace the libgcc soft floating point
-** routines that are called automatically when -msoft-float is selected.
-** The support single and double precision IEEE format, with provisions
-** for byte-swapped machines (tested on 386).  Some of the double-precision
-** routines work at full precision, but most of the hard ones simply punt
-** and call the single precision routines, producing a loss of accuracy.
-** long long support is not assumed or included.
-** Overall accuracy is close to IEEE (actually 68882) for single-precision
-** arithmetic.  I think there may still be a 1 in 1000 chance of a bit
-** being rounded the wrong way during a multiply.  I'm not fussy enough to
-** bother with it, but if anyone is, knock yourself out.
-**
-** Efficiency has only been addressed where it was obvious that something
-** would make a big difference.  Anyone who wants to do this right for
-** best speed should go in and rewrite in assembler.
-**
-** I have tested this only on a 68030 workstation and 386/ix integrated
-** in with -msoft-float.
-*/
+/* (c)2000/2001: hacked a little by johan.knol@iduna.nl for sdcc */
 
-/* the following deal with IEEE single-precision numbers */
-#define EXCESS         126
-#define SIGNBIT                ((unsigned long)0x80000000)
-#define HIDDEN         (unsigned long)(1 << 23)
-#define SIGN(fp)       ((fp >> (8*sizeof(fp)-1)) & 1)
-#define EXP(fp)                (((fp) >> 23) & (unsigned int) 0x00FF)
-#define MANT(fp)       (((fp) & (unsigned long) 0x007FFFFF) | HIDDEN)
-#define PACK(s,e,m)    ((s) | ((e) << 23) | (m))
+#include <float.h>
 
 union float_long
   {
@@ -69,15 +25,14 @@ union float_long
   };
 
 /* compare two floats */
-char
-__fsgt (float a1, float a2)
+char __fsgt (float a1, float a2)
 {
   volatile union float_long fl1, fl2;
 
   fl1.f = a1;
   fl2.f = a2;
 
-  if (SIGN (fl1.l) && SIGN (fl2.l))
+  if (fl1.l<0 && fl2.l<0)
     {
       fl1.l ^= SIGNBIT;
       fl2.l ^= SIGNBIT;
index e22a5eadc5e4c7612777b231b18ce590b37363f9..2e55f83afceffecdcf4226d29917e74ae771ac76 100644 (file)
@@ -6,61 +6,17 @@
 ** I would appreciate receiving any updates/patches/changes that anyone
 ** makes, and am willing to be the repository for said changes (am I
 ** making a big mistake?).
-
-Warning! Only single-precision is actually implemented.  This file
-won't really be much use until double-precision is supported.
-
-However, once that is done, this file might eventually become a
-replacement for libgcc1.c.  It might also make possible
-cross-compilation for an IEEE target machine from a non-IEEE
-host such as a VAX.
-
-If you'd like to work on completing this, please talk to rms@gnu.ai.mit.edu.
-
-
 **
 ** Pat Wood
 ** Pipeline Associates, Inc.
 ** pipeline!phw@motown.com or
 ** sun!pipeline!phw or
 ** uunet!motown!pipeline!phw
-**
-** 05/01/91 -- V1.0 -- first release to gcc mailing lists
-** 05/04/91 -- V1.1 -- added float and double prototypes and return values
-**                  -- fixed problems with adding and subtracting zero
-**                  -- fixed rounding in truncdfsf2
-**                  -- fixed SWAP define and tested on 386
 */
 
-/*
-** The following are routines that replace the libgcc soft floating point
-** routines that are called automatically when -msoft-float is selected.
-** The support single and double precision IEEE format, with provisions
-** for byte-swapped machines (tested on 386).  Some of the double-precision
-** routines work at full precision, but most of the hard ones simply punt
-** and call the single precision routines, producing a loss of accuracy.
-** long long support is not assumed or included.
-** Overall accuracy is close to IEEE (actually 68882) for single-precision
-** arithmetic.  I think there may still be a 1 in 1000 chance of a bit
-** being rounded the wrong way during a multiply.  I'm not fussy enough to
-** bother with it, but if anyone is, knock yourself out.
-**
-** Efficiency has only been addressed where it was obvious that something
-** would make a big difference.  Anyone who wants to do this right for
-** best speed should go in and rewrite in assembler.
-**
-** I have tested this only on a 68030 workstation and 386/ix integrated
-** in with -msoft-float.
-*/
+/* (c)2000/2001: hacked a little by johan.knol@iduna.nl for sdcc */
 
-/* the following deal with IEEE single-precision numbers */
-#define EXCESS         126
-#define SIGNBIT                ((unsigned long)0x80000000)
-#define HIDDEN         (unsgined long)(1 << 23)
-#define SIGN(fp)       ((fp >> (8*sizeof(fp)-1)) & 1)
-#define EXP(fp)                (((fp) >> 23) & (unsigned int)0x00FF)
-#define MANT(fp)       (((fp) & (unsigned long)0x007FFFFF) | HIDDEN)
-#define PACK(s,e,m)    ((s) | ((e) << 23) | (m))
+#include <float.h>
 
 union float_long
   {
@@ -69,15 +25,14 @@ union float_long
   };
 
 /* compare two floats */
-char
-__fslt (float a1, float a2)
+char __fslt (float a1, float a2)
 {
   volatile union float_long fl1, fl2;
 
   fl1.f = a1;
   fl2.f = a2;
 
-  if (SIGN (fl1.l) && SIGN (fl2.l))
+  if (fl1.l<0 && fl2.l<0)
     {
       fl1.l ^= SIGNBIT;
       fl2.l ^= SIGNBIT;
index c15078111cf6432c7b2ddf63e8a8fa53d91fbd44..09fd00a4fdba9092114e4d52538f139a366be3da 100644 (file)
@@ -6,85 +6,31 @@
 ** I would appreciate receiving any updates/patches/changes that anyone
 ** makes, and am willing to be the repository for said changes (am I
 ** making a big mistake?).
-
-Warning! Only single-precision is actually implemented.  This file
-won't really be much use until double-precision is supported.
-
-However, once that is done, this file might eventually become a
-replacement for libgcc1.c.  It might also make possible
-cross-compilation for an IEEE target machine from a non-IEEE
-host such as a VAX.
-
-If you'd like to work on completing this, please talk to rms@gnu.ai.mit.edu.
-
-
 **
 ** Pat Wood
 ** Pipeline Associates, Inc.
 ** pipeline!phw@motown.com or
 ** sun!pipeline!phw or
 ** uunet!motown!pipeline!phw
-**
-** 05/01/91 -- V1.0 -- first release to gcc mailing lists
-** 05/04/91 -- V1.1 -- added float and double prototypes and return values
-**                  -- fixed problems with adding and subtracting zero
-**                  -- fixed rounding in truncdfsf2
-**                  -- fixed SWAP define and tested on 386
-*/
-
-/*
-** The following are routines that replace the libgcc soft floating point
-** routines that are called automatically when -msoft-float is selected.
-** The support single and double precision IEEE format, with provisions
-** for byte-swapped machines (tested on 386).  Some of the double-precision
-** routines work at full precision, but most of the hard ones simply punt
-** and call the single precision routines, producing a loss of accuracy.
-** long long support is not assumed or included.
-** Overall accuracy is close to IEEE (actually 68882) for single-precision
-** arithmetic.  I think there may still be a 1 in 1000 chance of a bit
-** being rounded the wrong way during a multiply.  I'm not fussy enough to
-** bother with it, but if anyone is, knock yourself out.
-**
-** Efficiency has only been addressed where it was obvious that something
-** would make a big difference.  Anyone who wants to do this right for
-** best speed should go in and rewrite in assembler.
-**
-** I have tested this only on a 68030 workstation and 386/ix integrated
-** in with -msoft-float.
 */
 
-/* the following deal with IEEE single-precision numbers */
-#define EXCESS         126
-#define SIGNBIT                ((unsigned long)0x80000000)
-#define HIDDEN         (unsigned long)(1 << 23)
-#define SIGN(fp)       ((fp >> (8*sizeof(fp)-1)) & 1)
-#define EXP(fp)                (((fp) >> 23) & (unsigned int) 0x00FF)
-#define MANT(fp)       (((fp) & (unsigned long)0x007FFFFF) | HIDDEN)
-#define PACK(s,e,m)    ((s) | ((e) << 23) | (m))
+/* (c)2000/2001: hacked a little by johan.knol@iduna.nl for sdcc */
 
-/* the following deal with IEEE double-precision numbers */
-#define EXCESSD                1022
-#define HIDDEND                (1 << 20)
-#define EXPD(fp)       (((fp.l.upper) >> 20) & 0x7FF)
-#define SIGND(fp)      ((fp.l.upper) & SIGNBIT)
-#define MANTD(fp)      (((((fp.l.upper) & 0xFFFFF) | HIDDEND) << 10) | \
-                               (fp.l.lower >> 22))
+#include <float.h>
 
 union float_long
   {
     float f;
-    long l;
+    unsigned long l;
   };
 
 /* multiply two floats */
-float
-__fsmul (float a1, float a2)
-{
+float __fsmul (float a1, float a2) {
   volatile union float_long fl1, fl2;
   volatile unsigned long result;
   volatile int exp;
   char sign;
-
+  
   fl1.f = a1;
   fl2.f = a2;
 
@@ -104,7 +50,7 @@ __fsmul (float a1, float a2)
   result += ((fl1.l & (unsigned long) 0xFF) * (fl2.l >> 8)) >> 8;
   result += ((fl2.l & (unsigned long) 0xFF) * (fl1.l >> 8)) >> 8;
 
-  if (result & (unsigned long)0x80000000)
+  if (result & SIGNBIT)
     {
       /* round */
       result += 0x80;
@@ -121,6 +67,10 @@ __fsmul (float a1, float a2)
   result &= ~HIDDEN;
 
   /* pack up and go home */
-  fl1.l = PACK (sign ? ((unsigned long) 0x80000000) : 0 , (unsigned long)exp, result);  
+  fl1.l = PACK (sign ? SIGNBIT : 0 , (unsigned long)exp, result);  
   return (fl1.f);
 }
+
+
+
+
index 8d74dee7451efda8e9e7f962e7740950fd5c3f80..1d23ed38dc736144b6d5d8d72d5567ba41f276a6 100644 (file)
@@ -6,61 +6,17 @@
 ** I would appreciate receiving any updates/patches/changes that anyone
 ** makes, and am willing to be the repository for said changes (am I
 ** making a big mistake?).
-
-Warning! Only single-precision is actually implemented.  This file
-won't really be much use until double-precision is supported.
-
-However, once that is done, this file might eventually become a
-replacement for libgcc1.c.  It might also make possible
-cross-compilation for an IEEE target machine from a non-IEEE
-host such as a VAX.
-
-If you'd like to work on completing this, please talk to rms@gnu.ai.mit.edu.
-
-
 **
 ** Pat Wood
 ** Pipeline Associates, Inc.
 ** pipeline!phw@motown.com or
 ** sun!pipeline!phw or
 ** uunet!motown!pipeline!phw
-**
-** 05/01/91 -- V1.0 -- first release to gcc mailing lists
-** 05/04/91 -- V1.1 -- added float and double prototypes and return values
-**                  -- fixed problems with adding and subtracting zero
-**                  -- fixed rounding in truncdfsf2
-**                  -- fixed SWAP define and tested on 386
 */
 
-/*
-** The following are routines that replace the libgcc soft floating point
-** routines that are called automatically when -msoft-float is selected.
-** The support single and double precision IEEE format, with provisions
-** for byte-swapped machines (tested on 386).  Some of the double-precision
-** routines work at full precision, but most of the hard ones simply punt
-** and call the single precision routines, producing a loss of accuracy.
-** long long support is not assumed or included.
-** Overall accuracy is close to IEEE (actually 68882) for single-precision
-** arithmetic.  I think there may still be a 1 in 1000 chance of a bit
-** being rounded the wrong way during a multiply.  I'm not fussy enough to
-** bother with it, but if anyone is, knock yourself out.
-**
-** Efficiency has only been addressed where it was obvious that something
-** would make a big difference.  Anyone who wants to do this right for
-** best speed should go in and rewrite in assembler.
-**
-** I have tested this only on a 68030 workstation and 386/ix integrated
-** in with -msoft-float.
-*/
+/* (c)2000/2001: hacked a little by johan.knol@iduna.nl for sdcc */
 
-/* the following deal with IEEE single-precision numbers */
-#define EXCESS         126
-#define SIGNBIT                ((unsigned long)0x80000000)
-#define HIDDEN         (unsigned long)(1 << 23)
-#define SIGN(fp)       ((fp >> (8*sizeof(fp)-1)) & 1)
-#define EXP(fp)                (((fp) >> 23) & (unsigned int) 0x00FF)
-#define MANT(fp)       (((fp) & (unsigned long) 0x007FFFFF) | HIDDEN)
-#define PACK(s,e,m)    ((s) | ((e) << 23) | (m))
+#include <float.h>
 
 union float_long
   {
@@ -69,15 +25,14 @@ union float_long
   };
 
 /* compare two floats */
-char
-__fsneq (float a1, float a2)
+char __fsneq (float a1, float a2)
 {
   volatile union float_long fl1, fl2;
 
   fl1.f = a1;
   fl2.f = a2;
 
-  if (SIGN (fl1.l) && SIGN (fl2.l))
+  if (fl1.l<0 && fl2.l<0)
     {
       fl1.l ^= SIGNBIT;
       fl2.l ^= SIGNBIT;
index 43e10b29ee4943b1d99d533d7b263821e3dd789c..b9f453fb3a1d38ea7b8277929965ff232fa44201 100644 (file)
@@ -6,69 +6,17 @@
 ** I would appreciate receiving any updates/patches/changes that anyone
 ** makes, and am willing to be the repository for said changes (am I
 ** making a big mistake?).
-
-Warning! Only single-precision is actually implemented.  This file
-won't really be much use until double-precision is supported.
-
-However, once that is done, this file might eventually become a
-replacement for libgcc1.c.  It might also make possible
-cross-compilation for an IEEE target machine from a non-IEEE
-host such as a VAX.
-
-If you'd like to work on completing this, please talk to rms@gnu.ai.mit.edu.
-
-
 **
 ** Pat Wood
 ** Pipeline Associates, Inc.
 ** pipeline!phw@motown.com or
 ** sun!pipeline!phw or
 ** uunet!motown!pipeline!phw
-**
-** 05/01/91 -- V1.0 -- first release to gcc mailing lists
-** 05/04/91 -- V1.1 -- added float and double prototypes and return values
-**                  -- fixed problems with adding and subtracting zero
-**                  -- fixed rounding in truncdfsf2
-**                  -- fixed SWAP define and tested on 386
-*/
-
-/*
-** The following are routines that replace the libgcc soft floating point
-** routines that are called automatically when -msoft-float is selected.
-** The support single and double precision IEEE format, with provisions
-** for byte-swapped machines (tested on 386).  Some of the double-precision
-** routines work at full precision, but most of the hard ones simply punt
-** and call the single precision routines, producing a loss of accuracy.
-** long long support is not assumed or included.
-** Overall accuracy is close to IEEE (actually 68882) for single-precision
-** arithmetic.  I think there may still be a 1 in 1000 chance of a bit
-** being rounded the wrong way during a multiply.  I'm not fussy enough to
-** bother with it, but if anyone is, knock yourself out.
-**
-** Efficiency has only been addressed where it was obvious that something
-** would make a big difference.  Anyone who wants to do this right for
-** best speed should go in and rewrite in assembler.
-**
-** I have tested this only on a 68030 workstation and 386/ix integrated
-** in with -msoft-float.
 */
 
-/* the following deal with IEEE single-precision numbers */
-#define EXCESS         126
-#define SIGNBIT                ((unsigned long)0x80000000)
-#define HIDDEN         (unsigned long)(1 << 23)
-#define SIGN(fp)       ((fp) & SIGNBIT)
-#define EXP(fp)                (((fp) >> 23) & (unsigned int) 0x00FF)
-#define MANT(fp)       (((fp) & (unsigned long) 0x007FFFFF) | HIDDEN)
-#define PACK(s,e,m)    ((s) | ((e) << 23) | (m))
+/* (c)2000/2001: hacked a little by johan.knol@iduna.nl for sdcc */
 
-/* the following deal with IEEE double-precision numbers */
-#define EXCESSD                1022
-#define HIDDEND                (1 << 20)
-#define EXPD(fp)       (((fp.l.upper) >> 20) & 0x7FF)
-#define SIGND(fp)      ((fp.l.upper) & SIGNBIT)
-#define MANTD(fp)      (((((fp.l.upper) & 0xFFFFF) | HIDDEND) << 10) | \
-                               (fp.l.lower >> 22))
+#include <float.h>
 
 union float_long
   {
@@ -77,8 +25,7 @@ union float_long
   };
 
 /* subtract two floats */
-float
-__fssub (float a1, float a2)
+float __fssub (float a1, float a2)
 {
   volatile union float_long fl1, fl2;
 
index f7c90f33bfe6b2d985e00809ecf86edc1a8646b0..2a8fb4388bb176bfdf8fd706b9592dc7485c9e7b 100644 (file)
@@ -1,7 +1,6 @@
-float __slong2fs (long a );
+#include <float.h>
 
 /* convert signed char to float */
 float __schar2fs (signed char sc) {
-  signed long sl=sc;
-  return __slong2fs(sl);
+  return __slong2fs(sc);
 }
index 4ee9c8008dd6e5cca2ec786c3a01dd8b39eeabb8..0c86277cd12eac38b817cfb1ce41d103c64e46dd 100644 (file)
@@ -1,7 +1,6 @@
-float __slong2fs (signed long sl);
+#include <float.h>
 
 /* convert signed int to float */
 float __sint2fs (signed int si) {
-  signed long sl=si;
-  return __slong2fs(sl);
+  return __slong2fs(si);
 }
index 11516e4f04ed5d22aedc9c72be7996d142587f5b..394fba874f8dbbb3fdad4856acc1bfc55db91372 100644 (file)
@@ -1,9 +1,7 @@
-float 
-__ulong2fs (unsigned long a );
+#include <float.h>
 
 /* convert signed long to float */
-float __slong2fs (signed long sl) 
-{
+float __slong2fs (signed long sl) {
   if (sl<0) 
     return -__ulong2fs(-sl);
   else 
index 475253016026ebb3a66a659fa44e0c0433d664df..3e9198820efbe08e82d57d25169101acae23ab91 100644 (file)
@@ -1,7 +1,6 @@
-float __ulong2fs (unsigned long a );
+#include <float.h>
 
 /* convert unsigned char to float */
 float __uchar2fs (unsigned char uc) {
-  unsigned long ul=uc;
-  return __ulong2fs(ul);
+  return __ulong2fs(uc);
 }
index 514c0211af94fd1c67284dcacdc819953d3406f6..9b443fa9c70107f83adf5a1b3ffe92eb3f4cf2c7 100644 (file)
@@ -1,7 +1,6 @@
-float __ulong2fs (unsigned long a );
+#include <float.h>
 
 /* convert unsigned int to float */
 float __uint2fs (unsigned int ui) {
-  unsigned long ul=ui;
-  return __ulong2fs(ul);
+  return __ulong2fs(ui);
 }
index 7ba7e11c97946a67619354b1c9a2be0e66b090dd..f379420494a11e4c1a49823ef5e8ab80ea28c884 100644 (file)
 ** uunet!motown!pipeline!phw
 */
 
-/* (c)2000: hacked a little by johan.knol@iduna.nl for sdcc */
+/* (c)2000/2001: hacked a little by johan.knol@iduna.nl for sdcc */
 
-/* the following deal with IEEE single-precision numbers */
-#define EXCESS         126
-#define SIGNBIT                ((unsigned long)0x80000000)
-#define HIDDEN         (unsigned long)(1 << 23)
-#define SIGN(fp)       ((fp) & SIGNBIT)
-#define EXP(fp)                (((fp) >> 23) & (unsigned int) 0x00FF)
-#define MANT(fp)       (((fp) & (unsigned long)0x007FFFFF) | HIDDEN)
-#define PACK(s,e,m)    ((s) | ((e) << 23) | (m))
+#include <float.h>
 
 union float_long
   {
@@ -31,8 +24,7 @@ union float_long
     long l;
   };
 
-float 
-__ulong2fs (unsigned long a )
+float __ulong2fs (unsigned long a )
 {
   int exp = 24 + EXCESS;
   volatile union float_long fl;
@@ -42,13 +34,27 @@ __ulong2fs (unsigned long a )
       return 0.0;
     }
 
+  while (a & NORM) 
+    {
+      // we lose accuracy here
+      a >>= 1;
+      exp++;
+    }
+  
   while (a < HIDDEN)
     {
       a <<= 1;
       exp--;
     }
 
-   a &= ~HIDDEN ;
+#if 1
+  if ((a&0x7fffff)==0x7fffff) {
+    a=0;
+    exp++;
+  }
+#endif
+
+  a &= ~HIDDEN ;
   /* pack up and go home */
   fl.l = PACK(0,(unsigned long)exp, a);