OSDN Git Service

Add fix test from irix_stdio_dummy_va_list
[pf3gnuchains/gcc-fork.git] / gcc / libgcc2.c
index e2a852c..177931d 100644 (file)
@@ -1,7 +1,7 @@
 /* More subroutines needed by GCC output code on some machines.  */
 /* Compile this one with gcc.  */
-/* Copyright (C) 1989, 92, 93, 94, 95, 96, 97, 98, 1999, 2000
-   Free Software Foundation, Inc.
+/* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+   2000, 2001  Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -10,6 +10,15 @@ it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2, or (at your option)
 any later version.
 
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file.  (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
 GNU CC is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
@@ -20,13 +29,6 @@ along with GNU CC; see the file COPYING.  If not, write to
 the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
-/* As a special exception, if you link this library with other files,
-   some of which are compiled with GCC, to produce an executable,
-   this library does not by itself cause the resulting executable
-   to be covered by the GNU General Public License.
-   This exception does not however invalidate any other reasons why
-   the executable file might be covered by the GNU General Public License.  */
-
 /* 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.  */
@@ -35,20 +37,12 @@ Boston, MA 02111-1307, USA.  */
 #include "tsystem.h"
 
 #include "machmode.h"
-#include "defaults.h" 
 
 /* Don't use `fancy_abort' here even if config.h says to use it.  */
 #ifdef abort
 #undef abort
 #endif
 
-/* In a cross-compilation situation, default to inhibiting compilation
-   of routines that use libc.  */
-
-#if defined(CROSS_COMPILE) && !defined(inhibit_libc)
-#define inhibit_libc
-#endif
-
 #include "libgcc2.h"
 \f
 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
@@ -69,7 +63,176 @@ __negdi2 (DWtype u)
   return w.ll;
 }
 #endif
+
+#ifdef L_addvsi3
+Wtype
+__addvsi3 (Wtype a, Wtype b)
+{
+  Wtype w;
+
+  w = a + b;
+
+  if (b >= 0 ? w < a : w > a)
+    abort ();
+
+  return w;
+} 
+#endif
+\f
+#ifdef L_addvdi3
+DWtype
+__addvdi3 (DWtype a, DWtype b)
+{
+  DWtype w;
+
+  w = a + b;
+
+  if (b >= 0 ? w < a : w > a)
+    abort ();
+
+  return w;
+}
+#endif
+\f
+#ifdef L_subvsi3
+Wtype
+__subvsi3 (Wtype a, Wtype b)
+{
+#ifdef L_addvsi3
+  return __addvsi3 (a, (-b));
+#else
+  DWtype w;
+
+  w = a - b;
+
+  if (b >= 0 ? w > a : w < a)
+    abort ();
+
+  return w;
+#endif
+}
+#endif
 \f
+#ifdef L_subvdi3
+DWtype
+__subvdi3 (DWtype a, DWtype b)
+{
+#ifdef L_addvdi3
+  return (a, (-b));
+#else
+  DWtype w;
+
+  w = a - b;
+
+  if (b >= 0 ? w > a : w < a)
+    abort ();
+
+  return w;
+#endif
+}
+#endif
+\f
+#ifdef L_mulvsi3
+Wtype
+__mulvsi3 (Wtype a, Wtype b)
+{
+  DWtype w;
+
+  w = a * b;
+
+  if (((a >= 0) == (b >= 0)) ? w < 0 : w > 0)
+    abort ();
+
+  return w;
+}
+#endif
+\f
+#ifdef L_negvsi2
+Wtype
+__negvsi2 (Wtype a)
+{
+   Wtype w;
+
+   w  = -a;
+
+  if (a >= 0 ? w > 0 : w < 0)
+    abort ();
+
+   return w;
+}
+#endif
+\f
+#ifdef L_negvdi2
+DWtype
+__negvdi2 (DWtype a)
+{
+   DWtype w;
+
+   w  = -a;
+
+  if (a >= 0 ? w > 0 : w < 0)
+    abort ();
+
+   return w;
+}
+#endif
+\f
+#ifdef L_absvsi2
+Wtype
+__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;
+}
+#endif
+\f
+#ifdef L_absvdi2
+DWtype
+__absvdi2 (DWtype a)
+{
+   DWtype w = a;
+
+   if (a < 0)
+#ifdef L_negvsi2
+     w = __negvsi2 (a);
+#else
+     w = -a;
+
+   if (w < 0)
+     abort ();
+#endif
+
+   return w;
+}
+#endif
+\f
+#ifdef L_mulvdi3
+DWtype
+__mulvdi3 (DWtype u, DWtype v)
+{
+   DWtype w;
+
+  w = u * v;
+
+  if (((u >= 0) == (v >= 0)) ? w < 0 : w > 0)
+    abort ();
+
+  return w;
+}
+#endif
+\f
+
 /* Unless shift functions are defined whith full ANSI prototypes,
    parameter b will be promoted to int if word_type is smaller than an int.  */
 #ifdef L_lshrdi3
@@ -89,13 +252,14 @@ __lshrdi3 (DWtype u, word_type b)
   if (bm <= 0)
     {
       w.s.high = 0;
-      w.s.low = (UWtype)uu.s.high >> -bm;
+      w.s.low = (UWtype) uu.s.high >> -bm;
     }
   else
     {
-      UWtype carries = (UWtype)uu.s.high << bm;
-      w.s.high = (UWtype)uu.s.high >> b;
-      w.s.low = ((UWtype)uu.s.low >> b) | carries;
+      UWtype carries = (UWtype) uu.s.high << bm;
+
+      w.s.high = (UWtype) uu.s.high >> b;
+      w.s.low = ((UWtype) uu.s.low >> b) | carries;
     }
 
   return w.ll;
@@ -119,13 +283,14 @@ __ashldi3 (DWtype u, word_type b)
   if (bm <= 0)
     {
       w.s.low = 0;
-      w.s.high = (UWtype)uu.s.low << -bm;
+      w.s.high = (UWtype) uu.s.low << -bm;
     }
   else
     {
-      UWtype carries = (UWtype)uu.s.low >> bm;
-      w.s.low = (UWtype)uu.s.low << b;
-      w.s.high = ((UWtype)uu.s.high << b) | carries;
+      UWtype carries = (UWtype) uu.s.low >> bm;
+
+      w.s.low = (UWtype) uu.s.low << b;
+      w.s.high = ((UWtype) uu.s.high << b) | carries;
     }
 
   return w.ll;
@@ -154,9 +319,10 @@ __ashrdi3 (DWtype u, word_type b)
     }
   else
     {
-      UWtype carries = (UWtype)uu.s.high << bm;
+      UWtype carries = (UWtype) uu.s.high << bm;
+
       w.s.high = uu.s.high >> b;
-      w.s.low = ((UWtype)uu.s.low >> b) | carries;
+      w.s.low = ((UWtype) uu.s.low >> b) | carries;
     }
 
   return w.ll;
