From: johanknol Date: Sat, 16 Sep 2000 12:52:46 +0000 (+0000) Subject: restructuring fp support X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=9da5fdfa3ce768702c72349975421df704ec3e4c;p=fw%2Fsdcc restructuring fp support git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@363 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/device/lib/_char2fs.c b/device/lib/_char2fs.c deleted file mode 100644 index ec3e12dc..00000000 --- a/device/lib/_char2fs.c +++ /dev/null @@ -1,110 +0,0 @@ -/* -** 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?). - -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)) - -/* 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)) - -union float_long - { - float f; - long l; - }; - -float -__char2fs (char a ) -{ - long sign = 0; - int exp = 24 + EXCESS; - volatile union float_long fl; - long a1 = a; - - if (!a1) - { - fl.l = 0; - return (fl.f); - } - - if (a1 < 0) - { - sign = SIGNBIT; - a1 = -a1; - } - - while (a1 < HIDDEN) - { - a1 <<= 1; - exp--; - } - - a1 &= ~HIDDEN; - /* pack up and go home */ - fl.l = PACK(sign,(unsigned long)exp, a1); - - return (fl.f); -} diff --git a/device/lib/_fs2char.c b/device/lib/_fs2char.c deleted file mode 100644 index 7fc73ec1..00000000 --- a/device/lib/_fs2char.c +++ /dev/null @@ -1,97 +0,0 @@ -/* -** 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?). - -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)) - -union float_long - { - float f; - long l; - }; - -/* convert double to int */ -char -__fs2char (float a1) -{ - volatile union float_long fl1; - volatile int exp; - volatile long l; - - fl1.f = a1; - - if (!fl1.l) - return (0); - - exp = EXP (fl1.l) - EXCESS - 24; - l = MANT (fl1.l); - - if (exp > 0) - return (0x7F | SIGN(fl1.l)); /* largest integer */ - - /* shift down until exp = 0 or l = 0 */ - if (exp < 0 && exp > -25 && l) - l >>= -exp; - else - return (0); - - return (SIGN(fl1.l) ? -l : l); -} diff --git a/device/lib/_fs2int.c b/device/lib/_fs2int.c deleted file mode 100644 index d9192c42..00000000 --- a/device/lib/_fs2int.c +++ /dev/null @@ -1,97 +0,0 @@ -/* -** 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?). - -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)) - -union float_long - { - float f; - long l; - }; - -/* convert double to int */ -int -__fs2int (float a1) -{ - volatile union float_long fl1; - volatile int exp; - volatile long l; - - fl1.f = a1; - - if (!fl1.l) - return (0); - - exp = EXP (fl1.l) - EXCESS - 24; - l = MANT (fl1.l); - - if (exp > 0) - return (0x7F | SIGN(fl1.l)); /* largest integer */ - - /* shift down until exp = 0 or l = 0 */ - if (exp < 0 && exp > -25 && l) - l >>= -exp; - else - return (0); - - return (SIGN(fl1.l) ? -l : l); -} diff --git a/device/lib/_fs2long.c b/device/lib/_fs2long.c deleted file mode 100644 index ded945f3..00000000 --- a/device/lib/_fs2long.c +++ /dev/null @@ -1,98 +0,0 @@ -/* -** 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?). - -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)) - -union float_long - { - float f; - long l; - }; - -/* convert double to int */ -long -__fs2long (float a1) -{ - volatile union float_long fl1; - volatile int exp; - volatile long l; - - fl1.f = a1; - - if (!fl1.l) - return (0); - - exp = EXP (fl1.l) - EXCESS - 24; - l = MANT (fl1.l); - - if (exp > 0) - return (0x7F | SIGN(fl1.l)); /* largest integer */ - - /* shift down until exp = 0 or l = 0 */ - if (exp < 0 && exp > -25 && l) - l >>= -exp; - else - return (0); - - return (SIGN(fl1.l) ? -l : l); -} - diff --git a/device/lib/_fs2schar.c b/device/lib/_fs2schar.c new file mode 100644 index 00000000..0fc8c989 --- /dev/null +++ b/device/lib/_fs2schar.c @@ -0,0 +1,11 @@ +#include <_float.h> + +/* convert float to signed char */ +signed char __fs2schar (float f) { + signed long sl=__fs2slong(f); + if (sl>=SCHAR_MAX) + return SCHAR_MAX; + if (sl<=SCHAR_MIN) + return -SCHAR_MIN; + return sl; +} diff --git a/device/lib/_fs2sint.c b/device/lib/_fs2sint.c new file mode 100644 index 00000000..9299872f --- /dev/null +++ b/device/lib/_fs2sint.c @@ -0,0 +1,11 @@ +#include <_float.h> + +/* convert float to signed int */ +signed int __fs2sint (float f) { + signed long sl=__fs2slong(f); + if (sl>=SINT_MAX) + return SINT_MAX; + if (sl<=SINT_MIN) + return -SINT_MIN; + return sl; +} diff --git a/device/lib/_fs2slong.c b/device/lib/_fs2slong.c new file mode 100644 index 00000000..d84807a5 --- /dev/null +++ b/device/lib/_fs2slong.c @@ -0,0 +1,18 @@ +#include <_float.h> + +/* convert float to signed long */ +signed long __fs2slong (float f) { + + if (!f) + return 0; + + if (f<0) { + if (f<=SLONG_MIN) + return SLONG_MIN; + return -__fs2ulong(-f); + } else { + if (f>=SLONG_MAX) + return SLONG_MAX; + return __fs2ulong(f); + } +} diff --git a/device/lib/_fs2uchar.c b/device/lib/_fs2uchar.c index 6c669ad2..378f2615 100644 --- a/device/lib/_fs2uchar.c +++ b/device/lib/_fs2uchar.c @@ -1,97 +1,9 @@ -/* -** 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?). +#include <_float.h> -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)) - -union float_long - { - float f; - long l; - }; - -/* convert double to int */ -unsigned char -__fs2uchar (float a1) -{ - volatile union float_long fl1; - volatile int exp; - volatile long l; - - fl1.f = a1; - - if (!fl1.l) - return (0); - - exp = EXP (fl1.l) - EXCESS - 24; - l = MANT (fl1.l); - - if (exp > 0) - return (0x7F | SIGN(fl1.l)); /* largest integer */ - - /* shift down until exp = 0 or l = 0 */ - if (exp < 0 && exp > -25 && l) - l >>= -exp; - else - return (0); - - return (SIGN(fl1.l) ? -(unsigned char)l : (unsigned char)l); +/* convert float to unsigned char */ +unsigned char __fs2uchar (float f) { + unsigned long ul=__fs2ulong(f); + if (ul>=UCHAR_MAX) return UCHAR_MAX; + return ul; } + diff --git a/device/lib/_fs2uint.c b/device/lib/_fs2uint.c index b49df3f4..8542b039 100644 --- a/device/lib/_fs2uint.c +++ b/device/lib/_fs2uint.c @@ -1,97 +1,9 @@ -/* -** 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?). +#include <_float.h> -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)) - -union float_long - { - float f; - long l; - }; - -/* convert double to int */ -unsigned int -__fs2uint (float a1) -{ - volatile union float_long fl1; - volatile int exp; - volatile long l; - - fl1.f = a1; - - if (!fl1.l) - return (0); - - exp = EXP (fl1.l) - EXCESS - 24; - l = MANT (fl1.l); - - if (exp > 0) - return (0x7F | SIGN(fl1.l)); /* largest integer */ - - /* shift down until exp = 0 or l = 0 */ - if (exp < 0 && exp > -25 && l) - l >>= -exp; - else - return (0); - - return (SIGN(fl1.l) ? -l : l); +/* convert float to unsigned int */ +unsigned int __fs2uint (float f) { + unsigned long ul=__fs2ulong(f); + if (ul>=UINT_MAX) return UINT_MAX; + return ul; } + diff --git a/device/lib/_fs2ulong.c b/device/lib/_fs2ulong.c index 48730bca..bdff3c76 100644 --- a/device/lib/_fs2ulong.c +++ b/device/lib/_fs2ulong.c @@ -6,52 +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: hacked a little by johan.knol@iduna.nl for sdcc */ + +#include <_float.h> /* the following deal with IEEE single-precision numbers */ #define EXCESS 126 @@ -63,36 +28,35 @@ If you'd like to work on completing this, please talk to rms@gnu.ai.mit.edu. #define PACK(s,e,m) ((s) | ((e) << 23) | (m)) union float_long - { - float f; - long l; - }; +{ + float f; + long l; +}; -/* convert double to int */ +/* convert float to unsigned long */ unsigned long __fs2ulong (float a1) { volatile union float_long fl1; volatile int exp; volatile long l; - + fl1.f = a1; - - if (!fl1.l) + + 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); + + l >>= -exp; + + return l; +} - if (exp > 0) - return (0x7F | SIGN(fl1.l)); /* largest integer */ - /* shift down until exp = 0 or l = 0 */ - if (exp < 0 && exp > -25 && l) - l >>= -exp; - else - return (0); - return (SIGN(fl1.l) ? -l : l); -} diff --git a/device/lib/_int2fs.c b/device/lib/_int2fs.c deleted file mode 100644 index fff10c17..00000000 --- a/device/lib/_int2fs.c +++ /dev/null @@ -1,111 +0,0 @@ -/* -** 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?). - -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) 0x0FF) -#define MANT(fp) (((fp) & (unsigned long) 0x007FFFFF) | HIDDEN) -#define PACK(s,e,m) ((s) | ((e) << 23) | (m)) - -/* 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)) - -union float_long - { - float f; - long l; - }; - -float -__int2fs (int a ) -{ - long sign = 0; - int exp = 24 + EXCESS; - volatile union float_long fl; - long a1 = a; - - if (!a1) - { - fl.l = 0; - return (fl.f); - } - - if (a1 < 0) - { - sign = SIGNBIT; - a1 = -a1; - } - - while (a1 < HIDDEN) - { - a1 <<= 1; - exp--; - } - - a1 &= ~HIDDEN ; - - /* pack up and go home */ - fl.l = PACK(sign,(unsigned long)exp, a1); - - return (fl.f); -} diff --git a/device/lib/_long2fs.c b/device/lib/_long2fs.c deleted file mode 100644 index cd24f219..00000000 --- a/device/lib/_long2fs.c +++ /dev/null @@ -1,109 +0,0 @@ -/* -** 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?). - -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)) - -/* 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)) - -union float_long - { - float f; - long l; - }; - -float -__long2fs (long a1 ) -{ - long sign = 0; - int exp = 24 + EXCESS; - volatile union float_long fl; - - if (!a1) - { - fl.l = 0; - return (fl.f); - } - - if (a1 < 0) - { - sign = SIGNBIT; - a1 = -a1; - } - - while (a1 < HIDDEN) - { - a1 <<= 1; - exp--; - } - - a1 &= ~HIDDEN; - /* pack up and go home */ - fl.l = PACK(sign,(unsigned long)exp, a1); - - return (fl.f); -} diff --git a/device/lib/_schar2fs.c b/device/lib/_schar2fs.c new file mode 100644 index 00000000..27fa4544 --- /dev/null +++ b/device/lib/_schar2fs.c @@ -0,0 +1,7 @@ +#include <_float.h> + +/* convert signed char to float */ +float __schar2fs (signed char sc) { + signed long sl=sc; + return __slong2fs(sl); +} diff --git a/device/lib/_sint2fs.c b/device/lib/_sint2fs.c new file mode 100644 index 00000000..39bddfd3 --- /dev/null +++ b/device/lib/_sint2fs.c @@ -0,0 +1,7 @@ +#include <_float.h> + +/* convert signed int to float */ +float __sint2fs (signed int si) { + signed long sl=si; + return __slong2fs(sl); +} diff --git a/device/lib/_slong2fs.c b/device/lib/_slong2fs.c new file mode 100644 index 00000000..43272aea --- /dev/null +++ b/device/lib/_slong2fs.c @@ -0,0 +1,9 @@ +#include <_float.h> + +/* convert signed long to float */ +float __slong2fs (signed long sl) { + if (sl<0) + return -__ulong2fs(-sl); + else + return __ulong2fs(sl); +} diff --git a/device/lib/_uchar2fs.c b/device/lib/_uchar2fs.c index d7b74b27..6232ec61 100644 --- a/device/lib/_uchar2fs.c +++ b/device/lib/_uchar2fs.c @@ -1,110 +1,7 @@ -/* -** 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?). +#include <_float.h> -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)) - -/* 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)) - -union float_long - { - float f; - long l; - }; - -float -__uchar2fs (unsigned char a ) -{ - long sign = 0; - int exp = 24 + EXCESS; - volatile union float_long fl; - long a1 = a; - - if (!a1) - { - fl.l = 0; - return (fl.f); - } - - if (a1 < 0) - { - sign = SIGNBIT; - a1 = -a1; - } - - while (a1 < HIDDEN) - { - a1 <<= 1; - exp--; - } - - a1 &= ~HIDDEN; - /* pack up and go home */ - fl.l = PACK(sign,(unsigned long)exp, a1); - - return (fl.f); +/* convert unsigned char to float */ +float __uchar2fs (unsigned char uc) { + unsigned long ul=uc; + return __ulong2fs(ul); } diff --git a/device/lib/_uint2fs.c b/device/lib/_uint2fs.c index 03d13408..dcb45994 100644 --- a/device/lib/_uint2fs.c +++ b/device/lib/_uint2fs.c @@ -1,110 +1,7 @@ -/* -** 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?). +#include <_float.h> -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)) - -/* 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)) - -union float_long - { - float f; - long l; - }; - -float -__uint2fs (unsigned int a ) -{ - long sign = 0; - int exp = 24 + EXCESS; - volatile union float_long fl; - long a1 = a; - - if (!a1) - { - fl.l = 0; - return (fl.f); - } - - if (a1 < 0) - { - sign = SIGNBIT; - a1 = -a1; - } - - while (a1 < HIDDEN) - { - a1 <<= 1; - exp--; - } - - a1 &= ~HIDDEN ; - /* pack up and go home */ - fl.l = PACK(sign,(unsigned long)exp, a1); - - return (fl.f); +/* convert unsigned int to float */ +float __uchar2fs (unsigned char ui) { + unsigned long ul=ui; + return __ulong2fs(ul); } diff --git a/device/lib/_ulong2fs.c b/device/lib/_ulong2fs.c index 77869f6d..5a507896 100644 --- a/device/lib/_ulong2fs.c +++ b/device/lib/_ulong2fs.c @@ -6,52 +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: hacked a little by johan.knol@iduna.nl for sdcc */ + +#include <_float.h> /* the following deal with IEEE single-precision numbers */ #define EXCESS 126 @@ -62,14 +27,6 @@ If you'd like to work on completing this, please talk to rms@gnu.ai.mit.edu. #define MANT(fp) (((fp) & (unsigned long)0x007FFFFF) | HIDDEN) #define PACK(s,e,m) ((s) | ((e) << 23) | (m)) -/* 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)) - union float_long { float f; @@ -79,32 +36,23 @@ union float_long float __ulong2fs (unsigned long a ) { - long sign = 0; int exp = 24 + EXCESS; volatile union float_long fl; - long a1 = a; - - if (!a1) - { - fl.l = 0; - return (fl.f); - } - if (a1 < 0) + if (!a) { - sign = SIGNBIT; - a1 = -a1; + return 0.0; } - while (a1 < HIDDEN) + while (a < HIDDEN) { - a1 <<= 1; + a <<= 1; exp--; } - a1 &= ~HIDDEN ; + a &= ~HIDDEN ; /* pack up and go home */ - fl.l = PACK(sign,(unsigned long)exp, a1); + fl.l = PACK(0,(unsigned long)exp, a); return (fl.f); } diff --git a/device/lib/libfloat.lib b/device/lib/libfloat.lib index 2d28e3f2..ad35b908 100644 --- a/device/lib/libfloat.lib +++ b/device/lib/libfloat.lib @@ -6,15 +6,15 @@ _fslt _fsmul _fsneq _fssub -_char2fs -_int2fs -_long2fs _uchar2fs _uint2fs _ulong2fs -_fs2char -_fs2int -_fs2long +_schar2fs +_sint2fs +_slong2fs _fs2uchar _fs2uint _fs2ulong +_fs2schar +_fs2sint +_fs2slong