X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=gcc%2Fconfig%2Fm68k%2Ffpgnulib.c;fp=gcc%2Fconfig%2Fm68k%2Ffpgnulib.c;h=2a7f6c75d11ac7c60d2df29a0400c353254e78a9;hb=6fed43773c9b0ce596dca5686f37ac3fc0fa11c0;hp=0559b628c87a473ad10053b17fad8d6d3b222ae4;hpb=27b11d56b743098deb193d510b337ba22dc52e5c;p=msp430-gcc.git diff --git a/gcc/config/m68k/fpgnulib.c b/gcc/config/m68k/fpgnulib.c index 0559b628..2a7f6c75 100644 --- a/gcc/config/m68k/fpgnulib.c +++ b/gcc/config/m68k/fpgnulib.c @@ -59,24 +59,24 @@ #define PACK(s,e,m) ((s) | ((e) << 23L) | (m)) /* the following deal with IEEE double-precision numbers */ -#define EXCESSD 1022 +#define EXCESSD 1022L #define HIDDEND (1L << 20L) #define EXPDBITS 11 -#define EXPDMASK 0x7FF +#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 0xFFFFF /* mask of upper part */ +#define MANTDMASK 0xFFFFFL /* mask of upper part */ /* the following deal with IEEE extended-precision numbers */ -#define EXCESSX 16382 +#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 0x7FFFFFFF /* mask of upper part */ +#define MANTXMASK 0x7FFFFFFFL /* mask of upper part */ union double_long { @@ -105,9 +105,72 @@ union long_double_long #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 (int a1) +__floatsidf (long a1) { long sign = 0, exp = 31 + EXCESSD; union double_long dl; @@ -121,7 +184,7 @@ __floatsidf (int a1) if (a1 < 0) { sign = SIGNBIT; - a1 = -a1; + a1 = (long)-(unsigned long)a1; if (a1 < 0) { dl.l.upper = SIGNBIT | ((32 + EXCESSD) << 20L); @@ -130,13 +193,13 @@ __floatsidf (int a1) } } - while (a1 < 0x1000000) + while (a1 < 0x1000000L) { a1 <<= 4; exp -= 4; } - while (a1 < 0x40000000) + while (a1 < 0x40000000L) { a1 <<= 1; exp--; @@ -151,9 +214,17 @@ __floatsidf (int a1) 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 (int l) +__floatsisf (long l) { double foo = __floatsidf (l); return foo; @@ -166,20 +237,34 @@ __extendsfdf2 (float a1) register union float_long fl1; register union double_long dl; register long exp; + register long mant; fl1.f = a1; - if (!fl1.l) + dl.l.upper = SIGN (fl1.l); + if ((fl1.l & ~SIGNBIT) == 0) { - dl.l.upper = dl.l.lower = 0; + dl.l.lower = 0; return dl.d; } - dl.l.upper = SIGN (fl1.l); - exp = EXP (fl1.l) - EXCESS + EXCESSD; + 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 (fl1.l) & ~HIDDEN) >> 3; - dl.l.lower = MANT (fl1.l) << 29; + dl.l.upper |= mant >> 3; + dl.l.lower = mant << 29; return dl.d; } @@ -192,27 +277,58 @@ __truncdfsf2 (double a1) register long mant; register union float_long fl; register union double_long dl1; + int sticky; + int shift; dl1.d = a1; - if (!dl1.l.upper && !dl1.l.lower) - return 0; + 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 */ - mant = MANTD (dl1) >> 6; - - /* now round and shift down */ - mant += 1; - mant >>= 1; + sticky |= mant & ((1 << 6) - 1); + mant >>= 6; - /* did the round overflow? */ - if (mant & 0xFF000000) + /* Check for underflow and denormals. */ + if (exp <= 0) { - mant >>= 1; - exp++; + 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; @@ -222,7 +338,7 @@ __truncdfsf2 (double a1) } /* convert double to int */ -int +long __fixdfsi (double a1) { register union double_long dl1; @@ -240,7 +356,7 @@ __fixdfsi (double a1) if (exp > 0) { /* Return largest integer. */ - return SIGND (dl1) ? 0x80000000 : 0x7fffffff; + return SIGND (dl1) ? 0x80000000L : 0x7fffffffL; } if (exp <= -32) @@ -254,7 +370,7 @@ __fixdfsi (double a1) } /* convert float to int */ -int +long __fixsfsi (float a1) { double foo = a1; @@ -263,17 +379,38 @@ __fixsfsi (float a1) #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 __floatsidf (int); -float __floatsisf (int); +double __floatunsidf (unsigned long); +double __floatsidf (long); +float __floatsisf (long); double __extendsfdf2 (float); float __truncdfsf2 (double); -int __fixdfsi (double); -int __fixsfsi (float); +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 @@ -286,10 +423,14 @@ __extenddfxf2 (double d) dl.d = d; /*printf ("dfxf in: %g\n", d);*/ - if (!dl.l.upper && !dl.l.lower) - return 0; - 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; @@ -315,14 +456,17 @@ __truncxfdf2 (long double ld) ldl.ld = ld; /*printf ("xfdf in: %s\n", dumpxf (ld));*/ - if (!ldl.l.upper && !ldl.l.middle && !ldl.l.lower) - return 0; + 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 = SIGNX (ldl); 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); @@ -351,17 +495,25 @@ __truncxfsf2 (long double ld) /* convert an int to a long double */ long double -__floatsixf (int l) +__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 */ -int +long __fixxfsi (long double ld) { - int foo = __fixdfsi ((double) ld); + long foo = __fixdfsi ((double) ld); return foo; } @@ -439,4 +591,5 @@ __gexf2 (long double x1, long double x2) return __cmpdf2 ((double) x1, (double) x2); } +#endif /* !__mcoldfire__ */ #endif /* EXTFLOAT */