diff options
Diffstat (limited to 'contrib/gcc/libgcc2.c')
-rw-r--r-- | contrib/gcc/libgcc2.c | 740 |
1 files changed, 151 insertions, 589 deletions
diff --git a/contrib/gcc/libgcc2.c b/contrib/gcc/libgcc2.c index 851bdd0..4f45b09 100644 --- a/contrib/gcc/libgcc2.c +++ b/contrib/gcc/libgcc2.c @@ -1,7 +1,7 @@ /* More subroutines needed by GCC output code on some machines. */ /* Compile this one with gcc. */ /* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GCC. @@ -26,42 +26,33 @@ for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING. If not, write to the Free -Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301, USA. */ +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ + +/* We include auto-host.h here to get HAVE_GAS_HIDDEN. This is + supposedly valid even though this is a "target" file. */ +#include "auto-host.h" + +/* It is incorrect to include config.h here, because this file is being + compiled for the target, and hence definitions concerning only the host + do not apply. */ #include "tconfig.h" #include "tsystem.h" #include "coretypes.h" #include "tm.h" +/* Don't use `fancy_abort' here even if config.h says to use it. */ +#ifdef abort +#undef abort +#endif + #ifdef HAVE_GAS_HIDDEN #define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden"))) #else #define ATTRIBUTE_HIDDEN #endif -#ifndef MIN_UNITS_PER_WORD -#define MIN_UNITS_PER_WORD UNITS_PER_WORD -#endif - -/* Work out the largest "word" size that we can deal with on this target. */ -#if MIN_UNITS_PER_WORD > 4 -# define LIBGCC2_MAX_UNITS_PER_WORD 8 -#elif (MIN_UNITS_PER_WORD > 2 \ - || (MIN_UNITS_PER_WORD > 1 && LONG_LONG_TYPE_SIZE > 32)) -# define LIBGCC2_MAX_UNITS_PER_WORD 4 -#else -# define LIBGCC2_MAX_UNITS_PER_WORD MIN_UNITS_PER_WORD -#endif - -/* Work out what word size we are using for this compilation. - The value can be set on the command line. */ -#ifndef LIBGCC2_UNITS_PER_WORD -#define LIBGCC2_UNITS_PER_WORD LIBGCC2_MAX_UNITS_PER_WORD -#endif - -#if LIBGCC2_UNITS_PER_WORD <= LIBGCC2_MAX_UNITS_PER_WORD - #include "libgcc2.h" #ifdef DECLARE_LIBRARY_RENAMES @@ -157,12 +148,13 @@ __subvDI3 (DWtype a, DWtype b) #endif #ifdef L_mulvsi3 +#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) Wtype __mulvSI3 (Wtype a, Wtype b) { const DWtype w = (DWtype) a * (DWtype) b; - if ((Wtype) (w >> W_TYPE_SIZE) != (Wtype) w >> (W_TYPE_SIZE - 1)) + if ((Wtype) (w >> WORD_SIZE) != (Wtype) w >> (WORD_SIZE - 1)) abort (); return w; @@ -281,6 +273,7 @@ __absvDI2 (DWtype a) #endif #ifdef L_mulvdi3 +#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) DWtype __mulvDI3 (DWtype u, DWtype v) { @@ -289,10 +282,10 @@ __mulvDI3 (DWtype u, DWtype v) const DWunion uu = {.ll = u}; const DWunion vv = {.ll = v}; - if (__builtin_expect (uu.s.high == uu.s.low >> (W_TYPE_SIZE - 1), 1)) + if (__builtin_expect (uu.s.high == uu.s.low >> (WORD_SIZE - 1), 1)) { /* u fits in a single Wtype. */ - if (__builtin_expect (vv.s.high == vv.s.low >> (W_TYPE_SIZE - 1), 1)) + if (__builtin_expect (vv.s.high == vv.s.low >> (WORD_SIZE - 1), 1)) { /* v fits in a single Wtype as well. */ /* A single multiplication. No overflow risk. */ @@ -311,7 +304,7 @@ __mulvDI3 (DWtype u, DWtype v) if (uu.s.low < 0) w1.ll -= vv.ll; w1.ll += (UWtype) w0.s.high; - if (__builtin_expect (w1.s.high == w1.s.low >> (W_TYPE_SIZE - 1), 1)) + if (__builtin_expect (w1.s.high == w1.s.low >> (WORD_SIZE - 1), 1)) { w0.s.high = w1.s.low; return w0.ll; @@ -320,7 +313,7 @@ __mulvDI3 (DWtype u, DWtype v) } else { - if (__builtin_expect (vv.s.high == vv.s.low >> (W_TYPE_SIZE - 1), 1)) + if (__builtin_expect (vv.s.high == vv.s.low >> (WORD_SIZE - 1), 1)) { /* v fits into a single Wtype. */ /* Two multiplications. */ @@ -334,7 +327,7 @@ __mulvDI3 (DWtype u, DWtype v) if (vv.s.low < 0) w1.ll -= uu.ll; w1.ll += (UWtype) w0.s.high; - if (__builtin_expect (w1.s.high == w1.s.low >> (W_TYPE_SIZE - 1), 1)) + if (__builtin_expect (w1.s.high == w1.s.low >> (WORD_SIZE - 1), 1)) { w0.s.high = w1.s.low; return w0.ll; @@ -494,6 +487,7 @@ __ashrdi3 (DWtype u, word_type b) #ifdef L_ffssi2 #undef int +extern int __ffsSI2 (UWtype u); int __ffsSI2 (UWtype u) { @@ -509,6 +503,7 @@ __ffsSI2 (UWtype u) #ifdef L_ffsdi2 #undef int +extern int __ffsDI2 (DWtype u); int __ffsDI2 (DWtype u) { @@ -565,16 +560,16 @@ __udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d) { if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1))) { - /* Dividend, divisor, and quotient are nonnegative. */ + /* dividend, divisor, and quotient are nonnegative */ sdiv_qrnnd (q, r, a1, a0, d); } else { - /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d. */ + /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */ sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1)); - /* Divide (c1*2^32 + c0) by d. */ + /* Divide (c1*2^32 + c0) by d */ sdiv_qrnnd (q, r, c1, c0, d); - /* Add 2^31 to quotient. */ + /* Add 2^31 to quotient */ q += (UWtype) 1 << (W_TYPE_SIZE - 1); } } @@ -670,7 +665,7 @@ __udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)), #endif #ifdef L_clz -const UQItype __clz_tab[256] = +const UQItype __clz_tab[] = { 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, @@ -679,12 +674,13 @@ const UQItype __clz_tab[256] = 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, }; #endif #ifdef L_clzsi2 #undef int +extern int __clzSI2 (UWtype x); int __clzSI2 (UWtype x) { @@ -698,6 +694,7 @@ __clzSI2 (UWtype x) #ifdef L_clzdi2 #undef int +extern int __clzDI2 (UDWtype x); int __clzDI2 (UDWtype x) { @@ -717,6 +714,7 @@ __clzDI2 (UDWtype x) #ifdef L_ctzsi2 #undef int +extern int __ctzSI2 (UWtype x); int __ctzSI2 (UWtype x) { @@ -730,6 +728,7 @@ __ctzSI2 (UWtype x) #ifdef L_ctzdi2 #undef int +extern int __ctzDI2 (UDWtype x); int __ctzDI2 (UDWtype x) { @@ -747,8 +746,13 @@ __ctzDI2 (UDWtype x) } #endif +#if (defined (L_popcountsi2) || defined (L_popcountdi2) \ + || defined (L_popcount_tab)) +extern const UQItype __popcount_tab[] ATTRIBUTE_HIDDEN; +#endif + #ifdef L_popcount_tab -const UQItype __popcount_tab[256] = +const UQItype __popcount_tab[] = { 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, @@ -757,16 +761,17 @@ const UQItype __popcount_tab[256] = 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, - 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8 + 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8, }; #endif #ifdef L_popcountsi2 #undef int +extern int __popcountSI2 (UWtype x); int __popcountSI2 (UWtype x) { - int i, ret = 0; + UWtype i, ret = 0; for (i = 0; i < W_TYPE_SIZE; i += 8) ret += __popcount_tab[(x >> i) & 0xff]; @@ -777,10 +782,11 @@ __popcountSI2 (UWtype x) #ifdef L_popcountdi2 #undef int +extern int __popcountDI2 (UDWtype x); int __popcountDI2 (UDWtype x) { - int i, ret = 0; + UWtype i, ret = 0; for (i = 0; i < 2*W_TYPE_SIZE; i += 8) ret += __popcount_tab[(x >> i) & 0xff]; @@ -791,6 +797,7 @@ __popcountDI2 (UDWtype x) #ifdef L_paritysi2 #undef int +extern int __paritySI2 (UWtype x); int __paritySI2 (UWtype x) { @@ -812,6 +819,7 @@ __paritySI2 (UWtype x) #ifdef L_paritydi2 #undef int +extern int __parityDI2 (UDWtype x); int __parityDI2 (UDWtype x) { @@ -1093,7 +1101,7 @@ __moddi3 (DWtype u, DWtype v) if (vv.s.high < 0) vv.ll = -vv.ll; - (void) __udivmoddi4 (uu.ll, vv.ll, (UDWtype*)&w); + (void) __udivmoddi4 (uu.ll, vv.ll, &w); if (c) w = -w; @@ -1159,7 +1167,10 @@ __ucmpdi2 (DWtype a, DWtype b) } #endif -#if defined(L_fixunstfdi) && LIBGCC2_HAS_TF_MODE +#if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128) +#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) +#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) + DWtype __fixunstfDI (TFtype a) { @@ -1167,11 +1178,11 @@ __fixunstfDI (TFtype a) return 0; /* Compute high word of result, as a flonum. */ - const TFtype b = (a / Wtype_MAXp1_F); + const TFtype b = (a / HIGH_WORD_COEFF); /* Convert that to fixed (but not to DWtype!), and shift it into the high word. */ UDWtype v = (UWtype) b; - v <<= W_TYPE_SIZE; + v <<= WORD_SIZE; /* Remove high part from the TFtype, leaving the low part as flonum. */ a -= (TFtype)v; /* Convert that to fixed (but not to DWtype!) and add it in. @@ -1185,7 +1196,7 @@ __fixunstfDI (TFtype a) } #endif -#if defined(L_fixtfdi) && LIBGCC2_HAS_TF_MODE +#if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128) DWtype __fixtfdi (TFtype a) { @@ -1195,7 +1206,10 @@ __fixtfdi (TFtype a) } #endif -#if defined(L_fixunsxfdi) && LIBGCC2_HAS_XF_MODE +#if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96) +#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) +#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) + DWtype __fixunsxfDI (XFtype a) { @@ -1203,11 +1217,11 @@ __fixunsxfDI (XFtype a) return 0; /* Compute high word of result, as a flonum. */ - const XFtype b = (a / Wtype_MAXp1_F); + const XFtype b = (a / HIGH_WORD_COEFF); /* Convert that to fixed (but not to DWtype!), and shift it into the high word. */ UDWtype v = (UWtype) b; - v <<= W_TYPE_SIZE; + v <<= WORD_SIZE; /* Remove high part from the XFtype, leaving the low part as flonum. */ a -= (XFtype)v; /* Convert that to fixed (but not to DWtype!) and add it in. @@ -1221,7 +1235,7 @@ __fixunsxfDI (XFtype a) } #endif -#if defined(L_fixxfdi) && LIBGCC2_HAS_XF_MODE +#if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96) DWtype __fixxfdi (XFtype a) { @@ -1231,26 +1245,29 @@ __fixxfdi (XFtype a) } #endif -#if defined(L_fixunsdfdi) && LIBGCC2_HAS_DF_MODE +#ifdef L_fixunsdfdi +#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) +#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) + DWtype __fixunsdfDI (DFtype a) { /* Get high part of result. The division here will just moves the radix point and will not cause any rounding. Then the conversion to integral type chops result as desired. */ - const UWtype hi = a / Wtype_MAXp1_F; + const UWtype hi = a / HIGH_WORD_COEFF; /* Get low part of result. Convert `hi' to floating type and scale it back, then subtract this from the number being converted. This leaves the low part. Convert that to integral type. */ - const UWtype lo = a - (DFtype) hi * Wtype_MAXp1_F; + const UWtype lo = (a - ((DFtype) hi) * HIGH_WORD_COEFF); /* Assemble result from the two parts. */ - return ((UDWtype) hi << W_TYPE_SIZE) | lo; + return ((UDWtype) hi << WORD_SIZE) | lo; } #endif -#if defined(L_fixdfdi) && LIBGCC2_HAS_DF_MODE +#ifdef L_fixdfdi DWtype __fixdfdi (DFtype a) { @@ -1260,71 +1277,34 @@ __fixdfdi (DFtype a) } #endif -#if defined(L_fixunssfdi) && LIBGCC2_HAS_SF_MODE +#ifdef L_fixunssfdi +#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) +#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) + DWtype -__fixunssfDI (SFtype a) +__fixunssfDI (SFtype original_a) { -#if LIBGCC2_HAS_DF_MODE /* Convert the SFtype to a DFtype, because that is surely not going to lose any bits. Some day someone else can write a faster version that avoids converting to DFtype, and verify it really works right. */ - const DFtype dfa = a; + const DFtype a = original_a; /* Get high part of result. The division here will just moves the radix point and will not cause any rounding. Then the conversion to integral type chops result as desired. */ - const UWtype hi = dfa / Wtype_MAXp1_F; + const UWtype hi = a / HIGH_WORD_COEFF; /* Get low part of result. Convert `hi' to floating type and scale it back, then subtract this from the number being converted. This leaves the low part. Convert that to integral type. */ - const UWtype lo = dfa - (DFtype) hi * Wtype_MAXp1_F; + const UWtype lo = (a - ((DFtype) hi) * HIGH_WORD_COEFF); /* Assemble result from the two parts. */ - return ((UDWtype) hi << W_TYPE_SIZE) | lo; -#elif FLT_MANT_DIG < W_TYPE_SIZE - if (a < 1) - return 0; - if (a < Wtype_MAXp1_F) - return (UWtype)a; - if (a < Wtype_MAXp1_F * Wtype_MAXp1_F) - { - /* Since we know that there are fewer significant bits in the SFmode - quantity than in a word, we know that we can convert out all the - significant bits in one step, and thus avoid losing bits. */ - - /* ??? This following loop essentially performs frexpf. If we could - use the real libm function, or poke at the actual bits of the fp - format, it would be significantly faster. */ - - UWtype shift = 0, counter; - SFtype msb; - - a /= Wtype_MAXp1_F; - for (counter = W_TYPE_SIZE / 2; counter != 0; counter >>= 1) - { - SFtype counterf = (UWtype)1 << counter; - if (a >= counterf) - { - shift |= counter; - a /= counterf; - } - } - - /* Rescale into the range of one word, extract the bits of that - one word, and shift the result into position. */ - a *= Wtype_MAXp1_F; - counter = a; - return (DWtype)counter << shift; - } - return -1; -#else -# error -#endif + return ((UDWtype) hi << WORD_SIZE) | lo; } #endif -#if defined(L_fixsfdi) && LIBGCC2_HAS_SF_MODE +#ifdef L_fixsfdi DWtype __fixsfdi (SFtype a) { @@ -1334,280 +1314,102 @@ __fixsfdi (SFtype a) } #endif -#if defined(L_floatdixf) && LIBGCC2_HAS_XF_MODE +#if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96) +#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) +#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2)) +#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) + XFtype __floatdixf (DWtype u) { -#if W_TYPE_SIZE > XF_SIZE -# error -#endif - XFtype d = (Wtype) (u >> W_TYPE_SIZE); - d *= Wtype_MAXp1_F; - d += (UWtype)u; - return d; -} -#endif + XFtype d = (Wtype) (u >> WORD_SIZE); + d *= HIGH_HALFWORD_COEFF; + d *= HIGH_HALFWORD_COEFF; + d += (UWtype) (u & (HIGH_WORD_COEFF - 1)); -#if defined(L_floatundixf) && LIBGCC2_HAS_XF_MODE -XFtype -__floatundixf (UDWtype u) -{ -#if W_TYPE_SIZE > XF_SIZE -# error -#endif - XFtype d = (UWtype) (u >> W_TYPE_SIZE); - d *= Wtype_MAXp1_F; - d += (UWtype)u; return d; } #endif -#if defined(L_floatditf) && LIBGCC2_HAS_TF_MODE +#if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128) +#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) +#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2)) +#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) + TFtype __floatditf (DWtype u) { -#if W_TYPE_SIZE > TF_SIZE -# error -#endif - TFtype d = (Wtype) (u >> W_TYPE_SIZE); - d *= Wtype_MAXp1_F; - d += (UWtype)u; - return d; -} -#endif + TFtype d = (Wtype) (u >> WORD_SIZE); + d *= HIGH_HALFWORD_COEFF; + d *= HIGH_HALFWORD_COEFF; + d += (UWtype) (u & (HIGH_WORD_COEFF - 1)); -#if defined(L_floatunditf) && LIBGCC2_HAS_TF_MODE -TFtype -__floatunditf (UDWtype u) -{ -#if W_TYPE_SIZE > TF_SIZE -# error -#endif - TFtype d = (UWtype) (u >> W_TYPE_SIZE); - d *= Wtype_MAXp1_F; - d += (UWtype)u; return d; } #endif -#if (defined(L_floatdisf) && LIBGCC2_HAS_SF_MODE) \ - || (defined(L_floatdidf) && LIBGCC2_HAS_DF_MODE) -#define DI_SIZE (W_TYPE_SIZE * 2) -#define F_MODE_OK(SIZE) \ - (SIZE < DI_SIZE \ - && SIZE > (DI_SIZE - SIZE + FSSIZE) \ - /* Don't use IBM Extended Double TFmode for TI->SF calculations. \ - The conversion from long double to float suffers from double \ - rounding, because we convert via double. In any case, the \ - fallback code is faster. */ \ - && !IS_IBM_EXTENDED (SIZE)) -#if defined(L_floatdisf) -#define FUNC __floatdisf -#define FSTYPE SFtype -#define FSSIZE SF_SIZE -#else -#define FUNC __floatdidf -#define FSTYPE DFtype -#define FSSIZE DF_SIZE -#endif - -FSTYPE -FUNC (DWtype u) -{ -#if FSSIZE >= W_TYPE_SIZE - /* When the word size is small, we never get any rounding error. */ - FSTYPE f = (Wtype) (u >> W_TYPE_SIZE); - f *= Wtype_MAXp1_F; - f += (UWtype)u; - return f; -#elif (LIBGCC2_HAS_DF_MODE && F_MODE_OK (DF_SIZE)) \ - || (LIBGCC2_HAS_XF_MODE && F_MODE_OK (XF_SIZE)) \ - || (LIBGCC2_HAS_TF_MODE && F_MODE_OK (TF_SIZE)) - -#if (LIBGCC2_HAS_DF_MODE && F_MODE_OK (DF_SIZE)) -# define FSIZE DF_SIZE -# define FTYPE DFtype -#elif (LIBGCC2_HAS_XF_MODE && F_MODE_OK (XF_SIZE)) -# define FSIZE XF_SIZE -# define FTYPE XFtype -#elif (LIBGCC2_HAS_TF_MODE && F_MODE_OK (TF_SIZE)) -# define FSIZE TF_SIZE -# define FTYPE TFtype -#else -# error -#endif - -#define REP_BIT ((UDWtype) 1 << (DI_SIZE - FSIZE)) - - /* Protect against double-rounding error. - Represent any low-order bits, that might be truncated by a bit that - won't be lost. The bit can go in anywhere below the rounding position - of the FSTYPE. A fixed mask and bit position handles all usual - configurations. */ - if (! (- ((DWtype) 1 << FSIZE) < u - && u < ((DWtype) 1 << FSIZE))) - { - if ((UDWtype) u & (REP_BIT - 1)) - { - u &= ~ (REP_BIT - 1); - u |= REP_BIT; - } - } +#ifdef L_floatdidf +#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) +#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2)) +#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) - /* Do the calculation in a wider type so that we don't lose any of - the precision of the high word while multiplying it. */ - FTYPE f = (Wtype) (u >> W_TYPE_SIZE); - f *= Wtype_MAXp1_F; - f += (UWtype)u; - return (FSTYPE) f; -#else -#if FSSIZE >= W_TYPE_SIZE - 2 -# error -#endif - /* Finally, the word size is larger than the number of bits in the - required FSTYPE, and we've got no suitable wider type. The only - way to avoid double rounding is to special case the - extraction. */ - - /* If there are no high bits set, fall back to one conversion. */ - if ((Wtype)u == u) - return (FSTYPE)(Wtype)u; - - /* Otherwise, find the power of two. */ - Wtype hi = u >> W_TYPE_SIZE; - if (hi < 0) - hi = -hi; - - UWtype count, shift; - count_leading_zeros (count, hi); - - /* No leading bits means u == minimum. */ - if (count == 0) - return -(Wtype_MAXp1_F * (Wtype_MAXp1_F / 2)); - - shift = 1 + W_TYPE_SIZE - count; - - /* Shift down the most significant bits. */ - hi = u >> shift; - - /* If we lost any nonzero bits, set the lsb to ensure correct rounding. */ - if (u & (((DWtype)1 << shift) - 1)) - hi |= 1; +DFtype +__floatdidf (DWtype u) +{ + DFtype d = (Wtype) (u >> WORD_SIZE); + d *= HIGH_HALFWORD_COEFF; + d *= HIGH_HALFWORD_COEFF; + d += (UWtype) (u & (HIGH_WORD_COEFF - 1)); - /* Convert the one word of data, and rescale. */ - FSTYPE f = hi; - f *= (UDWtype)1 << shift; - return f; -#endif + return d; } #endif -#if (defined(L_floatundisf) && LIBGCC2_HAS_SF_MODE) \ - || (defined(L_floatundidf) && LIBGCC2_HAS_DF_MODE) -#define DI_SIZE (W_TYPE_SIZE * 2) -#define F_MODE_OK(SIZE) \ - (SIZE < DI_SIZE \ - && SIZE > (DI_SIZE - SIZE + FSSIZE) \ - /* Don't use IBM Extended Double TFmode for TI->SF calculations. \ - The conversion from long double to float suffers from double \ - rounding, because we convert via double. In any case, the \ - fallback code is faster. */ \ - && !IS_IBM_EXTENDED (SIZE)) -#if defined(L_floatundisf) -#define FUNC __floatundisf -#define FSTYPE SFtype -#define FSSIZE SF_SIZE -#else -#define FUNC __floatundidf -#define FSTYPE DFtype -#define FSSIZE DF_SIZE -#endif - -FSTYPE -FUNC (UDWtype u) -{ -#if FSSIZE >= W_TYPE_SIZE - /* When the word size is small, we never get any rounding error. */ - FSTYPE f = (UWtype) (u >> W_TYPE_SIZE); - f *= Wtype_MAXp1_F; - f += (UWtype)u; - return f; -#elif (LIBGCC2_HAS_DF_MODE && F_MODE_OK (DF_SIZE)) \ - || (LIBGCC2_HAS_XF_MODE && F_MODE_OK (XF_SIZE)) \ - || (LIBGCC2_HAS_TF_MODE && F_MODE_OK (TF_SIZE)) - -#if (LIBGCC2_HAS_DF_MODE && F_MODE_OK (DF_SIZE)) -# define FSIZE DF_SIZE -# define FTYPE DFtype -#elif (LIBGCC2_HAS_XF_MODE && F_MODE_OK (XF_SIZE)) -# define FSIZE XF_SIZE -# define FTYPE XFtype -#elif (LIBGCC2_HAS_TF_MODE && F_MODE_OK (TF_SIZE)) -# define FSIZE TF_SIZE -# define FTYPE TFtype -#else -# error -#endif +#ifdef L_floatdisf +#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT) +#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2)) +#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE) -#define REP_BIT ((UDWtype) 1 << (DI_SIZE - FSIZE)) +#define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT) +#define DF_SIZE DBL_MANT_DIG +#define SF_SIZE FLT_MANT_DIG +SFtype +__floatdisf (DWtype u) +{ /* Protect against double-rounding error. - Represent any low-order bits, that might be truncated by a bit that - won't be lost. The bit can go in anywhere below the rounding position - of the FSTYPE. A fixed mask and bit position handles all usual - configurations. */ - if (u >= ((UDWtype) 1 << FSIZE)) + Represent any low-order bits, that might be truncated in DFmode, + by a bit that won't be lost. The bit can go in anywhere below the + rounding position of the SFmode. A fixed mask and bit position + handles all usual configurations. It doesn't handle the case + of 128-bit DImode, however. */ + if (DF_SIZE < DI_SIZE + && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE)) { - if ((UDWtype) u & (REP_BIT - 1)) +#define REP_BIT ((UDWtype) 1 << (DI_SIZE - DF_SIZE)) + if (! (- ((DWtype) 1 << DF_SIZE) < u + && u < ((DWtype) 1 << DF_SIZE))) { - u &= ~ (REP_BIT - 1); - u |= REP_BIT; + if ((UDWtype) u & (REP_BIT - 1)) + { + u &= ~ (REP_BIT - 1); + u |= REP_BIT; + } } } + /* Do the calculation in DFmode + so that we don't lose any of the precision of the high word + while multiplying it. */ + DFtype f = (Wtype) (u >> WORD_SIZE); + f *= HIGH_HALFWORD_COEFF; + f *= HIGH_HALFWORD_COEFF; + f += (UWtype) (u & (HIGH_WORD_COEFF - 1)); - /* Do the calculation in a wider type so that we don't lose any of - the precision of the high word while multiplying it. */ - FTYPE f = (UWtype) (u >> W_TYPE_SIZE); - f *= Wtype_MAXp1_F; - f += (UWtype)u; - return (FSTYPE) f; -#else -#if FSSIZE == W_TYPE_SIZE - 1 -# error -#endif - /* Finally, the word size is larger than the number of bits in the - required FSTYPE, and we've got no suitable wider type. The only - way to avoid double rounding is to special case the - extraction. */ - - /* If there are no high bits set, fall back to one conversion. */ - if ((UWtype)u == u) - return (FSTYPE)(UWtype)u; - - /* Otherwise, find the power of two. */ - UWtype hi = u >> W_TYPE_SIZE; - - UWtype count, shift; - count_leading_zeros (count, hi); - - shift = W_TYPE_SIZE - count; - - /* Shift down the most significant bits. */ - hi = u >> shift; - - /* If we lost any nonzero bits, set the lsb to ensure correct rounding. */ - if (u & (((UDWtype)1 << shift) - 1)) - hi |= 1; - - /* Convert the one word of data, and rescale. */ - FSTYPE f = hi; - f *= (UDWtype)1 << shift; - return f; -#endif + return (SFtype) f; } #endif -#if defined(L_fixunsxfsi) && LIBGCC2_HAS_XF_MODE +#if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96 /* Reenable the normal types, in case limits.h needs them. */ #undef char #undef short @@ -1629,7 +1431,7 @@ __fixunsxfSI (XFtype a) } #endif -#if defined(L_fixunsdfsi) && LIBGCC2_HAS_DF_MODE +#ifdef L_fixunsdfsi /* Reenable the normal types, in case limits.h needs them. */ #undef char #undef short @@ -1651,7 +1453,7 @@ __fixunsdfSI (DFtype a) } #endif -#if defined(L_fixunssfsi) && LIBGCC2_HAS_SF_MODE +#ifdef L_fixunssfsi /* Reenable the normal types, in case limits.h needs them. */ #undef char #undef short @@ -1673,245 +1475,6 @@ __fixunssfSI (SFtype a) } #endif -/* Integer power helper used from __builtin_powi for non-constant - exponents. */ - -#if (defined(L_powisf2) && LIBGCC2_HAS_SF_MODE) \ - || (defined(L_powidf2) && LIBGCC2_HAS_DF_MODE) \ - || (defined(L_powixf2) && LIBGCC2_HAS_XF_MODE) \ - || (defined(L_powitf2) && LIBGCC2_HAS_TF_MODE) -# if defined(L_powisf2) -# define TYPE SFtype -# define NAME __powisf2 -# elif defined(L_powidf2) -# define TYPE DFtype -# define NAME __powidf2 -# elif defined(L_powixf2) -# define TYPE XFtype -# define NAME __powixf2 -# elif defined(L_powitf2) -# define TYPE TFtype -# define NAME __powitf2 -# endif - -#undef int -#undef unsigned -TYPE -NAME (TYPE x, int m) -{ - unsigned int n = m < 0 ? -m : m; - TYPE y = n % 2 ? x : 1; - while (n >>= 1) - { - x = x * x; - if (n % 2) - y = y * x; - } - return m < 0 ? 1/y : y; -} - -#endif - -#if ((defined(L_mulsc3) || defined(L_divsc3)) && LIBGCC2_HAS_SF_MODE) \ - || ((defined(L_muldc3) || defined(L_divdc3)) && LIBGCC2_HAS_DF_MODE) \ - || ((defined(L_mulxc3) || defined(L_divxc3)) && LIBGCC2_HAS_XF_MODE) \ - || ((defined(L_multc3) || defined(L_divtc3)) && LIBGCC2_HAS_TF_MODE) - -#undef float -#undef double -#undef long - -#if defined(L_mulsc3) || defined(L_divsc3) -# define MTYPE SFtype -# define CTYPE SCtype -# define MODE sc -# define CEXT f -# define NOTRUNC __FLT_EVAL_METHOD__ == 0 -#elif defined(L_muldc3) || defined(L_divdc3) -# define MTYPE DFtype -# define CTYPE DCtype -# define MODE dc -# if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 64 -# define CEXT l -# define NOTRUNC 1 -# else -# define CEXT -# define NOTRUNC __FLT_EVAL_METHOD__ == 0 || __FLT_EVAL_METHOD__ == 1 -# endif -#elif defined(L_mulxc3) || defined(L_divxc3) -# define MTYPE XFtype -# define CTYPE XCtype -# define MODE xc -# define CEXT l -# define NOTRUNC 1 -#elif defined(L_multc3) || defined(L_divtc3) -# define MTYPE TFtype -# define CTYPE TCtype -# define MODE tc -# define CEXT l -# define NOTRUNC 1 -#else -# error -#endif - -#define CONCAT3(A,B,C) _CONCAT3(A,B,C) -#define _CONCAT3(A,B,C) A##B##C - -#define CONCAT2(A,B) _CONCAT2(A,B) -#define _CONCAT2(A,B) A##B - -/* All of these would be present in a full C99 implementation of <math.h> - and <complex.h>. Our problem is that only a few systems have such full - implementations. Further, libgcc_s.so isn't currently linked against - libm.so, and even for systems that do provide full C99, the extra overhead - of all programs using libgcc having to link against libm. So avoid it. */ - -#define isnan(x) __builtin_expect ((x) != (x), 0) -#define isfinite(x) __builtin_expect (!isnan((x) - (x)), 1) -#define isinf(x) __builtin_expect (!isnan(x) & !isfinite(x), 0) - -#define INFINITY CONCAT2(__builtin_inf, CEXT) () -#define I 1i - -/* Helpers to make the following code slightly less gross. */ -#define COPYSIGN CONCAT2(__builtin_copysign, CEXT) -#define FABS CONCAT2(__builtin_fabs, CEXT) - -/* Verify that MTYPE matches up with CEXT. */ -extern void *compile_type_assert[sizeof(INFINITY) == sizeof(MTYPE) ? 1 : -1]; - -/* Ensure that we've lost any extra precision. */ -#if NOTRUNC -# define TRUNC(x) -#else -# define TRUNC(x) __asm__ ("" : "=m"(x) : "m"(x)) -#endif - -#if defined(L_mulsc3) || defined(L_muldc3) \ - || defined(L_mulxc3) || defined(L_multc3) - -CTYPE -CONCAT3(__mul,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d) -{ - MTYPE ac, bd, ad, bc, x, y; - - ac = a * c; - bd = b * d; - ad = a * d; - bc = b * c; - - TRUNC (ac); - TRUNC (bd); - TRUNC (ad); - TRUNC (bc); - - x = ac - bd; - y = ad + bc; - - if (isnan (x) && isnan (y)) - { - /* Recover infinities that computed as NaN + iNaN. */ - _Bool recalc = 0; - if (isinf (a) || isinf (b)) - { - /* z is infinite. "Box" the infinity and change NaNs in - the other factor to 0. */ - a = COPYSIGN (isinf (a) ? 1 : 0, a); - b = COPYSIGN (isinf (b) ? 1 : 0, b); - if (isnan (c)) c = COPYSIGN (0, c); - if (isnan (d)) d = COPYSIGN (0, d); - recalc = 1; - } - if (isinf (c) || isinf (d)) - { - /* w is infinite. "Box" the infinity and change NaNs in - the other factor to 0. */ - c = COPYSIGN (isinf (c) ? 1 : 0, c); - d = COPYSIGN (isinf (d) ? 1 : 0, d); - if (isnan (a)) a = COPYSIGN (0, a); - if (isnan (b)) b = COPYSIGN (0, b); - recalc = 1; - } - if (!recalc - && (isinf (ac) || isinf (bd) - || isinf (ad) || isinf (bc))) - { - /* Recover infinities from overflow by changing NaNs to 0. */ - if (isnan (a)) a = COPYSIGN (0, a); - if (isnan (b)) b = COPYSIGN (0, b); - if (isnan (c)) c = COPYSIGN (0, c); - if (isnan (d)) d = COPYSIGN (0, d); - recalc = 1; - } - if (recalc) - { - x = INFINITY * (a * c - b * d); - y = INFINITY * (a * d + b * c); - } - } - - return x + I * y; -} -#endif /* complex multiply */ - -#if defined(L_divsc3) || defined(L_divdc3) \ - || defined(L_divxc3) || defined(L_divtc3) - -CTYPE -CONCAT3(__div,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d) -{ - MTYPE denom, ratio, x, y; - - /* ??? We can get better behavior from logarithmic scaling instead of - the division. But that would mean starting to link libgcc against - libm. We could implement something akin to ldexp/frexp as gcc builtins - fairly easily... */ - if (FABS (c) < FABS (d)) - { - ratio = c / d; - denom = (c * ratio) + d; - x = ((a * ratio) + b) / denom; - y = ((b * ratio) - a) / denom; - } - else - { - ratio = d / c; - denom = (d * ratio) + c; - x = ((b * ratio) + a) / denom; - y = (b - (a * ratio)) / denom; - } - - /* Recover infinities and zeros that computed as NaN+iNaN; the only cases - are nonzero/zero, infinite/finite, and finite/infinite. */ - if (isnan (x) && isnan (y)) - { - if (c == 0.0 && d == 0.0 && (!isnan (a) || !isnan (b))) - { - x = COPYSIGN (INFINITY, c) * a; - y = COPYSIGN (INFINITY, c) * b; - } - else if ((isinf (a) || isinf (b)) && isfinite (c) && isfinite (d)) - { - a = COPYSIGN (isinf (a) ? 1 : 0, a); - b = COPYSIGN (isinf (b) ? 1 : 0, b); - x = INFINITY * (a * c + b * d); - y = INFINITY * (b * c - a * d); - } - else if ((isinf (c) || isinf (d)) && isfinite (a) && isfinite (b)) - { - c = COPYSIGN (isinf (c) ? 1 : 0, c); - d = COPYSIGN (isinf (d) ? 1 : 0, d); - x = 0.0 * (a * c + b * d); - y = 0.0 * (b * c - a * d); - } - } - - return x + I * y; -} -#endif /* complex divide */ - -#endif /* all complex float routines */ - /* From here on down, the routines use normal data types. */ #define SItype bogus_type @@ -2012,7 +1575,7 @@ __enable_execute_stack (void *addr __attribute__((__unused__))) #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN) -int +long getpagesize (void) { #ifdef _ALPHA_ @@ -2061,7 +1624,6 @@ TRANSFER_FROM_TRAMPOLINE #ifdef L__main #include "gbl-ctors.h" - /* Some systems use __main in a way incompatible with its use in gcc, in these cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to give the same symbol without quotes for an alternative entry point. You @@ -2071,7 +1633,7 @@ TRANSFER_FROM_TRAMPOLINE #define SYMBOL__MAIN __main #endif -#if defined (INIT_SECTION_ASM_OP) || defined (INIT_ARRAY_SECTION_ASM_OP) +#ifdef INIT_SECTION_ASM_OP #undef HAS_INIT_SECTION #define HAS_INIT_SECTION #endif @@ -2184,4 +1746,4 @@ func_ptr __DTOR_LIST__[2]; #endif #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */ #endif /* L_ctors */ -#endif /* LIBGCC2_UNITS_PER_WORD <= MIN_UNITS_PER_WORD */ + |