From 306c793e04db7aa9b07b985e2588aebcfb39b799 Mon Sep 17 00:00:00 2001 From: MaartenBrock Date: Wed, 26 Jul 2006 09:21:58 +0000 Subject: [PATCH] * device/lib/pic/libsdcc/fsdiv.c, * device/lib/pic/libsdcc/fsmul.c, * device/lib/pic16/libsdcc/float/fsdiv.c, * device/lib/pic16/libsdcc/float/fsmul.c: bugfix, handle too large and small numbers git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4303 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 4 + device/lib/pic/libsdcc/fsdiv.c | 205 +++++++++++++------------ device/lib/pic/libsdcc/fsmul.c | 167 ++++++++++---------- device/lib/pic16/libsdcc/float/fsdiv.c | 15 +- device/lib/pic16/libsdcc/float/fsmul.c | 7 +- 5 files changed, 213 insertions(+), 185 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9b909432..417602d8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2006-07-26 Maarten Brock + * device/lib/pic/libsdcc/fsdiv.c, + * device/lib/pic/libsdcc/fsmul.c, + * device/lib/pic16/libsdcc/float/fsdiv.c, + * device/lib/pic16/libsdcc/float/fsmul.c, * device/lib/_fsdiv.c, * device/lib/_fsmul.c: bugfix, handle too large and too small numbers * support/regression/tests/bug1520966.c: added diff --git a/device/lib/pic/libsdcc/fsdiv.c b/device/lib/pic/libsdcc/fsdiv.c index 7b5b4f50..beb6607d 100644 --- a/device/lib/pic/libsdcc/fsdiv.c +++ b/device/lib/pic/libsdcc/fsdiv.c @@ -1,99 +1,106 @@ -/* -** 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 -*/ - -/* -** $Id: fsdiv.c 3513 2004-10-01 14:49:51Z vrokas $ -*/ - -/* (c)2000/2001: hacked a little by johan.knol@iduna.nl for sdcc */ - -#include - -union float_long - { - float f; - long l; - }; - -/* divide two floats */ -float __fsdiv (float a1, float a2) _FS_REENTRANT -{ - FS_STATIC volatile union float_long fl1, fl2; - long result; - unsigned long mask; - long mant1, mant2; - int exp ; - char sign; - - fl1.f = a1; - fl2.f = a2; - - /* subtract exponents */ - exp = EXP (fl1.l) ; - exp -= EXP (fl2.l); - exp += EXCESS; - - /* compute sign */ - sign = SIGN (fl1.l) ^ SIGN (fl2.l); - - /* divide by zero??? */ - if (!fl2.l) - /* return NaN or -NaN */ - return (-1.0); - - /* numerator zero??? */ - if (!fl1.l) - return (0); - - /* now get mantissas */ - mant1 = MANT (fl1.l); - mant2 = MANT (fl2.l); - - /* this assures we have 25 bits of precision in the end */ - if (mant1 < mant2) - { - mant1 <<= 1; - exp--; - } - - /* now we perform repeated subtraction of fl2.l from fl1.l */ - mask = 0x1000000; - result = 0; - while (mask) - { - if (mant1 >= mant2) - { - result |= mask; - mant1 -= mant2; - } - mant1 <<= 1; - mask >>= 1; - } - - /* round */ - result += 1; - - /* normalize down */ - exp++; - result >>= 1; - - result &= ~HIDDEN; - - /* pack up and go home */ - fl1.l = PACK (sign ? 1ul<<31 : 0, (unsigned long) exp, result); - return (fl1.f); -} - +/* +** 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 +*/ + +/* +** $Id: fsdiv.c 3513 2004-10-01 14:49:51Z vrokas $ +*/ + +/* (c)2000/2001: hacked a little by johan.knol@iduna.nl for sdcc */ + +#include + +union float_long + { + float f; + long l; + }; + +/* divide two floats */ +float __fsdiv (float a1, float a2) _FS_REENTRANT +{ + FS_STATIC volatile union float_long fl1, fl2; + long result; + unsigned long mask; + long mant1, mant2; + int exp ; + char sign; + + fl1.f = a1; + fl2.f = a2; + + /* subtract exponents */ + exp = EXP (fl1.l) ; + exp -= EXP (fl2.l); + exp += EXCESS; + + /* compute sign */ + sign = SIGN (fl1.l) ^ SIGN (fl2.l); + + /* divide by zero??? */ + if (!fl2.l) + {/* return NaN or -NaN */ + fl2.l = 0x7FC00000; + return (fl2.f); + } + + /* numerator zero??? */ + if (!fl1.l) + return (0); + + /* now get mantissas */ + mant1 = MANT (fl1.l); + mant2 = MANT (fl2.l); + + /* this assures we have 25 bits of precision in the end */ + if (mant1 < mant2) + { + mant1 <<= 1; + exp--; + } + + /* now we perform repeated subtraction of fl2.l from fl1.l */ + mask = 0x1000000; + result = 0; + while (mask) + { + if (mant1 >= mant2) + { + result |= mask; + mant1 -= mant2; + } + mant1 <<= 1; + mask >>= 1; + } + + /* round */ + result += 1; + + /* normalize down */ + exp++; + result >>= 1; + + result &= ~HIDDEN; + + /* pack up and go home */ + if (exp >= 0x100) + fl1.l = (sign ? SIGNBIT : 0) | 0x7F800000; + else if (exp < 0) + fl1.l = 0; + else + fl1.l = PACK (sign ? SIGNBIT : 0 , exp, result); + return (fl1.f); +} + diff --git a/device/lib/pic/libsdcc/fsmul.c b/device/lib/pic/libsdcc/fsmul.c index 93cc9ccc..9752800c 100644 --- a/device/lib/pic/libsdcc/fsmul.c +++ b/device/lib/pic/libsdcc/fsmul.c @@ -1,81 +1,86 @@ -/* -** 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 -*/ - -/* -** $Id: fsmul.c 3513 2004-10-01 14:49:51Z vrokas $ -*/ - -/* (c)2000/2001: hacked a little by johan.knol@iduna.nl for sdcc */ - -#include - -union float_long - { - float f; - unsigned long l; - }; - -/* multiply two floats */ -float __fsmul (float a1, float a2) _FS_REENTRANT -{ - FS_STATIC volatile union float_long fl1, fl2; - unsigned long result; - int exp; - char sign; - - fl1.f = a1; - fl2.f = a2; - - if (!fl1.l || !fl2.l) - return (0); - - /* compute sign and exponent */ - sign = SIGN (fl1.l) ^ SIGN (fl2.l); - exp = EXP (fl1.l) - EXCESS; - exp += EXP (fl2.l); - - fl1.l = MANT (fl1.l); - fl2.l = MANT (fl2.l); - - /* the multiply is done as one 16x16 multiply and two 16x8 multiples */ - result = (fl1.l >> 8) * (fl2.l >> 8); - result += ((fl1.l & (unsigned long) 0xFF) * (fl2.l >> 8)) >> 8; - result += ((fl2.l & (unsigned long) 0xFF) * (fl1.l >> 8)) >> 8; - - if (0 != (result & SIGNBIT)) - { - /* round */ - result += 0x80; - result >>= 8; - } - else - { - /* round */ - result += 0x40; - result >>= 7; - exp--; - } - - result &= ~HIDDEN; - - /* pack up and go home */ - fl1.l = PACK (sign ? SIGNBIT : 0 , (unsigned long)exp, result); - return (fl1.f); -} - - - - +/* +** 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 +*/ + +/* +** $Id: fsmul.c 3513 2004-10-01 14:49:51Z vrokas $ +*/ + +/* (c)2000/2001: hacked a little by johan.knol@iduna.nl for sdcc */ + +#include + +union float_long + { + float f; + unsigned long l; + }; + +/* multiply two floats */ +float __fsmul (float a1, float a2) _FS_REENTRANT +{ + FS_STATIC volatile union float_long fl1, fl2; + unsigned long result; + int exp; + char sign; + + fl1.f = a1; + fl2.f = a2; + + if (!fl1.l || !fl2.l) + return (0); + + /* compute sign and exponent */ + sign = SIGN (fl1.l) ^ SIGN (fl2.l); + exp = EXP (fl1.l) - EXCESS; + exp += EXP (fl2.l); + + fl1.l = MANT (fl1.l); + fl2.l = MANT (fl2.l); + + /* the multiply is done as one 16x16 multiply and two 16x8 multiples */ + result = (fl1.l >> 8) * (fl2.l >> 8); + result += ((fl1.l & (unsigned long) 0xFF) * (fl2.l >> 8)) >> 8; + result += ((fl2.l & (unsigned long) 0xFF) * (fl1.l >> 8)) >> 8; + + if (0 != (result & SIGNBIT)) + { + /* round */ + result += 0x80; + result >>= 8; + } + else + { + /* round */ + result += 0x40; + result >>= 7; + exp--; + } + + result &= ~HIDDEN; + + /* pack up and go home */ + if (exp >= 0x100) + fl1.l = (sign ? SIGNBIT : 0) | 0x7F800000; + else if (exp < 0) + fl1.l = 0; + else + fl1.l = PACK (sign ? SIGNBIT : 0 , exp, result); + return (fl1.f); +} + + + + diff --git a/device/lib/pic16/libsdcc/float/fsdiv.c b/device/lib/pic16/libsdcc/float/fsdiv.c index e438a577..767f8032 100644 --- a/device/lib/pic16/libsdcc/float/fsdiv.c +++ b/device/lib/pic16/libsdcc/float/fsdiv.c @@ -35,7 +35,7 @@ float __fsdiv (float a1, float a2) _FS_REENTRANT volatile long result; volatile unsigned long mask; volatile long mant1, mant2; - volatile int exp ; + volatile int exp; char sign; fl1.f = a1; @@ -51,8 +51,10 @@ float __fsdiv (float a1, float a2) _FS_REENTRANT /* divide by zero??? */ if (!fl2.l) - /* return NaN or -NaN */ - return (-1.0); + {/* return NaN or -NaN */ + fl2.l = 0x7FC00000; + return (fl2.f); + } /* numerator zero??? */ if (!fl1.l) @@ -93,7 +95,12 @@ float __fsdiv (float a1, float a2) _FS_REENTRANT result &= ~HIDDEN; /* pack up and go home */ - fl1.l = PACK (sign ? 1ul<<31 : 0, (unsigned long) exp, result); + if (exp >= 0x100) + fl1.l = (sign ? SIGNBIT : 0) | 0x7F800000; + else if (exp < 0) + fl1.l = 0; + else + fl1.l = PACK (sign ? SIGNBIT : 0 , exp, result); return (fl1.f); } diff --git a/device/lib/pic16/libsdcc/float/fsmul.c b/device/lib/pic16/libsdcc/float/fsmul.c index 0e7fc27e..a0813cf0 100644 --- a/device/lib/pic16/libsdcc/float/fsmul.c +++ b/device/lib/pic16/libsdcc/float/fsmul.c @@ -72,7 +72,12 @@ float __fsmul (float a1, float a2) _FS_REENTRANT result &= ~HIDDEN; /* pack up and go home */ - fl1.l = PACK (sign ? SIGNBIT : 0 , (unsigned long)exp, result); + if (exp >= 0x100) + fl1.l = (sign ? SIGNBIT : 0) | 0x7F800000; + else if (exp < 0) + fl1.l = 0; + else + fl1.l = PACK (sign ? SIGNBIT : 0 , exp, result); return (fl1.f); } -- 2.30.2