OSDN Git Service

Index: gcc/ChangeLog
[pf3gnuchains/gcc-fork.git] / gcc / libgcc2.c
index 0827d83..68623c3 100644 (file)
@@ -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  Free Software Foundation, Inc.
+   2000, 2001, 2002, 2003, 2004, 2005  Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -63,13 +63,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 DWtype
 __negdi2 (DWtype u)
 {
-  DWunion w;
-  DWunion uu;
-
-  uu.ll = u;
-
-  w.s.low = -uu.s.low;
-  w.s.high = -uu.s.high - ((UWtype) w.s.low > 0);
+  const DWunion uu = {.ll = u};
+  const DWunion w = { {.low = -uu.s.low,
+                      .high = -uu.s.high - ((UWtype) -uu.s.low > 0) } };
 
   return w.ll;
 }
@@ -77,26 +73,34 @@ __negdi2 (DWtype u)
 
 #ifdef L_addvsi3
 Wtype
-__addvsi3 (Wtype a, Wtype b)
+__addvSI3 (Wtype a, Wtype b)
 {
-  Wtype w;
+  const Wtype w = a + b;
+
+  if (b >= 0 ? w < a : w > a)
+    abort ();
 
-  w = a + b;
+  return w;
+}
+#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
+SItype
+__addvsi3 (SItype a, SItype b)
+{
+  const SItype w = a + b;
 
   if (b >= 0 ? w < a : w > a)
     abort ();
 
   return w;
 }
+#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
 #endif
 \f
 #ifdef L_addvdi3
 DWtype