@@ -167,19 +333,19 @@ __ashrdi3 (DWtype u, word_type b)
 DWtype
 __ffsdi2 (DWtype u)
 {
-  DWunion uu, w;
+  DWunion uu;
+  UWtype word, count, add;
+
   uu.ll = u;
-  w.s.high = 0;
-  w.s.low = ffs (uu.s.low);
-  if (w.s.low != 0)
-    return w.ll;
-  w.s.low = ffs (uu.s.high);
-  if (w.s.low != 0)
-    {
-      w.s.low += BITS_PER_UNIT * sizeof (Wtype);
-      return w.ll;
-    }
-  return w.ll;
+  if (uu.s.low != 0)
+    word = uu.s.low, add = 0;
+  else if (uu.s.high != 0)
+    word = uu.s.high, add = BITS_PER_UNIT * sizeof (Wtype);
+  else
+    return 0;
+
+  count_trailing_zeros (count, word);
+  return count + add + 1;
 }
 #endif
 \f
@@ -317,8 +483,8 @@ __udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)),
 #define L_udivmoddi4
 #endif
 
-#ifdef L_udivmoddi4
-static const UQItype __clz_tab[] =
+#ifdef L_clz
+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,
@@ -329,6 +495,9 @@ static const UQItype __clz_tab[] =
   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
   8,8,8,8,8,8,8,8,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_udivmoddi4
 
 #if (defined (L_udivdi3) || defined (L_divdi3) || \
      defined (L_umoddi3) || defined (L_moddi3))
@@ -668,7 +837,7 @@ __ucmpdi2 (DWtype a, DWtype b)
 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
 
 DWtype
