OSDN Git Service

(MOD[SD]I_LIBCALL): Call ots$rem, not ots$mod.
[pf3gnuchains/gcc-fork.git] / gcc / libgcc2.c
index 5df5d91..3387070 100644 (file)
@@ -1,6 +1,6 @@
 /* More subroutines needed by GCC output code on some machines.  */
 /* Compile this one with gcc.  */
-/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+/* Copyright (C) 1989, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -42,7 +42,7 @@ Boston, MA 02111-1307, USA.  */
 #undef abort
 #endif
 
-#if (SUPPORTS_WEAK == 1) && defined (ASM_OUTPUT_DEF)
+#if (SUPPORTS_WEAK == 1) && (defined (ASM_OUTPUT_DEF) || defined (ASM_OUTPUT_WEAK_ALIAS))
 #define WEAK_ALIAS
 #endif
 
@@ -138,8 +138,7 @@ extern DItype __fixunstfdi (TFtype a);
 static inline
 #endif
 DItype
-__negdi2 (u)
-     DItype u;
+__negdi2 (DItype u)
 {
   DIunion w;
   DIunion uu;
@@ -153,11 +152,11 @@ __negdi2 (u)
 }
 #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
 DItype
-__lshrdi3 (u, b)
-     DItype u;
-     word_type b;
+__lshrdi3 (DItype u, word_type b)
 {
   DIunion w;
   word_type bm;
@@ -187,9 +186,7 @@ __lshrdi3 (u, b)
 
 #ifdef L_ashldi3
 DItype
-__ashldi3 (u, b)
-     DItype u;
-     word_type b;
+__ashldi3 (DItype u, word_type b)
 {
   DIunion w;
   word_type bm;
@@ -219,9 +216,7 @@ __ashldi3 (u, b)
 
 #ifdef L_ashrdi3
 DItype
-__ashrdi3 (u, b)
-     DItype u;
-     word_type b;
+__ashrdi3 (DItype u, word_type b)
 {
   DIunion w;
   word_type bm;
@@ -252,8 +247,7 @@ __ashrdi3 (u, b)
 \f
 #ifdef L_ffsdi2
 DItype
-__ffsdi2 (u)
-     DItype u;
+__ffsdi2 (DItype u)
 {
   DIunion uu, w;
   uu.ll = u;
@@ -273,8 +267,7 @@ __ffsdi2 (u)
 \f
 #ifdef L_muldi3
 DItype
-__muldi3 (u, v)
-     DItype u, v;
+__muldi3 (DItype u, DItype v)
 {
   DIunion w;
   DIunion uu, vv;
@@ -293,8 +286,7 @@ __muldi3 (u, v)
 #ifdef L_udiv_w_sdiv
 #if defined (sdiv_qrnnd)
 USItype
-__udiv_w_sdiv (rp, a1, a0, d)
-     USItype *rp, a1, a0, d;
+__udiv_w_sdiv (USItype *rp, USItype a1, USItype a0, USItype d)
 {
   USItype q, r;
   USItype c0, c1, b1;
@@ -392,8 +384,7 @@ __udiv_w_sdiv (rp, a1, a0, d)
 #else
 /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv.  */
 USItype
-__udiv_w_sdiv (rp, a1, a0, d)
-     USItype *rp, a1, a0, d;
+__udiv_w_sdiv (USItype *rp, USItype a1, USItype a0, USItype d)
 {}
 #endif
 #endif
@@ -421,9 +412,7 @@ static const UQItype __clz_tab[] =
 static inline
 #endif
 UDItype
-__udivmoddi4 (n, d, rp)
-     UDItype n, d;
-     UDItype *rp;
+__udivmoddi4 (UDItype n, UDItype d, UDItype *rp)
 {
   DIunion ww;
   DIunion nn, dd;
@@ -533,7 +522,7 @@ __udivmoddi4 (n, d, rp)
              udiv_qrnnd (q1, n1, n2, n1, d0);
            }
 
-         /* n1 != d0... */
+         /* n1 != d0...  */
 
          udiv_qrnnd (q0, n0, n1, n0, d0);
 
@@ -644,8 +633,7 @@ __udivmoddi4 (n, d, rp)
 UDItype __udivmoddi4 ();
 
 DItype
-__divdi3 (u, v)
-     DItype u, v;
+__divdi3 (DItype u, DItype v)
 {
   word_type c = 0;
   DIunion uu, vv;
@@ -672,8 +660,7 @@ __divdi3 (u, v)
 #ifdef L_moddi3
 UDItype __udivmoddi4 ();
 DItype
-__moddi3 (u, v)
-     DItype u, v;
+__moddi3 (DItype u, DItype v)
 {
   word_type c = 0;
   DIunion uu, vv;
@@ -699,8 +686,7 @@ __moddi3 (u, v)
 #ifdef L_umoddi3
 UDItype __udivmoddi4 ();
 UDItype
-__umoddi3 (u, v)
-     UDItype u, v;
+__umoddi3 (UDItype u, UDItype v)
 {
   UDItype w;
 
@@ -713,8 +699,7 @@ __umoddi3 (u, v)
 #ifdef L_udivdi3
 UDItype __udivmoddi4 ();
 UDItype
-__udivdi3 (n, d)
-     UDItype n, d;
+__udivdi3 (UDItype n, UDItype d)
 {
   return __udivmoddi4 (n, d, (UDItype *) 0);
 }
@@ -722,8 +707,7 @@ __udivdi3 (n, d)
 \f
 #ifdef L_cmpdi2
 word_type
-__cmpdi2 (a, b)
-     DItype a, b;
+__cmpdi2 (DItype a, DItype b)
 {
   DIunion au, bu;
 
@@ -743,8 +727,7 @@ __cmpdi2 (a, b)
 
 #ifdef L_ucmpdi2
 word_type
-__ucmpdi2 (a, b)
-     DItype a, b;
+__ucmpdi2 (DItype a, DItype b)
 {
   DIunion au, bu;
 
@@ -767,8 +750,7 @@ __ucmpdi2 (a, b)
 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
 
 DItype
-__fixunstfdi (a)
-     TFtype a;
+__fixunstfdi (TFtype a)
 {
   TFtype b;
   UDItype v;
@@ -797,8 +779,7 @@ __fixunstfdi (a)
 
 #if defined(L_fixtfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
 DItype
-__fixtfdi (a)
-     TFtype a;
+__fixtfdi (TFtype a)
 {
   if (a < 0)
     return - __fixunstfdi (-a);
@@ -811,8 +792,7 @@ __fixtfdi (a)
 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
 
 DItype
-__fixunsxfdi (a)
-     XFtype a;
+__fixunsxfdi (XFtype a)
 {
   XFtype b;
   UDItype v;
@@ -841,8 +821,7 @@ __fixunsxfdi (a)
 
 #if defined(L_fixxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
 DItype
-__fixxfdi (a)
-     XFtype a;
+__fixxfdi (XFtype a)
 {
   if (a < 0)
     return - __fixunsxfdi (-a);
@@ -855,8 +834,7 @@ __fixxfdi (a)
 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
 
 DItype
-__fixunsdfdi (a)
-     DFtype a;
+__fixunsdfdi (DFtype a)
 {
   DFtype b;
   UDItype v;
@@ -885,8 +863,7 @@ __fixunsdfdi (a)
 
 #ifdef L_fixdfdi
 DItype
-__fixdfdi (a)
-     DFtype a;
+__fixdfdi (DFtype a)
 {
   if (a < 0)
     return - __fixunsdfdi (-a);
@@ -946,8 +923,7 @@ __fixsfdi (SFtype a)
 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
 
 XFtype
-__floatdixf (u)
-     DItype u;
+__floatdixf (DItype u)
 {
   XFtype d;
   SItype negate = 0;
@@ -970,8 +946,7 @@ __floatdixf (u)
 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
 
 TFtype
-__floatditf (u)
-     DItype u;
+__floatditf (DItype u)
 {
   TFtype d;
   SItype negate = 0;
@@ -994,8 +969,7 @@ __floatditf (u)
 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
 
 DFtype
-__floatdidf (u)
-     DItype u;
+__floatdidf (DItype u)
 {
   DFtype d;
   SItype negate = 0;
@@ -1047,8 +1021,7 @@ __floatdidf (u)
 #endif
 
 SFtype
-__floatdisf (u)
-     DItype u;
+__floatdisf (DItype u)
 {
   /* Do the calculation in DFmode
      so that we don't lose any of the precision of the high word
@@ -1098,8 +1071,7 @@ __floatdisf (u)
 #include <limits.h>
 
 USItype
-__fixunsxfsi (a)
-     XFtype a;
+__fixunsxfsi (XFtype a)
 {
   if (a >= - (DFtype) LONG_MIN)
     return (SItype) (a + LONG_MIN) - LONG_MIN;
@@ -1121,8 +1093,7 @@ __fixunsxfsi (a)
 #include <limits.h>
 
 USItype
-__fixunsdfsi (a)
-     DFtype a;
+__fixunsdfsi (DFtype a)
 {
   if (a >= - (DFtype) LONG_MIN)
     return (SItype) (a + LONG_MIN) - LONG_MIN;
@@ -1176,9 +1147,7 @@ __fixunssfsi (SFtype a)
    positive if S1 is greater, 0 if S1 and S2 are equal.  */
 
 int
-__gcc_bcmp (s1, s2, size)
-     unsigned char *s1, *s2;
-     size_t size;
+__gcc_bcmp (unsigned char *s1, unsigned char *s2, size_t size)
 {
   while (size > 0)
     {
@@ -1192,6 +1161,11 @@ __gcc_bcmp (s1, s2, size)
 
 #endif
 \f\f
+#ifdef L__dummy
+void
+__dummy () {}
+#endif
+
 #ifdef L_varargs
 #ifdef __i860__
 #if defined(__svr4__) || defined(__alliant__)
@@ -1399,7 +1373,7 @@ asm ("___builtin_saveregs:");
   asm ("       sw      $7,12($30)");
   asm ("       j       $31");
   asm ("       .end __builtin_saveregs");
-#else /* not __mips__, etc. */
+#else /* not __mips__, etc.  */
 
 void *
 __builtin_saveregs ()
@@ -1419,11 +1393,8 @@ __builtin_saveregs ()
 #include <stdio.h>
 /* This is used by the `assert' macro.  */
 void
-__eprintf (string, expression, line, filename)
-     const char *string;
-     const char *expression;
-     int line;
-     const char *filename;
+__eprintf (const char *string, const char *expression,
+          int line, const char *filename)
 {
   fprintf (stderr, string, expression, line, filename);
   fflush (stderr);
@@ -1466,19 +1437,8 @@ BLOCK_PROFILER_CODE
 #include <stdio.h>
 char *ctime ();
 
-#ifdef HAVE_ATEXIT
-#ifdef WINNT
-extern int atexit (void (*) (void));
-#else
-extern void atexit (void (*) (void));
-#endif
-#define ON_EXIT(FUNC,ARG) atexit ((FUNC))
-#else
-#ifdef sun
-extern void on_exit (void*, void*);
-#define ON_EXIT(FUNC,ARG) on_exit ((FUNC), (ARG))
-#endif
-#endif
+#include "gbl-ctors.h"
+#include "gcov-io.h"
 
 static struct bb *bb_head;
 
@@ -1502,8 +1462,118 @@ static struct bb *bb_head;
 void
 __bb_exit_func (void)
 {
-  FILE *file = fopen ("bb.out", "a");
+  FILE *da_file, *file;
   long time_value;
+  int i;
+
+  if (bb_head == 0)
+    return;
+
+  i = strlen (bb_head->filename) - 3;
+
+  if (!strcmp (bb_head->filename+i, ".da"))
+    {
+      /* Must be -fprofile-arcs not -a.
+        Dump data in a form that gcov expects.  */
+
+      struct bb *ptr;
+
+      for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
+       {
+         /* If the file exists, and the number of counts in it is the same,
+            then merge them in.  */
+            
+         if ((da_file = fopen (ptr->filename, "r")) != 0)
+           {
+             long n_counts = 0;
+             unsigned char tmp;
+             int i;
+             int ret = 0;
+
+             
+             if (__read_long (&n_counts, da_file, 8) != 0)
+               {
+                 fprintf (stderr, "arc profiling: Can't read output file %s.\n",
+                          ptr->filename);
+                 continue;
+               }
+
+             if (n_counts == ptr->ncounts)
+               {
+                 int i;
+
+                 for (i = 0; i < n_counts; i++)
+                   {
+                     long v = 0;
+                     unsigned char tmp;
+                     int j;
+                     int ret = 0;
+
+                     if (__read_long (&v, da_file, 8) != 0)
+                       {
+                         fprintf (stderr, "arc profiling: Can't read output file %s.\n",
+                                  ptr->filename);
+                         break;
+                       }
+                     ptr->counts[i] += v;
+                   }
+               }
+
+             if (fclose (da_file) == EOF)
+               fprintf (stderr, "arc profiling: Error closing output file %s.\n",
+                        ptr->filename);
+           }
+         if ((da_file = fopen (ptr->filename, "w")) < 0)
+           {
+             fprintf (stderr, "arc profiling: Can't open output file %s.\n",
+                      ptr->filename);
+             continue;
+           }
+
+         /* ??? Should first write a header to the file.  Perferably, a 4 byte
+            magic number, 4 bytes containing the time the program was
+            compiled, 4 bytes containing the last modification time of the
+            source file, and 4 bytes indicating the compiler options used.
+
+            That way we can easily verify that the proper source/executable/
+            data file combination is being used from gcov.  */
+
+         if (__write_long (ptr->ncounts, da_file, 8) != 0)
+           {
+             
+             fprintf (stderr, "arc profiling: Error writing output file %s.\n",
+                      ptr->filename);
+           }
+         else
+           {
+             int j;
+             long *count_ptr = ptr->counts;
+             int ret = 0;
+             for (j = ptr->ncounts; j > 0; j--)
+               {
+                 if (__write_long (*count_ptr, da_file, 8) != 0)
+                   {
+                     ret=1;
+                     break;
+                   }
+                 count_ptr++;
+               }
+             if (ret)
+               fprintf (stderr, "arc profiling: Error writing output file %s.\n",
+                        ptr->filename);
+           }
+         
+         if (fclose (da_file) == EOF)
+           fprintf (stderr, "arc profiling: Error closing output file %s.\n",
+                    ptr->filename);
+       }
+
+      return;
+    }
+
+  /* Must be basic block profiling.  Emit a human readable output file.  */
+
+  file = fopen ("bb.out", "a");
 
   if (!file)
     perror ("bb.out");
@@ -1524,12 +1594,15 @@ __bb_exit_func (void)
       /* We check the length field explicitly in order to allow compatibility
         with older GCC's which did not provide it.  */
 
-      for (ptr = bb_head; ptr != (struct bb *)0; ptr = ptr->next)
+      for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
        {
          int i;
-         int func_p    = (ptr->nwords >= sizeof (struct bb) && ptr->nwords <= 1000);
+         int func_p    = (ptr->nwords >= sizeof (struct bb)
+                          && ptr->nwords <= 1000
+                          && ptr->functions);
          int line_p    = (func_p && ptr->line_nums);
          int file_p    = (func_p && ptr->filenames);
+         int addr_p    = (ptr->addresses != 0);
          long ncounts  = ptr->ncounts;
          long cnt_max  = 0;
          long line_max = 0;
@@ -1553,7 +1626,7 @@ __bb_exit_func (void)
              if (cnt_max < ptr->counts[i])
                cnt_max = ptr->counts[i];
 
-             if (addr_max < ptr->addresses[i])
+             if (addr_p && addr_max < ptr->addresses[i])
                addr_max = ptr->addresses[i];
 
              if (line_p && line_max < ptr->line_nums[i])
@@ -1584,10 +1657,13 @@ __bb_exit_func (void)
          for (i = 0; i < ncounts; i++)
            {
              fprintf (file,
-                      "    Block #%*d: executed %*ld time(s) address= 0x%.*lx",
+                      "    Block #%*d: executed %*ld time(s)",
                       blk_len, i+1,
-                      cnt_len, ptr->counts[i],
-                      addr_len, ptr->addresses[i]);
+                      cnt_len, ptr->counts[i]);
+
+             if (addr_p)
+               fprintf (file, " address= 0x%.*lx", addr_len,
+                        ptr->addresses[i]);
 
              if (func_p)
                fprintf (file, " function= %-*s", func_len,
@@ -1616,7 +1692,7 @@ void
 __bb_init_func (struct bb *blocks)
 {
   /* User is supposed to check whether the first word is non-0,
-     but just in case.... */
+     but just in case....  */
 
   if (blocks->zero_word)
     return;
@@ -1642,16 +1718,16 @@ __bb_init_func (struct bb *blocks)
 
 #include <string.h>
 
-/* Number of buckets in hashtable of basic block addresses. */
+/* Number of buckets in hashtable of basic block addresses.  */
 
 #define BB_BUCKETS 311
 
-/* Maximum length of string in file bb.in. */
+/* Maximum length of string in file bb.in.  */
 
 #define BBINBUFSIZE 500
 
 /* BBINBUFSIZE-1 with double quotes. We could use #BBINBUFSIZE or
-   "BBINBUFSIZE" but want to avoid trouble with preprocessors. */
+   "BBINBUFSIZE" but want to avoid trouble with preprocessors.  */
 
 #define BBINBUFSIZESTR "499"
 
@@ -1678,7 +1754,7 @@ struct bb_func
 
 /* This is the connection to the outside world.
    The BLOCK_PROFILER macro must set __bb.blocks
-   and __bb.blockno. */
+   and __bb.blockno.  */
 
 struct {
   unsigned long blockno;
@@ -1686,18 +1762,18 @@ struct {
 } __bb;
 
 /* Vars to store addrs of source and destination basic blocks 
-   of a jump. */
+   of a jump.  */
 
 static unsigned long bb_src = 0;
 static unsigned long bb_dst = 0;
 
-static FILE *bb_tracefile = (FILE*)0;
-static struct bb_edge **bb_hashbuckets = (struct bb_edge**)0;
-static struct bb_func *bb_func_head = (struct bb_func*)0;
+static FILE *bb_tracefile = (FILE *) 0;
+static struct bb_edge **bb_hashbuckets = (struct bb_edge **) 0;
+static struct bb_func *bb_func_head = (struct bb_func *) 0;
 static unsigned long bb_callcount = 0;
 static int bb_mode = 0;
 
-static unsigned long *bb_stack = (unsigned long *)0;
+static unsigned long *bb_stack = (unsigned long *) 0;
 static size_t bb_stacksize = 0;
 
 static int reported = 0;
@@ -1717,28 +1793,26 @@ bb_mode & 8 != 0   :   Insert return instructions in basic block flow.
 #include <sys/stat.h>
 /*#include <malloc.h>*/
 
-/* Commands executed by gopen. */
+/* Commands executed by gopen.  */
 
 #define GOPENDECOMPRESS "gzip -cd "
 #define GOPENCOMPRESS "gzip -c >"
 
 /* Like fopen but pipes through gzip.  mode may only be "r" or "w".
    If it does not compile, simply replace gopen by fopen and delete
-   '.gz' from any first parameter to gopen. */
+   '.gz' from any first parameter to gopen.  */
 
 static FILE *
-gopen (fn, mode)
-     char *fn;
-     char *mode;
+gopen (char *fn, char *mode)
 {
   int use_gzip;
   char *p;
 
   if (mode[1])
-    return (FILE*)0;
+    return (FILE *) 0;
 
   if (mode[0] != 'r' && mode[0] != 'w') 
-    return (FILE*)0;
+    return (FILE *) 0;
 
   p = fn + strlen (fn)-1;
   use_gzip = ((p[-1] == '.' && (p[0] == 'Z' || p[0] == 'z')) ||
@@ -1749,8 +1823,8 @@ gopen (fn, mode)
       if (mode[0]=='r')
         {
           FILE *f;
-          char *s = (char*) malloc (sizeof (char) * strlen (fn)
-                                    + sizeof (GOPENDECOMPRESS));
+          char *s = (char *) malloc (sizeof (char) * strlen (fn)
+                                    + sizeof (GOPENDECOMPRESS));
           strcpy (s, GOPENDECOMPRESS);
           strcpy (s + (sizeof (GOPENDECOMPRESS)-1), fn);
           f = popen (s, mode);
@@ -1761,8 +1835,8 @@ gopen (fn, mode)
       else
         {
           FILE *f;
-          char *s = (char*) malloc (sizeof (char) * strlen (fn)
-                                    + sizeof (GOPENCOMPRESS));
+          char *s = (char *) malloc (sizeof (char) * strlen (fn)
+                                    + sizeof (GOPENCOMPRESS));
           strcpy (s, GOPENCOMPRESS);
           strcpy (s + (sizeof (GOPENCOMPRESS)-1), fn);
           if (!(f = popen (s, mode)))
@@ -1777,12 +1851,11 @@ gopen (fn, mode)
 }
 
 static int
-gclose (f)
-     FILE *f;
+gclose (FILE *f)
 {
   struct stat buf;
 
-  if (f != NULL)
+  if (f != 0)
     {
       if (!fstat (fileno (f), &buf) && S_ISFIFO (buf.st_mode))
         return pclose (f);
@@ -1794,7 +1867,7 @@ gclose (f)
 
 #endif /* HAVE_POPEN */
 
-/* Called once per program. */
+/* Called once per program.  */
 
 static void
 __bb_exit_trace_func ()
@@ -1819,7 +1892,7 @@ __bb_exit_trace_func ()
 #endif /* HAVE_POPEN */
     }
 
-  /* Check functions in `bb.in'. */
+  /* Check functions in `bb.in'.  */
 
   if (file)
     {
@@ -1829,14 +1902,14 @@ __bb_exit_trace_func ()
       struct bb *ptr;
       long blk;
 
-      /* This is somewhat type incorrect. */
+      /* This is somewhat type incorrect.  */
       time ((void *) &time_value);
 
-      for (p = bb_func_head; p != (struct bb_func *)0; p = p->next)
+      for (p = bb_func_head; p != (struct bb_func *) 0; p = p->next)
         {
-          for (ptr = bb_head; ptr != (struct bb *)0; ptr = ptr->next)
+          for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
             {
-              if (!ptr->filename || p->filename != (char *)0 && strcmp (p->filename, ptr->filename))
+              if (!ptr->filename || p->filename != (char *) 0 && strcmp (p->filename, ptr->filename))
                 continue;
               for (blk = 0; blk < ptr->ncounts; blk++)
                 {
@@ -1901,7 +1974,7 @@ found:        ;
               break;
 
               case 4:
-               /* Print nothing. */
+               /* Print nothing.  */
               break;
 
               case 8:
@@ -1952,7 +2025,7 @@ found:        ;
    if (file)
      fclose (file);
 
-   /* Free allocated memory. */
+   /* Free allocated memory.  */
 
    f = bb_func_head;
    while (f)
@@ -1990,7 +2063,7 @@ found:        ;
      if (b->flags) free (b->flags);
 }
 
-/* Called once per program. */
+/* Called once per program.  */
 
 static void
 __bb_init_prg ()
@@ -2032,31 +2105,31 @@ __bb_init_prg ()
         bb_mode |= 8;
       else 
         {
-          struct bb_func *f = (struct bb_func*) malloc (sizeof (struct bb_func));
+          struct bb_func *f = (struct bb_func *) malloc (sizeof (struct bb_func));
           if (f)
             {
               unsigned long l;
               f->next = bb_func_head;
               if (pos = strchr (p, ':'))
                 {
-                  if (!(f->funcname = (char*) malloc (strlen (pos+1)+1)))
+                  if (!(f->funcname = (char *) malloc (strlen (pos+1)+1)))
                     continue;
                   strcpy (f->funcname, pos+1);
                   l = pos-p;
-                  if ((f->filename = (char*) malloc (l+1)))
+                  if ((f->filename = (char *) malloc (l+1)))
                     {
                       strncpy (f->filename, p, l);
                       f->filename[l] = '\0';
                     }
                   else
-                    f->filename = (char*)0;
+                    f->filename = (char *) 0;
                 }
               else
                 {
-                  if (!(f->funcname = (char*) malloc (strlen (p)+1)))
+                  if (!(f->funcname = (char *) malloc (strlen (p)+1)))
                     continue;
                   strcpy (f->funcname, p);
-                  f->filename = (char*)0;
+                  f->filename = (char *) 0;
                 }
               f->mode = m;
               bb_func_head = f;
@@ -2098,7 +2171,7 @@ __bb_init_prg ()
 
 }
 
-/* Called upon entering a basic block. */
+/* Called upon entering a basic block.  */
 
 void
 __bb_trace_func ()
@@ -2123,7 +2196,7 @@ __bb_trace_func ()
       struct bb_edge **startbucket, **oldnext;
 
       oldnext = startbucket =
-          & bb_hashbuckets[ (((int)bb_src*8)^(int)bb_dst) % BB_BUCKETS ];
+          & bb_hashbuckets[ (((int) bb_src*8) ^ (int) bb_dst) % BB_BUCKETS ];
       bucket = *startbucket;
 
       for (bucket = *startbucket; bucket; 
@@ -2171,7 +2244,7 @@ skip:
 
 }
 
-/* Called when returning from a function and `__bb_showret__' is set. */
+/* Called when returning from a function and `__bb_showret__' is set.  */
 
 static void
 __bb_trace_func_ret ()
@@ -2186,7 +2259,7 @@ __bb_trace_func_ret ()
       struct bb_edge **startbucket, **oldnext;
 
       oldnext = startbucket =
-          & bb_hashbuckets[ (((int)bb_dst*8)^(int)bb_src) % BB_BUCKETS ];
+          & bb_hashbuckets[ (((int) bb_dst * 8) ^ (int) bb_src) % BB_BUCKETS ];
       bucket = *startbucket;
 
       for (bucket = *startbucket; bucket; 
@@ -2232,11 +2305,10 @@ skip:
 
 }
 
-/* Called upon entering the first function of a file. */
+/* Called upon entering the first function of a file.  */
 
 static void
-__bb_init_file (blocks)
-     struct bb *blocks;
+__bb_init_file (struct bb *blocks)
 {
 
   const struct bb_func *p;
@@ -2250,7 +2322,7 @@ __bb_init_file (blocks)
 
   blocks->flags = 0;
   if (!bb_func_head ||
-      !(blocks->flags = (char*) malloc (sizeof (char) * blocks->ncounts)))
+      !(blocks->flags = (char *) malloc (sizeof (char) * blocks->ncounts)))
     return;
 
   for (blk = 0; blk < ncounts; blk++)
@@ -2270,7 +2342,7 @@ __bb_init_file (blocks)
 
 }
 
-/* Called when exiting from a function. */
+/* Called when exiting from a function.  */
 
 void
 __bb_trace_ret ()
@@ -2294,12 +2366,10 @@ __bb_trace_ret ()
 
 }
 
-/* Called when entering a function. */
+/* Called when entering a function.  */
 
 void
-__bb_init_trace_func (blocks, blockno)
-     struct bb *blocks;
-     unsigned long blockno;
+__bb_init_trace_func (struct bb *blocks, unsigned long blockno)
 {
   static int trace_init = 0;
 
@@ -2367,11 +2437,11 @@ stack_overflow:;
 #endif /* L_bb */
 \f
 /* Default free-store management functions for C++, per sections 12.5 and
-   17.3.3 of the Working Paper. */
+   17.3.3 of the Working Paper.  */
 
 #ifdef L_op_new
 /* operator new (size_t), described in 17.3.3.5.  This function is used by
-   C++ programs to allocate a block of memory to hold a single object. */
+   C++ programs to allocate a block of memory to hold a single object.  */
 
 typedef void (*vfp)(void);
 extern vfp __new_handler;
@@ -2427,7 +2497,7 @@ __builtin_vec_new (size_t sz)
 #ifdef L_new_handler
 /* set_new_handler (fvoid_t *) and the default new handler, described in
    17.3.3.2 and 17.3.3.5.  These functions define the result of a failure
-   to allocate the amount of memory requested from operator new or new []. */
+   to allocate the amount of memory requested from operator new or new [].  */
 
 #ifndef inhibit_libc
 /* This gets us __GNU_LIBRARY__.  */
@@ -2444,7 +2514,7 @@ __builtin_vec_new (size_t sz)
 typedef void (*vfp)(void);
 void __default_new_handler (void);
 
-vfp __new_handler = (vfp)0;
+vfp __new_handler = (vfp) 0;
 
 vfp
 set_new_handler (vfp handler)
@@ -2477,7 +2547,7 @@ __default_new_handler ()
 #ifdef L_op_delete
 /* operator delete (void *), described in 17.3.3.3.  This function is used
    by C++ programs to return to the free store a block of memory allocated
-   as a single object. */
+   as a single object.  */
 
 #ifdef WEAK_ALIAS
 void __builtin_delete (void *ptr)
@@ -2497,7 +2567,7 @@ __builtin_delete (void *ptr)
 #ifdef L_op_vdel
 /* operator delete [] (void *), described in 17.3.3.4.  This function is
    used by C++ programs to return to the free store a block of memory
-   allocated as an array. */
+   allocated as an array.  */
 
 extern void __builtin_delete (void *);
 
@@ -2536,8 +2606,7 @@ unsigned int __shtab[] = {
 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
 
 void
-__clear_cache (beg, end)
-     char *beg, *end;
+__clear_cache (char *beg, char *end)
 {
 #ifdef CLEAR_INSN_CACHE 
   CLEAR_INSN_CACHE (beg, end);
@@ -2567,7 +2636,7 @@ __clear_cache (beg, end)
            = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
          ptr += INSN_CACHE_LINE_WIDTH;
        }
-      *(INSTRUCTION_TYPE *)(ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
+      *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
 
       initialized = 1;
     }
@@ -2660,9 +2729,7 @@ long getpagesize()
 #endif
 }
 
-int mprotect(addr, len, prot)
-  char *addr;
-  int len, prot;
+int mprotect(char *addr, int len, int prot)
 {
   int np, op;
 
@@ -2697,8 +2764,7 @@ TRANSFER_FROM_TRAMPOLINE
 #endif
 
 void
-__enable_execute_stack (addr)
-     char *addr;
+__enable_execute_stack (char *addr)
 {
   kern_return_t r;
   char *eaddr = addr + TRAMPOLINE_SIZE;
@@ -2746,14 +2812,14 @@ __enable_execute_stack ()
       lowest = current;
     }
 
-  /* Clear instruction cache in case an old trampoline is in it. */
+  /* Clear instruction cache in case an old trampoline is in it.  */
   asm ("pich");
 }
 #endif /* __convex__ */
 
 #ifdef __DOLPHIN__
 
-/* Modified from the convex -code above. */
+/* Modified from the convex -code above.  */
 
 #include <sys/param.h>
 #include <errno.h>
@@ -2793,7 +2859,7 @@ __enable_execute_stack ()
 #include <sys/vmmac.h>
 
 /* Modified from the convex -code above.
-   mremap promises to clear the i-cache. */
+   mremap promises to clear the i-cache.  */
 
 void
 __enable_execute_stack ()
@@ -2808,6 +2874,31 @@ __enable_execute_stack ()
     }
 }
 #endif /* __pyr__ */
+
+#if defined (sony_news) && defined (SYSTYPE_BSD)
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <syscall.h>
+#include <machine/sysnews.h>
+
+/* cacheflush function for NEWS-OS 4.2.
+   This function is called from trampoline-initialize code
+   defined in config/mips/mips.h.  */
+
+void
+cacheflush (char *beg, int size, int flag)
+{
+  if (syscall (SYS_sysnews, NEWS_CACHEFLUSH, beg, size, FLUSH_BCACHE))
+    {
+      perror ("cache_flush");
+      fflush (stderr);
+      abort ();
+    }
+}
+
+#endif /* sony_news */
 #endif /* L_trampoline */
 \f
 #ifdef L__main
@@ -2816,13 +2907,18 @@ __enable_execute_stack ()
 /* 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
-   must define both, or neither. */
+   must define both, or neither.  */
 #ifndef NAME__MAIN
 #define NAME__MAIN "__main"
 #define SYMBOL__MAIN __main
 #endif
 
-#if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
+#ifdef INIT_SECTION_ASM_OP
+#undef HAS_INIT_SECTION
+#define HAS_INIT_SECTION
+#endif
+
+#if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
 /* Run all the global destructors on exit from the program.  */
 
 void
@@ -2831,14 +2927,17 @@ __do_global_dtors ()
 #ifdef DO_GLOBAL_DTORS_BODY
   DO_GLOBAL_DTORS_BODY;
 #else
-  func_ptr *p;
-  for (p = __DTOR_LIST__ + 1; *p; )
-    (*p++) ();
+  static func_ptr *p = __DTOR_LIST__ + 1;
+  while (*p)
+    {
+      p++;
+      (*(p-1)) ();
+    }
 #endif
 }
 #endif
 
-#ifndef INIT_SECTION_ASM_OP
+#ifndef HAS_INIT_SECTION
 /* Run all the global constructors on entry to the program.  */
 
 #ifndef ON_EXIT
@@ -2858,9 +2957,9 @@ __do_global_ctors ()
   DO_GLOBAL_CTORS_BODY;
   ON_EXIT (__do_global_dtors, 0);
 }
-#endif /* no INIT_SECTION_ASM_OP */
+#endif /* no HAS_INIT_SECTION */
 
-#if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
+#if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
 /* Subroutine called automatically by `main'.
    Compiling a global function named `main'
    produces an automatic call to this function at the beginning.
@@ -2880,7 +2979,7 @@ SYMBOL__MAIN ()
       __do_global_ctors ();
     }
 }
-#endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
+#endif /* no HAS_INIT_SECTION or INVOKE__main */
 
 #endif /* L__main */
 \f
@@ -2911,22 +3010,75 @@ func_ptr __DTOR_LIST__[2];
 
 #include "gbl-ctors.h"
 
+#ifdef NEED_ATEXIT
+# ifdef ON_EXIT
+#  undef ON_EXIT
+# endif
+int _exit_dummy_decl = 0;      /* prevent compiler & linker warnings */
+#endif
+
 #ifndef ON_EXIT
 
+#ifdef NEED_ATEXIT
+# include <errno.h>
+
+static func_ptr *atexit_chain = 0;
+static long atexit_chain_length = 0;
+static volatile long last_atexit_chain_slot = -1;
+
+int atexit (func_ptr func)
+{
+  if (++last_atexit_chain_slot == atexit_chain_length)
+    {
+      atexit_chain_length += 32;
+      if (atexit_chain)
+       atexit_chain = realloc (atexit_chain,
+                               atexit_chain_length * sizeof (func_ptr));
+      else
+       atexit_chain = malloc (atexit_chain_length * sizeof (func_ptr));
+      if (! atexit_chain)
+       {
+         atexit_chain_length = 0;
+         last_atexit_chain_slot = -1;
+         errno = ENOMEM;
+         return (-1);
+       }
+    }
+  atexit_chain[last_atexit_chain_slot] = func;
+  return (0);
+}
+#endif /* NEED_ATEXIT */
+
 /* If we have no known way of registering our own __do_global_dtors
    routine so that it will be invoked at program exit time, then we
    have to define our own exit routine which will get this to happen.  */
 
 extern void __do_global_dtors ();
+extern void __bb_exit_func ();
 extern void _cleanup ();
 extern void _exit () __attribute__ ((noreturn));
 
 void 
-exit (status)
-     int status;
+exit (int status)
 {
 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
+#ifdef NEED_ATEXIT
+  if (atexit_chain)
+    {
+      for ( ; last_atexit_chain_slot-- >= 0; )
+       {
+         (*atexit_chain[last_atexit_chain_slot + 1]) ();
+         atexit_chain[last_atexit_chain_slot + 1] = 0;
+       }
+      free (atexit_chain);
+      atexit_chain = 0;
+    }
+#else /* No NEED_ATEXIT */
   __do_global_dtors ();
+#endif /* No NEED_ATEXIT */
+#endif
+#ifndef inhibit_libc
+  __bb_exit_func ();
 #endif
 #ifdef EXIT_BODY
   EXIT_BODY;
@@ -2943,6 +3095,13 @@ int _exit_dummy_decl = 0;        /* prevent compiler & linker warnings */
 #endif /* L_exit */
 \f
 #ifdef L_eh
+
+#ifdef EH_TABLE_LOOKUP
+
+EH_TABLE_LOOKUP
+
+#else
+
 typedef struct {
   void *start;
   void *end;
@@ -2956,23 +3115,8 @@ struct exception_table_node {
   struct exception_table_node *next;
 };
 
-static int except_table_pos;
-static void *except_pc;
 static struct exception_table_node *exception_table_list;
 
-static exception_table *
-find_exception_table (pc)
-     void* pc;
-{
-  register struct exception_table_node *table = exception_table_list;
-  for ( ; table != 0; table = table->next)
-    {
-      if (table->start <= pc && table->end > pc)
-       return table->table;
-    }
-  return 0;
-}
-
 /* this routine takes a pc, and 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.  The algorithm works
@@ -2995,77 +3139,69 @@ find_exception_table (pc)
    return the tightest match...
 
    In the advent of a tie, we have to give the last entry, as it represents
-   an inner block.
- */
-
+   an inner block.  */
 
 void *
-__find_first_exception_table_match(pc)
-void *pc;
-{
-  exception_table *table = find_exception_table (pc);
-  int pos = 0;
-  int best = 0;
-  if (table == 0)
-    return (void*)0;
+__find_first_exception_table_match (void *pc)
+{
+  register struct exception_table_node *tnp;
+  register exception_table *table;
+  int pos;
+  int best;
+
 #if 0
-  printf("find_first_exception_table_match(): pc = %x!\n",pc);
+  printf ("find_first_exception_table_match (): pc = %x!\n", pc);
 #endif
 
-  except_pc = pc;
+  for (tnp = exception_table_list; tnp != 0; tnp = tnp->next)
+    {
+      if (tnp->start > pc || tnp->end <= pc)
+       continue;
+
+      table = tnp->table;
 
+      pos = 0;
+      best = 0;
 #if 0
-  /* We can't do this yet, as we don't know that the table is sorted.  */
-  do {
-    ++pos;
-    if (table[pos].start > except_pc)
-      /* found the first table[pos].start > except_pc, so the previous
-        entry better be the one we want! */
-      break;
-  } while(table[pos].exception_handler != (void*)-1);
-
-  --pos;
-  if (table[pos].start <= except_pc && table[pos].end > except_pc)
-    {
-      except_table_pos = pos;
+      /* We can't do this yet, as we don't know that the table is sorted.  */
+      do {
+       ++pos;
+       if (table[pos].start > pc)
+         /* found the first table[pos].start > pc, so the previous
+            entry better be the one we want! */
+         break;
+      } while (table[pos].exception_handler != (void *) -1);
+
+      --pos;
+      if (table[pos].start <= pc && table[pos].end > pc)
+       {
 #if 0
-      printf("find_first_eh_table_match(): found match: %x\n",table[pos].exception_handler);
+         printf ("find_first_eh_table_match (): found match: %x\n", table[pos].exception_handler);
 #endif
-      return table[pos].exception_handler;
-    }
+         return table[pos].exception_handler;
+       }
 #else
-  while (table[++pos].exception_handler != (void*)-1) {
-    if (table[pos].start <= except_pc && table[pos].end > except_pc)
-      {
-       /* This can apply.  Make sure it is better or as good as the previous
-          best.  */
-       /* The best one ends first. */
-       if (best == 0 || (table[pos].end <= table[best].end
-                         /* The best one starts last.  */
-                         && table[pos].start >= table[best].start))
-         best = pos;
+      while (table[++pos].exception_handler != (void *) -1) {
+       if (table[pos].start <= pc && table[pos].end > pc)
+         {
+           /* This can apply.  Make sure it is better or as good as
+              the previous best.  */
+           /* The best one ends first.  */
+           if (best == 0 || (table[pos].end <= table[best].end
+                             /* The best one starts last.  */
+                             && table[pos].start >= table[best].start))
+             best = pos;
+         }
       }
-  }
-  if (best != 0)
-    return table[best].exception_handler;
+      if (best != 0)
+       return table[best].exception_handler;
 #endif
+    }
 
 #if 0
-  printf("find_first_eh_table_match(): else: returning NULL!\n");
+  printf ("find_first_eh_table_match (): else: returning NULL!\n");
 #endif
-  return (void*)0;
-}
-
-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;
+  return (void *) 0;
 }
 
 void
@@ -3074,18 +3210,18 @@ __register_exceptions (exception_table *table)
   struct exception_table_node *node;
   exception_table *range = table + 1;
 
-  if (range->start == (void*)-1)
+  if (range->start == (void *) -1)
     return;
 
-  node = (struct exception_table_node*)
+  node = (struct exception_table_node *)
     malloc (sizeof (struct exception_table_node));
   node->table = table;
 
   /* This look can be optimized away either if the table
-     is sorted, or if we pass in extra parameters. */
+     is sorted, or if we pass in extra parameters.  */
   node->start = range->start;
   node->end = range->end;
-  for (range++ ; range->start != (void*)(-1); range++)
+  for (range++ ; range->start != (void *) (-1); range++)
     {
       if (range->start < node->start)
        node->start = range->start;
@@ -3096,6 +3232,34 @@ __register_exceptions (exception_table *table)
   node->next = exception_table_list;
   exception_table_list = node;
 }
+#endif
+
+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;
+}
+
+/* Throw stub routine.
+
+   This is work in progress, but not completed yet.  */
+
+void
+__throw ()
+{
+  abort ();
+}
+
+/* This value identifies the place from which an exception is being
+   thrown.  */
+
+void *__eh_pc;
 
 void
 __empty ()
@@ -3113,9 +3277,9 @@ __unwind_function(void *ptr)
   /* like ret, but stay here */
   asm("addl $4,%esp");
   
-  /* Now, undo previous frame. */
+  /* Now, undo previous frame.  */
   /* This is a test routine, as we have to dynamically probe to find out
-     what to pop for certain, this is just a guess. */
+     what to pop for certain, this is just a guess.  */
   asm("leal -16(%ebp),%esp");
   asm("pop %ebx");
   asm("pop %esi");
@@ -3126,7 +3290,7 @@ __unwind_function(void *ptr)
   asm("movl %ecx,0(%esp)");
   asm("ret");
 }
-#elif #machine(rs6000)
+#elif #machine(rs6000) && !defined _ARCH_PPC
 __unwind_function(void *ptr)
 {
   asm("mr 31,1");
@@ -3136,13 +3300,13 @@ __unwind_function(void *ptr)
 
   asm("mr 31,1");
   asm("l 1,0(1)");
-  /* use 31 as a scratch register to restore the link register. */
+  /* use 31 as a scratch register to restore the link register.  */
   asm("l 31, 8(1);mtlr 31 # l lr,8(1)");
   asm("l 31,-4(1)");
   asm("# br");
   asm("mtctr 3;bctr # b 3");
 }
-#elif #machine(powerpc)
+#elif (#machine(rs6000) || #machine(powerpc)) && defined _ARCH_PPC
 __unwind_function(void *ptr)
 {
   asm("mr 31,1");
@@ -3152,7 +3316,7 @@ __unwind_function(void *ptr)
 
   asm("mr 31,1");
   asm("lwz 1,0(1)");
-  /* use 31 as a scratch register to restore the link register. */
+  /* use 31 as a scratch register to restore the link register.  */
   asm("lwz 31, 8(1);mtlr 31 # l lr,8(1)");
   asm("lwz 31,-4(1)");
   asm("# br");