-__addvdi3 (DWtype a, DWtype b)
+__addvDI3 (DWtype a, DWtype b)
 {
-  DWtype w;
-
-  w = a + b;
+  const DWtype w = a + b;
 
   if (b >= 0 ? w < a : w > a)
     abort ();
@@ -107,26 +111,34 @@ __addvdi3 (DWtype a, DWtype b)
 \f
 #ifdef L_subvsi3
 Wtype
-__subvsi3 (Wtype a, Wtype b)
+__subvSI3 (Wtype a, Wtype b)
 {
-  DWtype w;
+  const Wtype w = a - b;
 
-  w = a - b;
+  if (b >= 0 ? w > a : w < a)
+    abort ();
+
+  return w;
+}
+#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
+SItype
+__subvsi3 (SItype a, SItype b)
+{
+  const SItype w = a - b;
 
   if (b >= 0 ? w > a : w < a)
     abort ();
 
   return w;
 }
+#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
 #endif
 \f
 #ifdef L_subvdi3
 DWtype
-__subvdi3 (DWtype a, DWtype b)
+__subvDI3 (DWtype a, DWtype b)
 {
-  DWtype w;
-
-  w = a - b;
+  const DWtype w = a - b;
 
   if (b >= 0 ? w > a : w < a)
     abort ();
@@ -136,45 +148,62 @@ __subvdi3 (DWtype a, DWtype b)
 #endif
 \f
 #ifdef L_mulvsi3
-#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
 Wtype
-__mulvsi3 (Wtype a, Wtype b)
+__mulvSI3 (Wtype a, Wtype b)
 {
-  DWtype w;
+  const DWtype w = (DWtype) a * (DWtype) b;
 
-  w = (DWtype) a * (DWtype) b;
+  if ((Wtype) (w >> W_TYPE_SIZE) != (Wtype) w >> (W_TYPE_SIZE - 1))
+    abort ();
 
-  if (((a >= 0) == (b >= 0))
-      ? (UDWtype) w > (UDWtype) (((DWtype) 1 << (WORD_SIZE - 1)) - 1)
-      : (UDWtype) w < (UDWtype) ((DWtype) -1 << (WORD_SIZE - 1)))
+  return w;
+}
+#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
+#undef WORD_SIZE
+#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
+SItype
+__mulvsi3 (SItype a, SItype b)
+{
+  const DItype w = (DItype) a * (DItype) b;
+
+  if ((SItype) (w >> WORD_SIZE) != (SItype) w >> (WORD_SIZE-1))
     abort ();
 
   return w;
 }
+#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
 #endif
 \f
 #ifdef L_negvsi2
 Wtype
-__negvsi2 (Wtype a)
+__negvSI2 (Wtype a)
 {
-  Wtype w;
+  const Wtype w = -a;
+
+  if (a >= 0 ? w > 0 : w < 0)
+    abort ();
 
-  w  = -a;
+   return w;
+}
+#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
+SItype
+__negvsi2 (SItype a)
+{
+  const SItype w = -a;
 
   if (a >= 0 ? w > 0 : w < 0)
     abort ();
 
    return w;
 }
+#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
 #endif
 \f
 #ifdef L_negvdi2
 DWtype
-__negvdi2 (DWtype a)
+__negvDI2 (DWtype a)
 {
-  DWtype w;
-
-  w  = -a;
+  const DWtype w = -a;
 
   if (a >= 0 ? w > 0 : w < 0)
     abort ();
@@ -185,12 +214,30 @@ __negvdi2 (DWtype a)
 \f
 #ifdef L_absvsi2
 Wtype
-__absvsi2 (Wtype a)
+__absvSI2 (Wtype a)
 {
   Wtype w = a;
 
   if (a < 0)
 #ifdef L_negvsi2
+    w = __negvSI2 (a);
+#else
+    w = -a;
+
+  if (w < 0)
+    abort ();
+#endif
+
+   return w;
+}
+#ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
+SItype
+__absvsi2 (SItype a)
+{
+  SItype w = a;
+
+  if (a < 0)
+#ifdef L_negvsi2
     w = __negvsi2 (a);
 #else
     w = -a;
@@ -201,17 +248,18 @@ __absvsi2 (Wtype a)
 
    return w;
 }
+#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
 #endif
 \f
 #ifdef L_absvdi2
 DWtype
-__absvdi2 (DWtype a)
+__absvDI2 (DWtype a)
 {
   DWtype w = a;
 
   if (a < 0)
 #ifdef L_negvdi2
-    w = __negvdi2 (a);
+    w = __negvDI2 (a);
 #else
     w = -a;
 
@@ -224,21 +272,18 @@ __absvdi2 (DWtype a)
 #endif
 \f
 #ifdef L_mulvdi3
-#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
 DWtype
-__mulvdi3 (DWtype u, DWtype v)
+__mulvDI3 (DWtype u, DWtype v)
 {
   /* The unchecked multiplication needs 3 Wtype x Wtype multiplications,
      but the checked multiplication needs only two.  */
-  DWunion uu, vv;
+  const DWunion uu = {.ll = u};
+  const DWunion vv = {.ll = v};
 
-  uu.ll = u;
-  vv.ll = v;
-
-  if (__builtin_expect (uu.s.high == uu.s.low >> (WORD_SIZE - 1), 1))
+  if (__builtin_expect (uu.s.high == uu.s.low >> (W_TYPE_SIZE - 1), 1))
     {
       /* u fits in a single Wtype.  */
-      if (__builtin_expect (vv.s.high == vv.s.low >> (WORD_SIZE - 1), 1))
+      if (__builtin_expect (vv.s.high == vv.s.low >> (W_TYPE_SIZE - 1), 1))
        {
          /* v fits in a single Wtype as well.  */
          /* A single multiplication.  No overflow risk.  */
@@ -247,16 +292,17 @@ __mulvdi3 (DWtype u, DWtype v)
       else
        {
          /* Two multiplications.  */
-         DWunion w0, w1;
+         DWunion w0 = {.ll = (UDWtype) (UWtype) uu.s.low
+                       * (UDWtype) (UWtype) vv.s.low};
+         DWunion w1 = {.ll = (UDWtype) (UWtype) uu.s.low
+                       * (UDWtype) (UWtype) vv.s.high};
 
-         w0.ll = (UDWtype) (UWtype) uu.s.low * (UDWtype) (UWtype) vv.s.low;
-         w1.ll = (UDWtype) (UWtype) uu.s.low * (UDWtype) (UWtype) vv.s.high;
          if (vv.s.high < 0)
            w1.s.high -= uu.s.low;
          if (uu.s.low < 0)
            w1.ll -= vv.ll;
          w1.ll += (UWtype) w0.s.high;
-         if (__builtin_expect (w1.s.high == w1.s.low >> (WORD_SIZE - 1), 1))
+         if (__builtin_expect (w1.s.high == w1.s.low >> (W_TYPE_SIZE - 1), 1))
            {
              w0.s.high = w1.s.low;
              return w0.ll;
@@ -265,20 +311,21 @@ __mulvdi3 (DWtype u, DWtype v)
     }
   else
     {
-      if (__builtin_expect (vv.s.high == vv.s.low >> (WORD_SIZE - 1), 1))
+      if (__builtin_expect (vv.s.high == vv.s.low >> (W_TYPE_SIZE - 1), 1))
        {
          /* v fits into a single Wtype.  */
          /* Two multiplications.  */
-         DWunion w0, w1;
+         DWunion w0 = {.ll = (UDWtype) (UWtype) uu.s.low
+                       * (UDWtype) (UWtype) vv.s.low};
+         DWunion w1 = {.ll = (UDWtype) (UWtype) uu.s.high
+                       * (UDWtype) (UWtype) vv.s.low};
 
-         w0.ll = (UDWtype) (UWtype) uu.s.low * (UDWtype) (UWtype) vv.s.low;
-         w1.ll = (UDWtype) (UWtype) uu.s.high * (UDWtype) (UWtype) vv.s.low;
          if (uu.s.high < 0)
            w1.s.high -= vv.s.low;
          if (vv.s.low < 0)
            w1.ll -= uu.ll;
          w1.ll += (UWtype) w0.s.high;
-         if (__builtin_expect (w1.s.high == w1.s.low >> (WORD_SIZE - 1), 1))
+         if (__builtin_expect (w1.s.high == w1.s.low >> (W_TYPE_SIZE - 1), 1))
            {
              w0.s.high = w1.s.low;
              return w0.ll;
@@ -293,10 +340,8 @@ __mulvdi3 (DWtype u, DWtype v)
                {
                  if (uu.s.high == 0 && vv.s.high == 0)
                    {
-                     DWtype w;
-
-                     w = (UDWtype) (UWtype) uu.s.low
-                         * (UDWtype) (UWtype) vv.s.low;
+                     const DWtype w = (UDWtype) (UWtype) uu.s.low
+                       * (UDWtype) (UWtype) vv.s.low;
                      if (__builtin_expect (w >= 0, 1))
                        return w;
                    }
@@ -305,10 +350,9 @@ __mulvdi3 (DWtype u, DWtype v)
                {
                  if (uu.s.high == 0 && vv.s.high == (Wtype) -1)
                    {
-                     DWunion ww;
+                     DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low
+                                   * (UDWtype) (UWtype) vv.s.low};
 
-                     ww.ll = (UDWtype) (UWtype) uu.s.low
-                             * (UDWtype) (UWtype) vv.s.low;
                      ww.s.high -= uu.s.low;
                      if (__builtin_expect (ww.s.high < 0, 1))
                        return ww.ll;
@@ -321,10 +365,9 @@ __mulvdi3 (DWtype u, DWtype v)
                {
                  if (uu.s.high == (Wtype) -1 && vv.s.high == 0)
                    {
-                     DWunion ww;
+                     DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low
+                                   * (UDWtype) (UWtype) vv.s.low};
 
-                     ww.ll = (UDWtype) (UWtype) uu.s.low
-                             * (UDWtype) (UWtype) vv.s.low;
                      ww.s.high -= vv.s.low;
                      if (__builtin_expect (ww.s.high < 0, 1))
                        return ww.ll;
@@ -334,10 +377,9 @@ __mulvdi3 (DWtype u, DWtype v)
                {
                  if (uu.s.high == (Wtype) -1 && vv.s.high == (Wtype) - 1)
                    {
-                     DWunion ww;
+                     DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low
+                                   * (UDWtype) (UWtype) vv.s.low};
 
-                     ww.ll = (UDWtype) (UWtype) uu.s.low
-                             * (UDWtype) (UWtype) vv.s.low;
                      ww.s.high -= uu.s.low;
                      ww.s.high -= vv.s.low;
                      if (__builtin_expect (ww.s.high >= 0, 1))
@@ -360,16 +402,13 @@ __mulvdi3 (DWtype u, DWtype v)
 DWtype
 __lshrdi3 (DWtype u, word_type b)
 {
-  DWunion w;
-  word_type bm;
-  DWunion uu;
-
   if (b == 0)
     return u;
 
-  uu.ll = u;
+  const DWunion uu = {.ll = u};
+  const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
+  DWunion w;
 
-  bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
   if (bm <= 0)
     {
       w.s.high = 0;
@@ -377,7 +416,7 @@ __lshrdi3 (DWtype u, word_type b)
     }
   else
     {
-      UWtype carries = (UWtype) uu.s.high << bm;
+      const UWtype carries = (UWtype) uu.s.high << bm;
 
       w.s.high = (UWtype) uu.s.high >> b;
       w.s.low = ((UWtype) uu.s.low >> b) | carries;
@@ -391,16 +430,13 @@ __lshrdi3 (DWtype u, word_type b)
 DWtype
 __ashldi3 (DWtype u, word_type b)
 {
-  DWunion w;
-  word_type bm;
-  DWunion uu;
-
   if (b == 0)
     return u;
 
-  uu.ll = u;
+  const DWunion uu = {.ll = u};
+  const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
+  DWunion w;
 
-  bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
   if (bm <= 0)
     {
       w.s.low = 0;
@@ -408,7 +444,7 @@ __ashldi3 (DWtype u, word_type b)
     }
   else
     {
-      UWtype carries = (UWtype) uu.s.low >> bm;
+      const UWtype carries = (UWtype) uu.s.low >> bm;
 
       w.s.low = (UWtype) uu.s.low << b;
       w.s.high = ((UWtype) uu.s.high << b) | carries;
@@ -422,16 +458,13 @@ __ashldi3 (DWtype u, word_type b)
 DWtype
 __ashrdi3 (DWtype u, word_type b)
 {
-  DWunion w;
-  word_type bm;
-  DWunion uu;
-
   if (b == 0)
     return u;
 
-  uu.ll = u;
+  const DWunion uu = {.ll = u};
+  const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
+  DWunion w;
 
-  bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
   if (bm <= 0)
     {
       /* w.s.high = 1..1 or 0..0 */
@@ -440,7 +473,7 @@ __ashrdi3 (DWtype u, word_type b)
     }
   else
     {
-      UWtype carries = (UWtype) uu.s.high << bm;
+      const UWtype carries = (UWtype) uu.s.high << bm;
 
       w.s.high = uu.s.high >> b;
       w.s.low = ((UWtype) uu.s.low >> b) | carries;
@@ -452,7 +485,6 @@ __ashrdi3 (DWtype u, word_type b)
 \f
 #ifdef L_ffssi2
 #undef int
-extern int __ffsSI2 (UWtype u);
 int
 __ffsSI2 (UWtype u)
 {
@@ -468,14 +500,12 @@ __ffsSI2 (UWtype u)
 \f
 #ifdef L_ffsdi2
 #undef int
-extern int __ffsDI2 (DWtype u);
 int
 __ffsDI2 (DWtype u)
 {
-  DWunion uu;
+  const DWunion uu = {.ll = u};
   UWtype word, count, add;
 
-  uu.ll = u;
   if (uu.s.low != 0)
     word = uu.s.low, add = 0;
   else if (uu.s.high != 0)
@@ -492,13 +522,10 @@ __ffsDI2 (DWtype u)
 DWtype
 __muldi3 (DWtype u, DWtype v)
 {
-  DWunion w;
-  DWunion uu, vv;
+  const DWunion uu = {.ll = u};
+  const DWunion vv = {.ll = v};
+  DWunion w = {.ll = __umulsidi3 (uu.s.low, vv.s.low)};
 
-  uu.ll = u,
-  vv.ll = v;
-
-  w.ll = __umulsidi3 (uu.s.low, vv.s.low);
   w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
               + (UWtype) uu.s.high * (UWtype) vv.s.low);
 
@@ -529,16 +556,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);
        }
     }
@@ -649,7 +676,6 @@ const UQItype __clz_tab[] =
 \f
 #ifdef L_clzsi2
 #undef int
-extern int __clzSI2 (UWtype x);
 int
 __clzSI2 (UWtype x)
 {
@@ -663,15 +689,13 @@ __clzSI2 (UWtype x)
 \f
 #ifdef L_clzdi2
 #undef int
-extern int __clzDI2 (UDWtype x);
 int
 __clzDI2 (UDWtype x)
 {
-  DWunion uu;
+  const DWunion uu = {.ll = x};
   UWtype word;
   Wtype ret, add;
 
-  uu.ll = x;
   if (uu.s.high)
     word = uu.s.high, add = 0;
   else
@@ -684,7 +708,6 @@ __clzDI2 (UDWtype x)
 \f
 #ifdef L_ctzsi2
 #undef int
-extern int __ctzSI2 (UWtype x);
 int
 __ctzSI2 (UWtype x)
 {
@@ -698,15 +721,13 @@ __ctzSI2 (UWtype x)
 \f
 #ifdef L_ctzdi2
 #undef int
-extern int __ctzDI2 (UDWtype x);
 int
 __ctzDI2 (UDWtype x)
 {
-  DWunion uu;
+  const DWunion uu = {.ll = x};
   UWtype word;
   Wtype ret, add;
 
-  uu.ll = x;
   if (uu.s.low)
     word = uu.s.low, add = 0;
   else
@@ -738,7 +759,6 @@ const UQItype __popcount_tab[] =
 \f
 #ifdef L_popcountsi2
 #undef int
-extern int __popcountSI2 (UWtype x);
 int
 __popcountSI2 (UWtype x)
 {
@@ -753,7 +773,6 @@ __popcountSI2 (UWtype x)
 \f
 #ifdef L_popcountdi2
 #undef int
-extern int __popcountDI2 (UDWtype x);
 int
 __popcountDI2 (UDWtype x)
 {
@@ -768,7 +787,6 @@ __popcountDI2 (UDWtype x)
 \f
 #ifdef L_paritysi2
 #undef int
-extern int __paritySI2 (UWtype x);
 int
 __paritySI2 (UWtype x)
 {
@@ -790,15 +808,11 @@ __paritySI2 (UWtype x)
 \f
 #ifdef L_paritydi2
 #undef int
-extern int __parityDI2 (UDWtype x);
 int
 __parityDI2 (UDWtype x)
 {
-  DWunion uu;
-  UWtype nx;
-
-  uu.ll = x;
-  nx = uu.s.low ^ uu.s.high;
+  const DWunion uu = {.ll = x};
+  UWtype nx = uu.s.low ^ uu.s.high;
 
 #if W_TYPE_SIZE > 64
 # error "fill out the table"
@@ -825,16 +839,13 @@ static inline __attribute__ ((__always_inline__))
 UDWtype
 __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
 {
-  DWunion ww;
-  DWunion nn, dd;
+  const DWunion nn = {.ll = n};
+  const DWunion dd = {.ll = d};
   DWunion rr;
   UWtype d0, d1, n0, n1, n2;
   UWtype q0, q1;
   UWtype b, bm;
 
-  nn.ll = n;
-  dd.ll = d;
-
   d0 = dd.s.low;
   d1 = dd.s.high;
   n0 = nn.s.low;
@@ -1034,8 +1045,7 @@ __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
        }
     }
 
-  ww.s.low = q0;
-  ww.s.high = q1;
+  const DWunion ww = {{.low = q0, .high = q1}};
   return ww.ll;
 }
 #endif
@@ -1045,12 +1055,10 @@ DWtype
 __divdi3 (DWtype u, DWtype v)
 {
   word_type c = 0;
-  DWunion uu, vv;
+  DWunion uu = {.ll = u};
+  DWunion vv = {.ll = v};
   DWtype w;
 
-  uu.ll = u;
-  vv.ll = v;
-
   if (uu.s.high < 0)
     c = ~c,
     uu.ll = -uu.ll;
@@ -1071,19 +1079,17 @@ DWtype
 __moddi3 (DWtype u, DWtype v)
 {
   word_type c = 0;
-  DWunion uu, vv;
+  DWunion uu = {.ll = u};
+  DWunion vv = {.ll = v};
   DWtype w;
 
-  uu.ll = u;
-  vv.ll = v;
-
   if (uu.s.high < 0)
     c = ~c,
     uu.ll = -uu.ll;
   if (vv.s.high < 0)
     vv.ll = -vv.ll;
 
-  (void) __udivmoddi4 (uu.ll, vv.ll, &w);
+  (void) __udivmoddi4 (uu.ll, vv.ll, (UDWtype*)&w);
   if (c)
     w = -w;
 
@@ -1115,9 +1121,8 @@ __udivdi3 (UDWtype n, UDWtype d)
 word_type
 __cmpdi2 (DWtype a, DWtype b)
 {
-  DWunion au, bu;
-
-  au.ll = a, bu.ll = b;
+  const DWunion au = {.ll = a};
+  const DWunion bu = {.ll = b};
 
   if (au.s.high < bu.s.high)
     return 0;
@@ -1135,9 +1140,8 @@ __cmpdi2 (DWtype a, DWtype b)
 word_type
 __ucmpdi2 (DWtype a, DWtype b)
 {
-  DWunion au, bu;
-
-  au.ll = a, bu.ll = b;
+  const DWunion au = {.ll = a};
+  const DWunion bu = {.ll = b};
 
   if ((UWtype) au.s.high < (UWtype) bu.s.high)
     return 0;
@@ -1151,25 +1155,19 @@ __ucmpdi2 (DWtype a, DWtype b)
 }
 #endif
 \f
-#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)
-
+#if defined(L_fixunstfdi) && LIBGCC2_HAS_TF_MODE
 DWtype
 __fixunstfDI (TFtype a)
 {
-  TFtype b;
-  UDWtype v;
-
   if (a < 0)
     return 0;
 
   /* Compute high word of result, as a flonum.  */
-  b = (a / HIGH_WORD_COEFF);
+  const TFtype b = (a / Wtype_MAXp1_F);
   /* Convert that to fixed (but not to DWtype!),
      and shift it into the high word.  */
-  v = (UWtype) b;
-  v <<= WORD_SIZE;
+  UDWtype v = (UWtype) b;
+  v <<= W_TYPE_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.
@@ -1183,7 +1181,7 @@ __fixunstfDI (TFtype a)
 }
 #endif
 
-#if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
+#if defined(L_fixtfdi) && LIBGCC2_HAS_TF_MODE
 DWtype
 __fixtfdi (TFtype a)
 {
@@ -1193,25 +1191,19 @@ __fixtfdi (TFtype a)
 }
 #endif
 
-#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)
-
+#if defined(L_fixunsxfdi) && LIBGCC2_HAS_XF_MODE
 DWtype
 __fixunsxfDI (XFtype a)
 {
-  XFtype b;
-  UDWtype v;
-
   if (a < 0)
     return 0;
 
   /* Compute high word of result, as a flonum.  */
-  b = (a / HIGH_WORD_COEFF);
+  const XFtype b = (a / Wtype_MAXp1_F);
   /* Convert that to fixed (but not to DWtype!),
      and shift it into the high word.  */
-  v = (UWtype) b;
-  v <<= WORD_SIZE;
+  UDWtype v = (UWtype) b;
+  v <<= W_TYPE_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.
@@ -1225,7 +1217,7 @@ __fixunsxfDI (XFtype a)
 }
 #endif
 
-#if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
+#if defined(L_fixxfdi) && LIBGCC2_HAS_XF_MODE
 DWtype
 __fixxfdi (XFtype a)
 {
@@ -1235,31 +1227,26 @@ __fixxfdi (XFtype a)
 }
 #endif
 
-#ifdef L_fixunsdfdi
-#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
-#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
-
+#if defined(L_fixunsdfdi) && LIBGCC2_HAS_DF_MODE
 DWtype
 __fixunsdfDI (DFtype a)
 {
-  UWtype hi, lo;
-
   /* 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.  */
-  hi = a / HIGH_WORD_COEFF;
+  const UWtype hi = a / Wtype_MAXp1_F;
 
   /* 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.  */
-  lo = (a - ((DFtype) hi) * HIGH_WORD_COEFF);
+  const UWtype lo = a - (DFtype) hi * Wtype_MAXp1_F;
 
   /* Assemble result from the two parts.  */
-  return ((UDWtype) hi << WORD_SIZE) | lo;
+  return ((UDWtype) hi << W_TYPE_SIZE) | lo;
 }
 #endif
 
-#ifdef L_fixdfdi
+#if defined(L_fixdfdi) && LIBGCC2_HAS_DF_MODE
 DWtype
 __fixdfdi (DFtype a)
 {
@@ -1270,30 +1257,66 @@ __fixdfdi (DFtype a)
 #endif
 
 #ifdef L_fixunssfdi
-#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
-#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
-
 DWtype
-__fixunssfDI (SFtype original_a)
+__fixunssfDI (SFtype 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.  */
-  DFtype a = original_a;
-  UWtype hi, lo;
+  const DFtype dfa = 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.  */
-  hi = a / HIGH_WORD_COEFF;
+  const UWtype hi = dfa / Wtype_MAXp1_F;
 
   /* 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.  */
-  lo = (a - ((DFtype) hi) * HIGH_WORD_COEFF);
+  const UWtype lo = dfa - (DFtype) hi * Wtype_MAXp1_F;
 
   /* Assemble result from the two parts.  */
-  return ((UDWtype) hi << WORD_SIZE) | lo;
+  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
 }
 #endif
 
@@ -1307,90 +1330,72 @@ __fixsfdi (SFtype a)
 }
 #endif
 
-#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)
-
+#if defined(L_floatdixf) && LIBGCC2_HAS_XF_MODE
 XFtype
 __floatdixf (DWtype u)
 {
-  XFtype d;
-
-  d = (Wtype) (u >> WORD_SIZE);
-  d *= HIGH_HALFWORD_COEFF;
-  d *= HIGH_HALFWORD_COEFF;
-  d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
-
+  XFtype d = (Wtype) (u >> W_TYPE_SIZE);
+  d *= Wtype_MAXp1_F;
+  d += (UWtype)u;
   return d;
 }
 #endif
 
-#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)
-
+#if defined(L_floatditf) && LIBGCC2_HAS_TF_MODE
 TFtype
 __floatditf (DWtype u)
 {
-  TFtype d;
-
-  d = (Wtype) (u >> WORD_SIZE);
-  d *= HIGH_HALFWORD_COEFF;
-  d *= HIGH_HALFWORD_COEFF;
-  d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
-
+  TFtype d = (Wtype) (u >> W_TYPE_SIZE);
+  d *= Wtype_MAXp1_F;
+  d += (UWtype)u;
   return d;
 }
 #endif
 
-#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)
-
+#if defined(L_floatdidf) && LIBGCC2_HAS_DF_MODE
 DFtype
 __floatdidf (DWtype u)
 {
-  DFtype d;
-
-  d = (Wtype) (u >> WORD_SIZE);
-  d *= HIGH_HALFWORD_COEFF;
-  d *= HIGH_HALFWORD_COEFF;
-  d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
-
+  DFtype d = (Wtype) (u >> W_TYPE_SIZE);
+  d *= Wtype_MAXp1_F;
+  d += (UWtype)u;
   return d;
 }
 #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 DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT)
-#define DF_SIZE DBL_MANT_DIG
+#define DI_SIZE (W_TYPE_SIZE * 2)
 #define SF_SIZE FLT_MANT_DIG
 
 SFtype
 __floatdisf (DWtype u)
 {
-  /* Do the calculation in DFmode
-     so that we don't lose any of the precision of the high word
-     while multiplying it.  */
-  DFtype f;
+#if SF_SIZE >= W_TYPE_SIZE
+  /* When the word size is small, we never get any rounding error.  */
+  SFtype f = (Wtype) (u >> W_TYPE_SIZE);
+  f *= Wtype_MAXp1_F;
+  f += (UWtype)u;
+  return f;
+#elif LIBGCC2_HAS_DF_MODE
+
+#if LIBGCC2_DOUBLE_TYPE_SIZE == 64
+#define DF_SIZE DBL_MANT_DIG
+#elif LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 64
+#define DF_SIZE LDBL_MANT_DIG
+#else
+# error
+#endif
+
+#define REP_BIT ((UDWtype) 1 << (DI_SIZE - DF_SIZE))
 
   /* Protect against double-rounding error.
-     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.  */
+     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 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))
     {
-#define REP_BIT ((UDWtype) 1 << (DI_SIZE - DF_SIZE))
       if (! (- ((DWtype) 1 << DF_SIZE) < u
             && u < ((DWtype) 1 << DF_SIZE)))
        {
@@ -1401,16 +1406,52 @@ __floatdisf (DWtype u)
            }
        }
     }
-  f = (Wtype) (u >> WORD_SIZE);
-  f *= HIGH_HALFWORD_COEFF;
-  f *= HIGH_HALFWORD_COEFF;
-  f += (UWtype) (u & (HIGH_WORD_COEFF - 1));
 
+  /* 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 >> W_TYPE_SIZE);
+  f *= Wtype_MAXp1_F;
+  f += (UWtype)u;
   return (SFtype) f;
+#else
+  /* Finally, the word size is larger than the number of bits in SFmode,
+     and we've got no DFmode.  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 (SFtype)(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 = 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 & ((1 << shift) - 1))
+    hi |= 1;
+
+  /* Convert the one word of data, and rescale.  */
+  SFtype f = hi;
+  f *= (UWtype)1 << shift;
+  return f;
+#endif
 }
 #endif
 
-#if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
+#if defined(L_fixunsxfsi) && LIBGCC2_HAS_XF_MODE
 /* Reenable the normal types, in case limits.h needs them.  */
 #undef char
 #undef short
@@ -1432,7 +1473,7 @@ __fixunsxfSI (XFtype a)
 }
 #endif
 
-#ifdef L_fixunsdfsi
+#if defined(L_fixunsdfsi) && LIBGCC2_HAS_DF_MODE
 /* Reenable the normal types, in case limits.h needs them.  */
 #undef char
 #undef short
@@ -1476,6 +1517,243 @@ __fixunssfSI (SFtype a)
 }
 #endif
 \f
+/* Integer power helper used from __builtin_powi for non-constant
+   exponents.  */
+
+#if defined(L_powisf2) \
+    || (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
+
+TYPE
+NAME (TYPE x, Wtype m)
+{
+  UWtype 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
+\f
+#if defined(L_mulsc3) || defined(L_divsc3) \
+    || ((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 (denom == 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 */
+\f
 /* From here on down, the routines use normal data types.  */
 
 #define SItype bogus_type
@@ -1510,7 +1788,7 @@ __gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
 {
   while (size > 0)
     {
-      unsigned char c1 = *s1++, c2 = *s2++;
+      const unsigned char c1 = *s1++, c2 = *s2++;
       if (c1 != c2)
        return c1 - c2;
       size--;
@@ -1557,13 +1835,26 @@ __clear_cache (char *beg __attribute__((__unused__)),
 
 #endif /* L_clear_cache */
 \f
+#ifdef L_enable_execute_stack
+/* Attempt to turn on execute permission for the stack.  */
+
+#ifdef ENABLE_EXECUTE_STACK
+  ENABLE_EXECUTE_STACK
+#else
+void
+__enable_execute_stack (void *addr __attribute__((__unused__)))
+{}
+#endif /* ENABLE_EXECUTE_STACK */
+
+#endif /* L_enable_execute_stack */
+\f
 #ifdef L_trampoline
 
 /* Jump to a trampoline, loading the static chain address.  */
 
 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
 
-long
+int
 getpagesize (void)
 {
 #ifdef _ALPHA_
@@ -1734,4 +2025,3 @@ func_ptr __DTOR_LIST__[2];
 #endif
 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
 #endif /* L_ctors */
-