X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=device%2Flib%2Fpic%2Flibsdcc%2Ffsdiv.c;h=f4a44e6b7497391601021bcf0211590b91446bfe;hb=5c167d844868e592617c9a8f1355abb9e29647a9;hp=beb6607d216a8cb8878071b376dca4fee173d355;hpb=4a739655b9d81efc3155fdd9326ac1f55d415253;p=fw%2Fsdcc diff --git a/device/lib/pic/libsdcc/fsdiv.c b/device/lib/pic/libsdcc/fsdiv.c index beb6607d..f4a44e6b 100644 --- a/device/lib/pic/libsdcc/fsdiv.c +++ b/device/lib/pic/libsdcc/fsdiv.c @@ -1,106 +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 */ - 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); -} - +/* +** 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$ +*/ + +/* (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); +} +