-__fixunstfdi (TFtype a)
+__fixunstfDI (TFtype a)
 {
   TFtype b;
   UDWtype v;
@@ -700,8 +869,8 @@ DWtype
 __fixtfdi (TFtype a)
 {
   if (a < 0)
-    return - __fixunstfdi (-a);
-  return __fixunstfdi (a);
+    return - __fixunstfDI (-a);
+  return __fixunstfDI (a);
 }
 #endif
 
@@ -710,7 +879,7 @@ __fixtfdi (TFtype a)
 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
 
 DWtype
-__fixunsxfdi (XFtype a)
+__fixunsxfDI (XFtype a)
 {
   XFtype b;
   UDWtype v;
@@ -742,8 +911,8 @@ DWtype
 __fixxfdi (XFtype a)
 {
   if (a < 0)
-    return - __fixunsxfdi (-a);
-  return __fixunsxfdi (a);
+    return - __fixunsxfDI (-a);
+  return __fixunsxfDI (a);
 }
 #endif
 
@@ -752,7 +921,7 @@ __fixxfdi (XFtype a)
 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
 
 DWtype
-__fixunsdfdi (DFtype a)
+__fixunsdfDI (DFtype a)
 {
   DFtype b;
   UDWtype v;
@@ -784,8 +953,8 @@ DWtype
 __fixdfdi (DFtype a)
 {
   if (a < 0)
-    return - __fixunsdfdi (-a);
-  return __fixunsdfdi (a);
+    return - __fixunsdfDI (-a);
+  return __fixunsdfDI (a);
 }
 #endif
 
@@ -794,7 +963,7 @@ __fixdfdi (DFtype a)
 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
 
 DWtype
-__fixunssfdi (SFtype original_a)
+__fixunssfDI (SFtype original_a)
 {
   /* 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
@@ -813,7 +982,7 @@ __fixunssfdi (SFtype original_a)
   v = (UWtype) b;
   v <<= WORD_SIZE;
   /* Remove high part from the DFtype, leaving the low part as flonum.  */
-  a -= (DFtype)v;
+  a -= (DFtype) v;
   /* Convert that to fixed (but not to DWtype!) and add it in.
      Sometimes A comes out negative.  This is significant, since
      A has more bits than a long int does.  */
@@ -830,8 +999,8 @@ DWtype
 __fixsfdi (SFtype a)
 {
   if (a < 0)
-    return - __fixunssfdi (-a);
-  return __fixunssfdi (a);
+    return - __fixunssfDI (-a);
+  return __fixunssfDI (a);
 }
 #endif
 
@@ -943,11 +1112,11 @@ __floatdisf (DWtype u)
   if (DF_SIZE < DI_SIZE
       && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
     {
-#define REP_BIT ((UWtype) 1 << (DI_SIZE - DF_SIZE))
+#define REP_BIT ((UDWtype) 1 << (DI_SIZE - DF_SIZE))
       if (! (- ((DWtype) 1 << DF_SIZE) < u
             && u < ((DWtype) 1 << DF_SIZE)))
        {
-         if ((UWtype) u & (REP_BIT - 1))
+         if ((UDWtype) u & (REP_BIT - 1))
            u |= REP_BIT;
        }
     }
@@ -974,10 +1143,10 @@ __floatdisf (DWtype u)
 #include <limits.h>
 
 UWtype
-__fixunsxfsi (XFtype a)
+__fixunsxfSI (XFtype a)
 {
-  if (a >= - (DFtype) LONG_MIN)
-    return (Wtype) (a + LONG_MIN) - LONG_MIN;
+  if (a >= - (DFtype) Wtype_MIN)
+    return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
   return (Wtype) a;
 }
 #endif
@@ -996,10 +1165,10 @@ __fixunsxfsi (XFtype a)
 #include <limits.h>
 
 UWtype
-__fixunsdfsi (DFtype a)
+__fixunsdfSI (DFtype a)
 {
-  if (a >= - (DFtype) LONG_MIN)
-    return (Wtype) (a + LONG_MIN) - LONG_MIN;
+  if (a >= - (DFtype) Wtype_MIN)
+    return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
   return (Wtype) a;
 }
 #endif
@@ -1018,10 +1187,10 @@ __fixunsdfsi (DFtype a)
 #include <limits.h>
 
 UWtype
-__fixunssfsi (SFtype a)
+__fixunssfSI (SFtype a)
 {
-  if (a >= - (SFtype) LONG_MIN)
-    return (Wtype) (a + LONG_MIN) - LONG_MIN;
+  if (a >= - (SFtype) Wtype_MIN)
+    return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
   return (Wtype) a;
 }
 #endif
@@ -1069,241 +1238,17 @@ __gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
 }
 
 #endif
-\f\f
-#ifdef L__dummy
-void
-__dummy (void) {}
-#endif
-
-#ifdef L_varargs
-#ifdef __i860__
-#if defined(__svr4__) || defined(__alliant__)
-       asm ("  .text");
-       asm ("  .align  4");
-
-/* The Alliant needs the added underscore.  */
-       asm (".globl    __builtin_saveregs");
-asm ("__builtin_saveregs:");
-       asm (".globl    ___builtin_saveregs");
-asm ("___builtin_saveregs:");
-
-        asm (" andnot  0x0f,%sp,%sp"); /* round down to 16-byte boundary */
-       asm ("  adds    -96,%sp,%sp");  /* allocate stack space for reg save
-                                          area and also for a new va_list
-                                          structure */
-       /* Save all argument registers in the arg reg save area.  The
-          arg reg save area must have the following layout (according
-          to the svr4 ABI):
-
-               struct {
-                 union  {
-                   float freg[8];
-                   double dreg[4];
-                 } float_regs;
-                 long  ireg[12];
-               };
-       */
-
-       asm ("  fst.q   %f8,  0(%sp)"); /* save floating regs (f8-f15)  */
-       asm ("  fst.q   %f12,16(%sp)"); 
-
-       asm ("  st.l    %r16,32(%sp)"); /* save integer regs (r16-r27) */
-       asm ("  st.l    %r17,36(%sp)"); 
-       asm ("  st.l    %r18,40(%sp)");
-       asm ("  st.l    %r19,44(%sp)");
-       asm ("  st.l    %r20,48(%sp)");
-       asm ("  st.l    %r21,52(%sp)");
-       asm ("  st.l    %r22,56(%sp)");
-       asm ("  st.l    %r23,60(%sp)");
-       asm ("  st.l    %r24,64(%sp)");
-       asm ("  st.l    %r25,68(%sp)");
-       asm ("  st.l    %r26,72(%sp)");
-       asm ("  st.l    %r27,76(%sp)");
-
-       asm ("  adds    80,%sp,%r16");  /* compute the address of the new
-                                          va_list structure.  Put in into
-                                          r16 so that it will be returned
-                                          to the caller.  */
-
-       /* Initialize all fields of the new va_list structure.  This
-          structure looks like:
-
-               typedef struct {
-                   unsigned long       ireg_used;
-                   unsigned long       freg_used;
-                   long                *reg_base;
-                   long                *mem_ptr;
-               } va_list;
-       */
-
-       asm ("  st.l    %r0, 0(%r16)"); /* nfixed */
-       asm ("  st.l    %r0, 4(%r16)"); /* nfloating */
-       asm ("  st.l    %sp, 8(%r16)"); /* __va_ctl points to __va_struct.  */
-       asm ("  bri     %r1");          /* delayed return */
-       asm ("  st.l    %r28,12(%r16)"); /* pointer to overflow args */
-
-#else /* not __svr4__ */
-#if defined(__PARAGON__)
-       /*
-        *      we'll use SVR4-ish varargs but need SVR3.2 assembler syntax,
-        *      and we stand a better chance of hooking into libraries
-        *      compiled by PGI.  [andyp@ssd.intel.com]
-        */
-       asm ("  .text");
-       asm ("  .align  4");
-       asm (".globl    __builtin_saveregs");
-asm ("__builtin_saveregs:");
-       asm (".globl    ___builtin_saveregs");
-asm ("___builtin_saveregs:");
-
-        asm (" andnot  0x0f,sp,sp");   /* round down to 16-byte boundary */
-       asm ("  adds    -96,sp,sp");    /* allocate stack space for reg save
-                                          area and also for a new va_list
-                                          structure */
-       /* Save all argument registers in the arg reg save area.  The
-          arg reg save area must have the following layout (according
-          to the svr4 ABI):
-
-               struct {
-                 union  {
-                   float freg[8];
-                   double dreg[4];
-                 } float_regs;
-                 long  ireg[12];
-               };
-       */
-
-       asm ("  fst.q   f8,  0(sp)");
-       asm ("  fst.q   f12,16(sp)"); 
-       asm ("  st.l    r16,32(sp)");
-       asm ("  st.l    r17,36(sp)"); 
-       asm ("  st.l    r18,40(sp)");
-       asm ("  st.l    r19,44(sp)");
-       asm ("  st.l    r20,48(sp)");
-       asm ("  st.l    r21,52(sp)");
-       asm ("  st.l    r22,56(sp)");
-       asm ("  st.l    r23,60(sp)");
-       asm ("  st.l    r24,64(sp)");
-       asm ("  st.l    r25,68(sp)");
-       asm ("  st.l    r26,72(sp)");
-       asm ("  st.l    r27,76(sp)");
-
-       asm ("  adds    80,sp,r16");  /* compute the address of the new
-                                          va_list structure.  Put in into
-                                          r16 so that it will be returned
-                                          to the caller.  */
-
-       /* Initialize all fields of the new va_list structure.  This
-          structure looks like:
-
-               typedef struct {
-                   unsigned long       ireg_used;
-                   unsigned long       freg_used;
-                   long                *reg_base;
-                   long                *mem_ptr;
-               } va_list;
-       */
-
-       asm ("  st.l    r0, 0(r16)"); /* nfixed */
-       asm ("  st.l    r0, 4(r16)"); /* nfloating */
-       asm ("  st.l    sp, 8(r16)"); /* __va_ctl points to __va_struct.  */
-       asm ("  bri     r1");           /* delayed return */
-       asm ("   st.l   r28,12(r16)"); /* pointer to overflow args */
-#else /* not __PARAGON__ */
-       asm ("  .text");
-       asm ("  .align  4");
-
-       asm (".globl    ___builtin_saveregs");
-       asm ("___builtin_saveregs:");
-       asm ("  mov     sp,r30");
-       asm ("  andnot  0x0f,sp,sp");
-       asm ("  adds    -96,sp,sp");  /* allocate sufficient space on the stack */
-
-/* Fill in the __va_struct.  */
-       asm ("  st.l    r16, 0(sp)"); /* save integer regs (r16-r27) */
-       asm ("  st.l    r17, 4(sp)"); /* int    fixed[12] */
-       asm ("  st.l    r18, 8(sp)");
-       asm ("  st.l    r19,12(sp)");
-       asm ("  st.l    r20,16(sp)");
-       asm ("  st.l    r21,20(sp)");
-       asm ("  st.l    r22,24(sp)");
-       asm ("  st.l    r23,28(sp)");
-       asm ("  st.l    r24,32(sp)");
-       asm ("  st.l    r25,36(sp)");
-       asm ("  st.l    r26,40(sp)");
-       asm ("  st.l    r27,44(sp)");
-
-       asm ("  fst.q   f8, 48(sp)"); /* save floating regs (f8-f15) */
-       asm ("  fst.q   f12,64(sp)"); /* int floating[8] */
-
-/* Fill in the __va_ctl.  */
-       asm ("  st.l    sp, 80(sp)"); /* __va_ctl points to __va_struct.  */
-       asm ("  st.l    r28,84(sp)"); /* pointer to more args */
-       asm ("  st.l    r0, 88(sp)"); /* nfixed */
-       asm ("  st.l    r0, 92(sp)"); /* nfloating */
-
-       asm ("  adds    80,sp,r16");  /* return address of the __va_ctl.  */
-       asm ("  bri     r1");
-       asm ("  mov     r30,sp");
-                               /* recover stack and pass address to start 
-                                  of data.  */
-#endif /* not __PARAGON__ */
-#endif /* not __svr4__ */
-#else /* not __i860__ */
-#ifdef __sparc__
-       asm (".global __builtin_saveregs");
-       asm ("__builtin_saveregs:");
-       asm (".global ___builtin_saveregs");
-       asm ("___builtin_saveregs:");
-#ifdef NEED_PROC_COMMAND
-       asm (".proc 020");
-#endif
-       asm ("st %i0,[%fp+68]");
-       asm ("st %i1,[%fp+72]");
-       asm ("st %i2,[%fp+76]");
-       asm ("st %i3,[%fp+80]");
-       asm ("st %i4,[%fp+84]");
-       asm ("retl");
-       asm ("st %i5,[%fp+88]");
-#ifdef NEED_TYPE_COMMAND
-       asm (".type __builtin_saveregs,#function");
-       asm (".size __builtin_saveregs,.-__builtin_saveregs");
-#endif
-#else /* not __sparc__ */
-#if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
-
-  asm ("       .text");
-#ifdef __mips16
-  asm ("       .set nomips16");
-#endif
-  asm ("       .ent __builtin_saveregs");
-  asm ("       .globl __builtin_saveregs");
-  asm ("__builtin_saveregs:");
-  asm ("       sw      $4,0($30)");
-  asm ("       sw      $5,4($30)");
-  asm ("       sw      $6,8($30)");
-  asm ("       sw      $7,12($30)");
-  asm ("       j       $31");
-  asm ("       .end __builtin_saveregs");
-#else /* not __mips__, etc.  */
-
-void * __attribute__ ((__noreturn__))
-__builtin_saveregs (void)
-{
-  abort ();
-}
-
-#endif /* not __mips__ */
-#endif /* not __sparc__ */
-#endif /* not __i860__ */
-#endif
 \f
+/* __eprintf used to be used by GCC's private version of <assert.h>.
+   We no longer provide that header, but this routine remains in libgcc.a
+   for binary backward compatibility.  Note that it is not included in
+   the shared version of libgcc.  */
 #ifdef L_eprintf
 #ifndef inhibit_libc
 
 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
 #include <stdio.h>
-/* This is used by the `assert' macro.  */
+
 void
 __eprintf (const char *string, const char *expression,
           unsigned int line, const char *filename)
@@ -1347,7 +1292,7 @@ BLOCK_PROFILER_CODE
 
 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
 #include <stdio.h>
-char *ctime ();
+char *ctime PARAMS ((const time_t *));
 
 #include "gbl-ctors.h"
 #include "gcov-io.h"
@@ -2401,19 +2346,6 @@ stack_overflow:;
 #endif /* not BLOCK_PROFILER_CODE */
 #endif /* L_bb */
 \f
-#ifdef L_shtab
-unsigned int __shtab[] = {
-    0x00000001, 0x00000002, 0x00000004, 0x00000008,
-    0x00000010, 0x00000020, 0x00000040, 0x00000080,
-    0x00000100, 0x00000200, 0x00000400, 0x00000800,
-    0x00001000, 0x00002000, 0x00004000, 0x00008000,
-    0x00010000, 0x00020000, 0x00040000, 0x00080000,
-    0x00100000, 0x00200000, 0x00400000, 0x00800000,
-    0x01000000, 0x02000000, 0x04000000, 0x08000000,
-    0x10000000, 0x20000000, 0x40000000, 0x80000000
-  };
-#endif
-\f
 #ifdef L_clear_cache
 /* Clear part of an instruction cache.  */
 
@@ -2796,7 +2728,7 @@ cacheflush (char *beg, int size, int flag)
    code to run constructors.  In that case, we need to handle EH here, too.  */
 
 #ifdef EH_FRAME_SECTION
-#include "frame.h"
+#include "unwind-dw2-fde.h"
 extern unsigned char __EH_FRAME_BEGIN__[];
 #endif
 
@@ -2973,998 +2905,3 @@ atexit (func_ptr func)
 #endif /* NEED_ATEXIT */
 
 #endif /* L_exit */
-\f
-#ifdef L_eh
-
-#include "gthr.h"
-
-/* Shared exception handling support routines.  */
-
-void
-__default_terminate (void)
-{
-  abort ();
-}
-
-void (*__terminate_func)(void) __attribute__ ((__noreturn__)) =
-  __default_terminate;
-
-void
-__terminate (void)
-{
-  (*__terminate_func)();
-}
-
-void *
-__throw_type_match (void *catch_type, void *throw_type, void *obj)
-{
-#if 0
- printf ("__throw_type_match (): catch_type = %s, throw_type = %s\n",
-        catch_type, throw_type);
-#endif
- if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)
-   return obj;
- return 0;
-}
-
-void
-__empty (void)
-{
-}
-\f
-
-/* Include definitions of EH context and table layout */
-
-#include "eh-common.h"
-#ifndef inhibit_libc
-#include <stdio.h>
-#endif
-
-/* Allocate and return a new EH context structure. */
-
-#if __GTHREADS
-static void *
-new_eh_context (void)
-{
-  struct eh_full_context {
-    struct eh_context c;
-    void *top_elt[2];
-  } *ehfc = (struct eh_full_context *) malloc (sizeof *ehfc);
-
-  if (! ehfc)
-    __terminate ();
-
-  memset (ehfc, 0, sizeof *ehfc);
-
-  ehfc->c.dynamic_handler_chain = (void **) ehfc->top_elt;
-
-  /* This should optimize out entirely.  This should always be true,
-     but just in case it ever isn't, don't allow bogus code to be
-     generated.  */
-
-  if ((void*)(&ehfc->c) != (void*)ehfc)
-    __terminate ();
-
-  return &ehfc->c;
-}
-
-static __gthread_key_t eh_context_key;
-
-/* Destructor for struct eh_context. */
-static void
-eh_context_free (void *ptr)
-{
-  __gthread_key_dtor (eh_context_key, ptr);
-  if (ptr)
-    free (ptr);
-}
-#endif
-
-/* Pointer to function to return EH context. */
-
-static struct eh_context *eh_context_initialize (void);
-static struct eh_context *eh_context_static (void);
-#if __GTHREADS
-static struct eh_context *eh_context_specific (void);
-#endif
-
-static struct eh_context *(*get_eh_context) (void) = &eh_context_initialize;
-
-/* Routine to get EH context.
-   This one will simply call the function pointer. */
-
-void *
-__get_eh_context (void)
-{
-  return (void *) (*get_eh_context) ();
-}
-
-/* Get and set the language specific info pointer. */
-
-void **
-__get_eh_info (void)
-{
-  struct eh_context *eh = (*get_eh_context) ();
-  return &eh->info;
-}
-\f
-#ifdef DWARF2_UNWIND_INFO
-static int dwarf_reg_size_table_initialized = 0;
-static char dwarf_reg_size_table[DWARF_FRAME_REGISTERS];
-
-static void
-init_reg_size_table (void)
-{
-  __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
-  dwarf_reg_size_table_initialized = 1;
-}
-#endif
-
-#if __GTHREADS
-static void
-eh_threads_initialize (void)
-{
-  /* Try to create the key.  If it fails, revert to static method,
-     otherwise start using thread specific EH contexts. */
-  if (__gthread_key_create (&eh_context_key, &eh_context_free) == 0)
-    get_eh_context = &eh_context_specific;
-  else
-    get_eh_context = &eh_context_static;
-}
-#endif /* no __GTHREADS */
-
-/* Initialize EH context.
-   This will be called only once, since we change GET_EH_CONTEXT
-   pointer to another routine. */
-
-static struct eh_context *
-eh_context_initialize (void)
-{
-#if __GTHREADS
-
-  static __gthread_once_t once = __GTHREAD_ONCE_INIT;
-  /* Make sure that get_eh_context does not point to us anymore.
-     Some systems have dummy thread routines in their libc that
-     return a success (Solaris 2.6 for example). */
-  if (__gthread_once (&once, eh_threads_initialize) != 0
-      || get_eh_context == &eh_context_initialize)
-    {
-      /* Use static version of EH context. */
-      get_eh_context = &eh_context_static;
-    }
-#ifdef DWARF2_UNWIND_INFO
-  {
-    static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
-    if (__gthread_once (&once_regsizes, init_reg_size_table) != 0
-       || ! dwarf_reg_size_table_initialized)
-      init_reg_size_table ();
-  }
-#endif
-
-#else /* no __GTHREADS */
-
-  /* Use static version of EH context. */
-  get_eh_context = &eh_context_static;
-
-#ifdef DWARF2_UNWIND_INFO
-  init_reg_size_table ();
-#endif
-
-#endif /* no __GTHREADS */
-
-  return (*get_eh_context) ();
-}
-
-/* Return a static EH context. */
-
-static struct eh_context *
-eh_context_static (void)
-{
-  static struct eh_context eh;
-  static int initialized;
-  static void *top_elt[2];
-
-  if (! initialized)
-    {
-      initialized = 1;
-      memset (&eh, 0, sizeof eh);
-      eh.dynamic_handler_chain = top_elt;
-    }
-  return &eh;
-}
-
-#if __GTHREADS
-/* Return a thread specific EH context. */
-
-static struct eh_context *
-eh_context_specific (void)
-{
-  struct eh_context *eh;
-  eh = (struct eh_context *) __gthread_getspecific (eh_context_key);
-  if (! eh)
-    {
-      eh = new_eh_context ();
-      if (__gthread_setspecific (eh_context_key, (void *) eh) != 0)
-       __terminate ();
-    }
-
-  return eh;
-}
-#endif __GTHREADS
-\f
-/* Support routines for setjmp/longjmp exception handling.  */
-
-/* Calls to __sjthrow are generated by the compiler when an exception
-   is raised when using the setjmp/longjmp exception handling codegen
-   method.  */
-
-#ifdef DONT_USE_BUILTIN_SETJMP
-extern void longjmp (void *, int);
-#endif
-
-/* Routine to get the head of the current thread's dynamic handler chain
-   use for exception handling. */
-
-void ***
-__get_dynamic_handler_chain (void)
-{
-  struct eh_context *eh = (*get_eh_context) ();
-  return &eh->dynamic_handler_chain;
-}
-
-/* This is used to throw an exception when the setjmp/longjmp codegen
-   method is used for exception handling.
-
-   We call __terminate if there are no handlers left.  Otherwise we run the
-   cleanup actions off the dynamic cleanup stack, and pop the top of the
-   dynamic handler chain, and use longjmp to transfer back to the associated
-   handler.  */
-
-void
-__sjthrow (void)
-{
-  struct eh_context *eh = (*get_eh_context) ();
-  void ***dhc = &eh->dynamic_handler_chain;
-  void *jmpbuf;
-  void (*func)(void *, int);
-  void *arg;
-  /* The cleanup chain is one word into the buffer.  Get the cleanup chain. */
-  void ***cleanup = (void***)&(*dhc)[1];
-
-  /* If there are any cleanups in the chain, run them now.  */
-  if (cleanup[0])
-    {
-      double store[200];
-      void **buf = (void**)store;
-      buf[1] = 0;
-      buf[0] = (*dhc);
-
-      /* try { */
-#ifdef DONT_USE_BUILTIN_SETJMP
-      if (! setjmp (&buf[2]))
-#else
-      if (! __builtin_setjmp (&buf[2]))
-#endif
-       {
-         *dhc = buf;
-         while (cleanup[0])
-           {
-             func = (void(*)(void*, int))cleanup[0][1];
-             arg = (void*)cleanup[0][2];
-
-             /* Update this before running the cleanup.  */
-             cleanup[0] = (void **)cleanup[0][0];
-
-             (*func)(arg, 2);
-           }
-         *dhc = buf[0];
-       }
-      /* catch (...) */
-      else
-       {
-         __terminate ();
-       }
-    }
-  
-  /* We must call terminate if we try and rethrow an exception, when
-     there is no exception currently active and when there are no
-     handlers left.  */
-  if (! eh->info || (*dhc)[0] == 0)
-    __terminate ();
-    
-  /* Find the jmpbuf associated with the top element of the dynamic
-     handler chain.  The jumpbuf starts two words into the buffer.  */
-  jmpbuf = &(*dhc)[2];
-
-  /* Then we pop the top element off the dynamic handler chain.  */
-  *dhc = (void**)(*dhc)[0];
-
-  /* And then we jump to the handler.  */
-
-#ifdef DONT_USE_BUILTIN_SETJMP
-  longjmp (jmpbuf, 1);
-#else
-  __builtin_longjmp (jmpbuf, 1);
-#endif
-}
-
-/* Run cleanups on the dynamic cleanup stack for the current dynamic
-   handler, then pop the handler off the dynamic handler stack, and
-   then throw.  This is used to skip the first handler, and transfer
-   control to the next handler in the dynamic handler stack.  */
-
-void
-__sjpopnthrow (void)
-{
-  struct eh_context *eh = (*get_eh_context) ();
-  void ***dhc = &eh->dynamic_handler_chain;
-  void (*func)(void *, int);
-  void *arg;
-  /* The cleanup chain is one word into the buffer.  Get the cleanup chain. */
-  void ***cleanup = (void***)&(*dhc)[1];
-
-  /* If there are any cleanups in the chain, run them now.  */
-  if (cleanup[0])
-    {
-      double store[200];
-      void **buf = (void**)store;
-      buf[1] = 0;
-      buf[0] = (*dhc);
-
-      /* try { */
-#ifdef DONT_USE_BUILTIN_SETJMP
-      if (! setjmp (&buf[2]))
-#else
-      if (! __builtin_setjmp (&buf[2]))
-#endif
-       {
-         *dhc = buf;
-         while (cleanup[0])
-           {
-             func = (void(*)(void*, int))cleanup[0][1];
-             arg = (void*)cleanup[0][2];
-
-             /* Update this before running the cleanup.  */
-             cleanup[0] = (void **)cleanup[0][0];
-
-             (*func)(arg, 2);
-           }
-         *dhc = buf[0];
-       }
-      /* catch (...) */
-      else
-       {
-         __terminate ();
-       }
-    }
-
-  /* Then we pop the top element off the dynamic handler chain.  */
-  *dhc = (void**)(*dhc)[0];
-
-  __sjthrow ();
-}
-\f
-/* Support code for all exception region-based exception handling.  */
-
-int
-__eh_rtime_match (void *rtime)
-{
-  void *info;
-  __eh_matcher matcher;
-  void *ret;
-
-  info = *(__get_eh_info ());
-  matcher = ((__eh_info *)info)->match_function;
-  if (! matcher)
-    {
-#ifndef inhibit_libc
-      fprintf (stderr, "Internal Compiler Bug: No runtime type matcher.");
-#endif
-      return 0;
-    }
-  ret = (*matcher) (info, rtime, (void *)0);
-  return (ret != NULL);
-}
-
-/* This value identifies the place from which an exception is being
-   thrown.  */
-
-#ifdef EH_TABLE_LOOKUP
-
-EH_TABLE_LOOKUP
-
-#else
-
-#ifdef DWARF2_UNWIND_INFO
-
-/* Return the table version of an exception descriptor */
-
-short 
-__get_eh_table_version (exception_descriptor *table) 
-{
-  return table->lang.version;
-}
-
-/* Return the originating table language of an exception descriptor */
-
-short 
-__get_eh_table_language (exception_descriptor *table)
-{
-  return table->lang.language;
-}
-
-/* This routine takes a PC and a pointer to the exception region TABLE for
-   its translation unit, and returns the address of the exception handler
-   associated with the closest exception table handler entry associated
-   with that PC, or 0 if there are no table entries the PC fits in.
-
-   In the advent of a tie, we have to give the last entry, as it represents
-   an inner block.  */
-
-static void *
-old_find_exception_handler (void *pc, old_exception_table *table)
-{
-  if (table)
-    {
-      int pos;
-      int best = -1;
-
-      /* We can't do a binary search because the table isn't guaranteed
-         to be sorted from function to function.  */
-      for (pos = 0; table[pos].start_region != (void *) -1; ++pos)
-        {
-          if (table[pos].start_region <= pc && table[pos].end_region > pc)
-            {
-              /* This can apply.  Make sure it is at least as small as
-                 the previous best.  */
-              if (best == -1 || (table[pos].end_region <= table[best].end_region
-                        && table[pos].start_region >= table[best].start_region))
-                best = pos;
-            }
-          /* But it is sorted by starting PC within a function.  */
-          else if (best >= 0 && table[pos].start_region > pc)
-            break;
-        }
-      if (best != -1)
-        return table[best].exception_handler;
-    }
-
-  return (void *) 0;
-}
-
-/* find_exception_handler finds the correct handler, if there is one, to
-   handle an exception.
-   returns a pointer to the handler which controlled should be transferred
-   to, or NULL if there is nothing left.
-   Parameters:
-   PC - pc where the exception originates. If this is a rethrow, 
-        then this starts out as a pointer to the exception table
-       entry we wish to rethrow out of.
-   TABLE - exception table for the current module.
-   EH_INFO - eh info pointer for this exception.
-   RETHROW - 1 if this is a rethrow. (see incoming value of PC).
-   CLEANUP - returned flag indicating whether this is a cleanup handler.
-*/
-static void *
-find_exception_handler (void *pc, exception_descriptor *table, 
-                        __eh_info *eh_info, int rethrow, int *cleanup)
-{
-
-  void *retval = NULL;
-  *cleanup = 1;
-  if (table)
-    {
-      int pos = 0;
-      /* The new model assumed the table is sorted inner-most out so the
-         first region we find which matches is the correct one */
-
-      exception_table *tab = &(table->table[0]);
-
-      /* Subtract 1 from the PC to avoid hitting the next region */
-      if (rethrow) 
-        {
-          /* pc is actually the region table entry to rethrow out of */
-          pos = ((exception_table *) pc) - tab;
-          pc = ((exception_table *) pc)->end_region - 1;
-
-          /* The label is always on the LAST handler entry for a region, 
-             so we know the next entry is a different region, even if the
-             addresses are the same. Make sure its not end of table tho. */
-          if (tab[pos].start_region != (void *) -1)
-            pos++;
-        }
-      else
-        pc--;
-      
-      /* We can't do a binary search because the table is in inner-most
-         to outermost address ranges within functions */
-      for ( ; tab[pos].start_region != (void *) -1; pos++)
-        { 
-          if (tab[pos].start_region <= pc && tab[pos].end_region > pc)
-            {
-              if (tab[pos].match_info)
-                {
-                  __eh_matcher matcher = eh_info->match_function;
-                  /* match info but no matcher is NOT a match */
-                  if (matcher) 
-                    {
-                      void *ret = (*matcher)((void *) eh_info, 
-                                             tab[pos].match_info, table);
-                      if (ret) 
-                        {
-                          if (retval == NULL)
-                            retval = tab[pos].exception_handler;
-                          *cleanup = 0;
-                          break;
-                        }
-                    }
-                }
-              else
-                {
-                  if (retval == NULL)
-                    retval = tab[pos].exception_handler;
-                }
-            }
-        }
-    }
-  return retval;
-}
-#endif /* DWARF2_UNWIND_INFO */
-#endif /* EH_TABLE_LOOKUP */
-\f
-#ifdef DWARF2_UNWIND_INFO
-/* Support code for exception handling using static unwind information.  */
-
-#include "frame.h"
-
-/* This type is used in get_reg and put_reg to deal with ABIs where a void*
-   is smaller than a word, such as the Irix 6 n32 ABI.  We cast twice to
-   avoid a warning about casting between int and pointer of different
-   sizes.  */
-
-typedef int ptr_type __attribute__ ((mode (pointer)));
-
-#ifdef INCOMING_REGNO
-/* Is the saved value for register REG in frame UDATA stored in a register
-   window in the previous frame?  */
-
-/* ??? The Sparc INCOMING_REGNO references TARGET_FLAT.  This allows us
-   to use the macro here.  One wonders, though, that perhaps TARGET_FLAT
-   compiled functions won't work with the frame-unwind stuff here.  
-   Perhaps the entireity of in_reg_window should be conditional on having
-   seen a DW_CFA_GNU_window_save?  */
-#define target_flags 0
-
-static int
-in_reg_window (int reg, frame_state *udata)
-{
-  if (udata->saved[reg] == REG_SAVED_REG)
-    return INCOMING_REGNO (reg) == reg;
-  if (udata->saved[reg] != REG_SAVED_OFFSET)
-    return 0;
-
-#ifdef STACK_GROWS_DOWNWARD
-  return udata->reg_or_offset[reg] > 0;
-#else
-  return udata->reg_or_offset[reg] < 0;
-#endif
-}
-#else
-static inline int
-in_reg_window (int reg __attribute__ ((__unused__)),
-              frame_state *udata __attribute__ ((__unused__)))
-{
-  return 0;
-}
-#endif /* INCOMING_REGNO */
-
-/* Get the address of register REG as saved in UDATA, where SUB_UDATA is a
-   frame called by UDATA or 0.  */
-
-static word_type *
-get_reg_addr (unsigned reg, frame_state *udata, frame_state *sub_udata)
-{
-  while (udata->saved[reg] == REG_SAVED_REG)
-    {
-      reg = udata->reg_or_offset[reg];
-      if (in_reg_window (reg, udata))
-       {
-          udata = sub_udata;
-         sub_udata = NULL;
-       }
-    }
-  if (udata->saved[reg] == REG_SAVED_OFFSET)
-    return (word_type *)(udata->cfa + udata->reg_or_offset[reg]);
-  else
-    abort ();
-}
-
-/* Get the value of register REG as saved in UDATA, where SUB_UDATA is a
-   frame called by UDATA or 0.  */
-
-static inline void *
-get_reg (unsigned reg, frame_state *udata, frame_state *sub_udata)
-{
-  return (void *)(ptr_type) *get_reg_addr (reg, udata, sub_udata);
-}
-
-/* Overwrite the saved value for register REG in frame UDATA with VAL.  */
-
-static inline void
-put_reg (unsigned reg, void *val, frame_state *udata)
-{
-  *get_reg_addr (reg, udata, NULL) = (word_type)(ptr_type) val;
-}
-
-/* Copy the saved value for register REG from frame UDATA to frame
-   TARGET_UDATA.  Unlike the previous two functions, this can handle
-   registers that are not one word large.  */
-
-static void
-copy_reg (unsigned reg, frame_state *udata, frame_state *target_udata)
-{
-  word_type *preg = get_reg_addr (reg, udata, NULL);
-  word_type *ptreg = get_reg_addr (reg, target_udata, NULL);
-
-  memcpy (ptreg, preg, dwarf_reg_size_table [reg]);
-}
-
-/* Retrieve the return address for frame UDATA.  */
-
-static inline void *
-get_return_addr (frame_state *udata, frame_state *sub_udata)
-{
-  return __builtin_extract_return_addr
-    (get_reg (udata->retaddr_column, udata, sub_udata));
-}
-
-/* Overwrite the return address for frame UDATA with VAL.  */
-
-static inline void
-put_return_addr (void *val, frame_state *udata)
-{
-  val = __builtin_frob_return_addr (val);
-  put_reg (udata->retaddr_column, val, udata);
-}
-
-/* Given the current frame UDATA and its return address PC, return the
-   information about the calling frame in CALLER_UDATA.  */
-
-static void *
-next_stack_level (void *pc, frame_state *udata, frame_state *caller_udata)
-{
-  caller_udata = __frame_state_for (pc, caller_udata);
-  if (! caller_udata)
-    return 0;
-
-  /* Now go back to our caller's stack frame.  If our caller's CFA register
-     was saved in our stack frame, restore it; otherwise, assume the CFA
-     register is SP and restore it to our CFA value.  */
-  if (udata->saved[caller_udata->cfa_reg])
-    caller_udata->cfa = get_reg (caller_udata->cfa_reg, udata, 0);
-  else
-    caller_udata->cfa = udata->cfa;
-  caller_udata->cfa += caller_udata->cfa_offset;
-
-  return caller_udata;
-}
-
-/* Hook to call before __terminate if only cleanup handlers remain. */
-void 
-__unwinding_cleanup (void)
-{
-}
-
-/* throw_helper performs some of the common grunt work for a throw. This
-   routine is called by throw and rethrows. This is pretty much split 
-   out from the old __throw routine. An addition has been added which allows
-   for a dummy call to a routine __unwinding_cleanup() when there are nothing
-   but cleanups remaining. This allows a debugger to examine the state
-   at which the throw was executed, before any cleanups, rather than
-   at the terminate point after the stack has been unwound.
-
-   EH is the current eh_context structure.
-   PC is the address of the call to __throw.
-   MY_UDATA is the unwind information for __throw.
-   OFFSET_P is where we return the SP adjustment offset.  */
-
-static void *
-throw_helper (struct eh_context *eh, void *pc, frame_state *my_udata,
-             long *offset_p)
-{
-  frame_state ustruct2, *udata = &ustruct2;
-  frame_state ustruct;
-  frame_state *sub_udata = &ustruct;
-  void *saved_pc = pc;
-  void *handler;
-  void *handler_p = 0;
-  void *pc_p = 0;
-  frame_state saved_ustruct;
-  int new_eh_model;
-  int cleanup = 0;
-  int only_cleanup = 0;
-  int rethrow = 0;
-  int saved_state = 0;
-  long args_size;
-  __eh_info *eh_info = (__eh_info *)eh->info;
-
-  /* Do we find a handler based on a re-throw PC? */
-  if (eh->table_index != (void *) 0)
-    rethrow = 1;
-
-  memcpy (udata, my_udata, sizeof (*udata));
-
-  handler = (void *) 0;
-  for (;;)
-    { 
-      frame_state *p = udata;
-      udata = next_stack_level (pc, udata, sub_udata);
-      sub_udata = p;
-
-      /* If we couldn't find the next frame, we lose.  */
-      if (! udata)
-       break;
-
-      if (udata->eh_ptr == NULL)
-        new_eh_model = 0;
-      else
-        new_eh_model = (((exception_descriptor *)(udata->eh_ptr))->
-                                          runtime_id_field == NEW_EH_RUNTIME);
-
-      if (rethrow) 
-        {
-          rethrow = 0;
-          handler = find_exception_handler (eh->table_index, udata->eh_ptr, 
-                                          eh_info, 1, &cleanup);
-          eh->table_index = (void *)0;
-        }
-      else
-        if (new_eh_model)
-          handler = find_exception_handler (pc, udata->eh_ptr, eh_info, 
-                                            0, &cleanup);
-        else
-          handler = old_find_exception_handler (pc, udata->eh_ptr);
-
-      /* If we found one, we can stop searching, if its not a cleanup. 
-         for cleanups, we save the state, and keep looking. This allows
-         us to call a debug hook if there are nothing but cleanups left. */
-      if (handler)
-       {
-         if (cleanup)
-           {
-             if (!saved_state)
-               {
-                 saved_ustruct = *udata;
-                 handler_p = handler;
-                 pc_p = pc;
-                 saved_state = 1;
-                 only_cleanup = 1;
-               }
-           }
-         else
-           {
-             only_cleanup = 0;
-             break;
-           }
-       }
-
-      /* Otherwise, we continue searching.  We subtract 1 from PC to avoid
-        hitting the beginning of the next region.  */
-      pc = get_return_addr (udata, sub_udata) - 1;
-    }
-
-  if (saved_state) 
-    {
-      udata = &saved_ustruct;
-      handler = handler_p;
-      pc = pc_p;
-      if (only_cleanup)
-        __unwinding_cleanup ();
-    }
-
-  /* If we haven't found a handler by now, this is an unhandled
-     exception.  */
-  if (! handler) 
-    __terminate();
-
-  eh->handler_label = handler;
-
-  args_size = udata->args_size;
-
-  if (pc == saved_pc)
-    /* We found a handler in the throw context, no need to unwind.  */
-    udata = my_udata;
-  else
-    {
-      int i;
-
-      /* Unwind all the frames between this one and the handler by copying
-        their saved register values into our register save slots.  */
-
-      /* Remember the PC where we found the handler.  */
-      void *handler_pc = pc;
-
-      /* Start from the throw context again.  */
-      pc = saved_pc;
-      memcpy (udata, my_udata, sizeof (*udata));
-
-      while (pc != handler_pc)
-       {
-         frame_state *p = udata;
-         udata = next_stack_level (pc, udata, sub_udata);
-         sub_udata = p;
-
-         for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
-           if (i != udata->retaddr_column && udata->saved[i])
-             {
-               /* If you modify the saved value of the return address
-                  register on the SPARC, you modify the return address for
-                  your caller's frame.  Don't do that here, as it will
-                  confuse get_return_addr.  */
-               if (in_reg_window (i, udata)
-                   && udata->saved[udata->retaddr_column] == REG_SAVED_REG
-                   && udata->reg_or_offset[udata->retaddr_column] == i)
-                 continue;
-               copy_reg (i, udata, my_udata);
-             }
-
-         pc = get_return_addr (udata, sub_udata) - 1;
-       }
-
-      /* But we do need to update the saved return address register from
-        the last frame we unwind, or the handler frame will have the wrong
-        return address.  */
-      if (udata->saved[udata->retaddr_column] == REG_SAVED_REG)
-       {
-         i = udata->reg_or_offset[udata->retaddr_column];
-         if (in_reg_window (i, udata))
-           copy_reg (i, udata, my_udata);
-       }
-    }
-  /* udata now refers to the frame called by the handler frame.  */
-
-  /* We adjust SP by the difference between __throw's CFA and the CFA for
-     the frame called by the handler frame, because those CFAs correspond
-     to the SP values at the two call sites.  We need to further adjust by
-     the args_size of the handler frame itself to get the handler frame's
-     SP from before the args were pushed for that call.  */
-#ifdef STACK_GROWS_DOWNWARD
-  *offset_p = udata->cfa - my_udata->cfa + args_size;
-#else
-  *offset_p = my_udata->cfa - udata->cfa - args_size;
-#endif
-                      
-  return handler;
-}
-
-
-/* We first search for an exception handler, and if we don't find
-   it, we call __terminate on the current stack frame so that we may
-   use the debugger to walk the stack and understand why no handler
-   was found.
-
-   If we find one, then we unwind the frames down to the one that
-   has the handler and transfer control into the handler.  */
-
-/*extern void __throw(void) __attribute__ ((__noreturn__));*/
-
-void
-__throw (void)
-{
-  struct eh_context *eh = (*get_eh_context) ();
-  void *pc, *handler;
-  long offset;
-
-  /* XXX maybe make my_ustruct static so we don't have to look it up for
-     each throw.  */
-  frame_state my_ustruct, *my_udata = &my_ustruct;
-
-  /* This is required for C++ semantics.  We must call terminate if we
-     try and rethrow an exception, when there is no exception currently
-     active.  */
-  if (! eh->info)
-    __terminate ();
-    
-  /* Start at our stack frame.  */
-label:
-  my_udata = __frame_state_for (&&label, my_udata);
-  if (! my_udata)
-    __terminate ();
-
-  /* We need to get the value from the CFA register. */
-  my_udata->cfa = __builtin_dwarf_cfa ();
-
-  /* Do any necessary initialization to access arbitrary stack frames.
-     On the SPARC, this means flushing the register windows.  */
-  __builtin_unwind_init ();
-
-  /* Now reset pc to the right throw point.  */
-  pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
-
-  handler = throw_helper (eh, pc, my_udata, &offset);
-
-  /* Now go!  */
-
-  __builtin_eh_return ((void *)eh, offset, handler);
-
-  /* Epilogue:  restore the handler frame's register values and return
-     to the stub.  */
-}
-
-/*extern void __rethrow(void *) __attribute__ ((__noreturn__));*/
-
-void
-__rethrow (void *index)
-{
-  struct eh_context *eh = (*get_eh_context) ();
-  void *pc, *handler;
-  long offset;
-
-  /* XXX maybe make my_ustruct static so we don't have to look it up for
-     each throw.  */
-  frame_state my_ustruct, *my_udata = &my_ustruct;
-
-  /* This is required for C++ semantics.  We must call terminate if we
-     try and rethrow an exception, when there is no exception currently
-     active.  */
-  if (! eh->info)
-    __terminate ();
-
-  /* This is the table index we want to rethrow from. The value of
-     the END_REGION label is used for the PC of the throw, and the
-     search begins with the next table entry. */
-  eh->table_index = index;
-    
-  /* Start at our stack frame.  */
-label:
-  my_udata = __frame_state_for (&&label, my_udata);
-  if (! my_udata)
-    __terminate ();
-
-  /* We need to get the value from the CFA register. */
-  my_udata->cfa = __builtin_dwarf_cfa ();
-
-  /* Do any necessary initialization to access arbitrary stack frames.
-     On the SPARC, this means flushing the register windows.  */
-  __builtin_unwind_init ();
-
-  /* Now reset pc to the right throw point.  */
-  pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
-
-  handler = throw_helper (eh, pc, my_udata, &offset);
-
-  /* Now go!  */
-
-  __builtin_eh_return ((void *)eh, offset, handler);
-
-  /* Epilogue:  restore the handler frame's register values and return
-     to the stub.  */
-}
-#endif /* DWARF2_UNWIND_INFO */
-
-#endif /* L_eh */
-\f
-#ifdef L_pure
-#ifndef inhibit_libc
-/* This gets us __GNU_LIBRARY__.  */
-#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
-#include <stdio.h>
-
-#ifdef __GNU_LIBRARY__
-  /* Avoid forcing the library's meaning of `write' on the user program
-     by using the "internal" name (for use within the library)  */
-#define write(fd, buf, n)      __write((fd), (buf), (n))
-#endif
-#endif /* inhibit_libc */
-
-#define MESSAGE "pure virtual method called\n"
-
-void
-__pure_virtual (void)
-{
-#ifndef inhibit_libc
-  write (2, MESSAGE, sizeof (MESSAGE) - 1);
-#endif
-  __terminate ();
-}
-#endif