diff options
Diffstat (limited to 'gcc/config/m68k/fpgnulib.c')
-rw-r--r-- | gcc/config/m68k/fpgnulib.c | 595 |
1 files changed, 0 insertions, 595 deletions
diff --git a/gcc/config/m68k/fpgnulib.c b/gcc/config/m68k/fpgnulib.c deleted file mode 100644 index 2a7f6c75d11..00000000000 --- a/gcc/config/m68k/fpgnulib.c +++ /dev/null @@ -1,595 +0,0 @@ -/* This is a stripped down version of floatlib.c. It supplies only those - functions which exist in libgcc, but for which there is not assembly - language versions in m68k/lb1sf68.asm. - - It also includes simplistic support for extended floats (by working in - double precision). You must compile this file again with -DEXTFLOAT - to get this support. */ - -/* -** gnulib 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 -** -** 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 gnulib 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 126L -#define SIGNBIT 0x80000000L -#define HIDDEN (1L << 23L) -#define SIGN(fp) ((fp) & SIGNBIT) -#define EXP(fp) (((fp) >> 23L) & 0xFF) -#define MANT(fp) (((fp) & 0x7FFFFFL) | HIDDEN) -#define PACK(s,e,m) ((s) | ((e) << 23L) | (m)) - -/* the following deal with IEEE double-precision numbers */ -#define EXCESSD 1022L -#define HIDDEND (1L << 20L) -#define EXPDBITS 11 -#define EXPDMASK 0x7FFL -#define EXPD(fp) (((fp.l.upper) >> 20L) & 0x7FFL) -#define SIGND(fp) ((fp.l.upper) & SIGNBIT) -#define MANTD(fp) (((((fp.l.upper) & 0xFFFFF) | HIDDEND) << 10) | \ - (fp.l.lower >> 22)) -#define MANTDMASK 0xFFFFFL /* mask of upper part */ - -/* the following deal with IEEE extended-precision numbers */ -#define EXCESSX 16382L -#define HIDDENX (1L << 31L) -#define EXPXBITS 15 -#define EXPXMASK 0x7FFF -#define EXPX(fp) (((fp.l.upper) >> 16) & EXPXMASK) -#define SIGNX(fp) ((fp.l.upper) & SIGNBIT) -#define MANTXMASK 0x7FFFFFFFL /* mask of upper part */ - -union double_long -{ - double d; - struct { - long upper; - unsigned long lower; - } l; -}; - -union float_long { - float f; - long l; -}; - -union long_double_long -{ - long double ld; - struct - { - long upper; - unsigned long middle; - unsigned long lower; - } l; -}; - -#ifndef EXTFLOAT - -int -__unordsf2(float a, float b) -{ - union float_long fl; - - fl.f = a; - if (EXP(fl.l) == EXP(~0u) && (MANT(fl.l) & ~HIDDEN) != 0) - return 1; - fl.f = b; - if (EXP(fl.l) == EXP(~0u) && (MANT(fl.l) & ~HIDDEN) != 0) - return 1; - return 0; -} - -int -__unorddf2(double a, double b) -{ - union double_long dl; - - dl.d = a; - if (EXPD(dl) == EXPDMASK - && ((dl.l.upper & MANTDMASK) != 0 || dl.l.lower != 0)) - return 1; - dl.d = b; - if (EXPD(dl) == EXPDMASK - && ((dl.l.upper & MANTDMASK) != 0 || dl.l.lower != 0)) - return 1; - return 0; -} - -/* convert unsigned int to double */ -double -__floatunsidf (unsigned long a1) -{ - long exp = 32 + EXCESSD; - union double_long dl; - - if (!a1) - { - dl.l.upper = dl.l.lower = 0; - return dl.d; - } - - while (a1 < 0x2000000L) - { - a1 <<= 4; - exp -= 4; - } - - while (a1 < 0x80000000L) - { - a1 <<= 1; - exp--; - } - - /* pack up and go home */ - dl.l.upper = exp << 20L; - dl.l.upper |= (a1 >> 11L) & ~HIDDEND; - dl.l.lower = a1 << 21L; - - return dl.d; -} - -/* convert int to double */ -double -__floatsidf (long a1) -{ - long sign = 0, exp = 31 + EXCESSD; - union double_long dl; - - if (!a1) - { - dl.l.upper = dl.l.lower = 0; - return dl.d; - } - - if (a1 < 0) - { - sign = SIGNBIT; - a1 = (long)-(unsigned long)a1; - if (a1 < 0) - { - dl.l.upper = SIGNBIT | ((32 + EXCESSD) << 20L); - dl.l.lower = 0; - return dl.d; - } - } - - while (a1 < 0x1000000L) - { - a1 <<= 4; - exp -= 4; - } - - while (a1 < 0x40000000L) - { - a1 <<= 1; - exp--; - } - - /* pack up and go home */ - dl.l.upper = sign; - dl.l.upper |= exp << 20L; - dl.l.upper |= (a1 >> 10L) & ~HIDDEND; - dl.l.lower = a1 << 22L; - - return dl.d; -} - -/* convert unsigned int to float */ -float -__floatunsisf (unsigned long l) -{ - double foo = __floatunsidf (l); - return foo; -} - -/* convert int to float */ -float -__floatsisf (long l) -{ - double foo = __floatsidf (l); - return foo; -} - -/* convert float to double */ -double -__extendsfdf2 (float a1) -{ - register union float_long fl1; - register union double_long dl; - register long exp; - register long mant; - - fl1.f = a1; - - dl.l.upper = SIGN (fl1.l); - if ((fl1.l & ~SIGNBIT) == 0) - { - dl.l.lower = 0; - return dl.d; - } - - exp = EXP(fl1.l); - mant = MANT (fl1.l) & ~HIDDEN; - if (exp == 0) - { - /* Denormal. */ - exp = 1; - while (!(mant & HIDDEN)) - { - mant <<= 1; - exp--; - } - mant &= ~HIDDEN; - } - exp = exp - EXCESS + EXCESSD; - dl.l.upper |= exp << 20; - dl.l.upper |= mant >> 3; - dl.l.lower = mant << 29; - - return dl.d; -} - -/* convert double to float */ -float -__truncdfsf2 (double a1) -{ - register long exp; - register long mant; - register union float_long fl; - register union double_long dl1; - int sticky; - int shift; - - dl1.d = a1; - - if ((dl1.l.upper & ~SIGNBIT) == 0 && !dl1.l.lower) - { - fl.l = SIGND(dl1); - return fl.f; - } - - exp = EXPD (dl1) - EXCESSD + EXCESS; - - sticky = dl1.l.lower & ((1 << 22) - 1); - mant = MANTD (dl1); - /* shift double mantissa 6 bits so we can round */ - sticky |= mant & ((1 << 6) - 1); - mant >>= 6; - - /* Check for underflow and denormals. */ - if (exp <= 0) - { - if (exp < -24) - { - sticky |= mant; - mant = 0; - } - else - { - sticky |= mant & ((1 << (1 - exp)) - 1); - mant >>= 1 - exp; - } - exp = 0; - } - - /* now round */ - shift = 1; - if ((mant & 1) && (sticky || (mant & 2))) - { - int rounding = exp ? 2 : 1; - - mant += 1; - - /* did the round overflow? */ - if (mant >= (HIDDEN << rounding)) - { - exp++; - shift = rounding; - } - } - /* shift down */ - mant >>= shift; - - mant &= ~HIDDEN; - - /* pack up and go home */ - fl.l = PACK (SIGND (dl1), exp, mant); - return (fl.f); -} - -/* convert double to int */ -long -__fixdfsi (double a1) -{ - register union double_long dl1; - register long exp; - register long l; - - dl1.d = a1; - - if (!dl1.l.upper && !dl1.l.lower) - return 0; - - exp = EXPD (dl1) - EXCESSD - 31; - l = MANTD (dl1); - - if (exp > 0) - { - /* Return largest integer. */ - return SIGND (dl1) ? 0x80000000L : 0x7fffffffL; - } - - if (exp <= -32) - return 0; - - /* shift down until exp = 0 */ - if (exp < 0) - l >>= -exp; - - return (SIGND (dl1) ? -l : l); -} - -/* convert float to int */ -long -__fixsfsi (float a1) -{ - double foo = a1; - return __fixdfsi (foo); -} - -#else /* EXTFLOAT */ - -/* We do not need these routines for coldfire, as it has no extended - float format. */ -#if !defined (__mcoldfire__) - -/* Primitive extended precision floating point support. - - We assume all numbers are normalized, don't do any rounding, etc. */ - -/* Prototypes for the above in case we use them. */ -double __floatunsidf (unsigned long); -double __floatsidf (long); -float __floatsisf (long); -double __extendsfdf2 (float); -float __truncdfsf2 (double); -long __fixdfsi (double); -long __fixsfsi (float); - -int -__unordxf2(long double a, long double b) -{ - union long_double_long ldl; - - ldl.ld = a; - if (EXPX(ldl) == EXPXMASK - && ((ldl.l.middle & MANTXMASK) != 0 || ldl.l.lower != 0)) - return 1; - ldl.ld = b; - if (EXPX(ldl) == EXPXMASK - && ((ldl.l.middle & MANTXMASK) != 0 || ldl.l.lower != 0)) - return 1; - return 0; -} - -/* convert double to long double */ -long double -__extenddfxf2 (double d) -{ - register union double_long dl; - register union long_double_long ldl; - register long exp; - - dl.d = d; - /*printf ("dfxf in: %g\n", d);*/ - - ldl.l.upper = SIGND (dl); - if ((dl.l.upper & ~SIGNBIT) == 0 && !dl.l.lower) - { - ldl.l.middle = 0; - ldl.l.lower = 0; - return ldl.ld; - } - - exp = EXPD (dl) - EXCESSD + EXCESSX; - ldl.l.upper |= exp << 16; - ldl.l.middle = HIDDENX; - /* 31-20: # mantissa bits in ldl.l.middle - # mantissa bits in dl.l.upper */ - ldl.l.middle |= (dl.l.upper & MANTDMASK) << (31 - 20); - /* 1+20: explicit-integer-bit + # mantissa bits in dl.l.upper */ - ldl.l.middle |= dl.l.lower >> (1 + 20); - /* 32 - 21: # bits of dl.l.lower in ldl.l.middle */ - ldl.l.lower = dl.l.lower << (32 - 21); - - /*printf ("dfxf out: %s\n", dumpxf (ldl.ld));*/ - return ldl.ld; -} - -/* convert long double to double */ -double -__truncxfdf2 (long double ld) -{ - register long exp; - register union double_long dl; - register union long_double_long ldl; - - ldl.ld = ld; - /*printf ("xfdf in: %s\n", dumpxf (ld));*/ - - dl.l.upper = SIGNX (ldl); - if ((ldl.l.upper & ~SIGNBIT) == 0 && !ldl.l.middle && !ldl.l.lower) - { - dl.l.lower = 0; - return dl.d; - } - - exp = EXPX (ldl) - EXCESSX + EXCESSD; - /* ??? quick and dirty: keep `exp' sane */ - if (exp >= EXPDMASK) - exp = EXPDMASK - 1; - dl.l.upper |= exp << (32 - (EXPDBITS + 1)); - /* +1-1: add one for sign bit, but take one off for explicit-integer-bit */ - dl.l.upper |= (ldl.l.middle & MANTXMASK) >> (EXPDBITS + 1 - 1); - dl.l.lower = (ldl.l.middle & MANTXMASK) << (32 - (EXPDBITS + 1 - 1)); - dl.l.lower |= ldl.l.lower >> (EXPDBITS + 1 - 1); - - /*printf ("xfdf out: %g\n", dl.d);*/ - return dl.d; -} - -/* convert a float to a long double */ -long double -__extendsfxf2 (float f) -{ - long double foo = __extenddfxf2 (__extendsfdf2 (f)); - return foo; -} - -/* convert a long double to a float */ -float -__truncxfsf2 (long double ld) -{ - float foo = __truncdfsf2 (__truncxfdf2 (ld)); - return foo; -} - -/* convert an int to a long double */ -long double -__floatsixf (long l) -{ - double foo = __floatsidf (l); - return foo; -} - -/* convert an unsigned int to a long double */ -long double -__floatunsixf (unsigned long l) -{ - double foo = __floatunsidf (l); - return foo; -} - -/* convert a long double to an int */ -long -__fixxfsi (long double ld) -{ - long foo = __fixdfsi ((double) ld); - return foo; -} - -/* The remaining provide crude math support by working in double precision. */ - -long double -__addxf3 (long double x1, long double x2) -{ - return (double) x1 + (double) x2; -} - -long double -__subxf3 (long double x1, long double x2) -{ - return (double) x1 - (double) x2; -} - -long double -__mulxf3 (long double x1, long double x2) -{ - return (double) x1 * (double) x2; -} - -long double -__divxf3 (long double x1, long double x2) -{ - return (double) x1 / (double) x2; -} - -long double -__negxf2 (long double x1) -{ - return - (double) x1; -} - -long -__cmpxf2 (long double x1, long double x2) -{ - return __cmpdf2 ((double) x1, (double) x2); -} - -long -__eqxf2 (long double x1, long double x2) -{ - return __cmpdf2 ((double) x1, (double) x2); -} - -long -__nexf2 (long double x1, long double x2) -{ - return __cmpdf2 ((double) x1, (double) x2); -} - -long -__ltxf2 (long double x1, long double x2) -{ - return __cmpdf2 ((double) x1, (double) x2); -} - -long -__lexf2 (long double x1, long double x2) -{ - return __cmpdf2 ((double) x1, (double) x2); -} - -long -__gtxf2 (long double x1, long double x2) -{ - return __cmpdf2 ((double) x1, (double) x2); -} - -long -__gexf2 (long double x1, long double x2) -{ - return __cmpdf2 ((double) x1, (double) x2); -} - -#endif /* !__mcoldfire__ */ -#endif /* EXTFLOAT */ |