summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/libgcc2.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/libgcc2.c')
-rw-r--r--contrib/gcc/libgcc2.c740
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 */
+
OpenPOWER on IntegriCloud