OSDN Git Service

(__udiv_w_sdiv): If we don't have sdiv_qrnnd, define dummy variant of
[pf3gnuchains/gcc-fork.git] / gcc / libgcc2.c
index e5a1e09..3d9637c 100644 (file)
@@ -16,7 +16,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+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,
@@ -31,6 +32,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include "tconfig.h"
 #include "machmode.h"
+#include "defaults.h" 
 #ifndef L_trampoline
 #include <stddef.h>
 #endif
@@ -40,6 +42,10 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #undef abort
 #endif
 
+#if (SUPPORTS_WEAK == 1) && defined (ASM_OUTPUT_DEF)
+#define WEAK_ALIAS
+#endif
+
 /* Permit the tm.h file to select the endianness to use just for this
    file.  This is used when the endianness is determined when the
    compiler is run.  */
@@ -110,7 +116,9 @@ typedef union
   DItype ll;
 } DIunion;
 
-#if defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_w_sdiv)
+#if (defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_w_sdiv)\
+     || defined (L_divdi3) || defined (L_udivdi3) \
+     || defined (L_moddi3) || defined (L_umoddi3))
 
 #include "longlong.h"
 
@@ -283,6 +291,7 @@ __muldi3 (u, v)
 #endif
 \f
 #ifdef L_udiv_w_sdiv
+#if defined (sdiv_qrnnd)
 USItype
 __udiv_w_sdiv (rp, a1, a0, d)
      USItype *rp, a1, a0, d;
@@ -380,8 +389,20 @@ __udiv_w_sdiv (rp, a1, a0, d)
   *rp = r;
   return q;
 }
+#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;
+{}
+#endif
 #endif
 \f
+#if (defined (L_udivdi3) || defined (L_divdi3) || \
+     defined (L_umoddi3) || defined (L_moddi3))
+#define L_udivmoddi4
+#endif
+
 #ifdef L_udivmoddi4
 static const UQItype __clz_tab[] =
 {
@@ -395,6 +416,10 @@ 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,
 };
 
+#if (defined (L_udivdi3) || defined (L_divdi3) || \
+     defined (L_umoddi3) || defined (L_moddi3))
+static inline
+#endif
 UDItype
 __udivmoddi4 (n, d, rp)
      UDItype n, d;
@@ -992,25 +1017,35 @@ __floatdidf (u)
 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
 #define DI_SIZE (sizeof (DItype) * BITS_PER_UNIT)
-#if TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
+
+/* Define codes for all the float formats that we know of.  Note
+   that this is copied from real.h.  */
+   
+#define UNKNOWN_FLOAT_FORMAT 0
+#define IEEE_FLOAT_FORMAT 1
+#define VAX_FLOAT_FORMAT 2
+#define IBM_FLOAT_FORMAT 3
+
+/* Default to IEEE float if not specified.  Nearly all machines use it.  */
+#ifndef HOST_FLOAT_FORMAT
+#define        HOST_FLOAT_FORMAT       IEEE_FLOAT_FORMAT
+#endif
+
+#if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
 #define DF_SIZE 53
 #define SF_SIZE 24
-#else
-#if TARGET_FLOAT_FORMAT == IBM_FLOAT_FORMAT
+#endif
+
+#if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
 #define DF_SIZE 56
 #define SF_SIZE 24
-#else
-#if TARGET_FLOAT_FORMAT == VAX_FLOAT_FORMAT
+#endif
+
+#if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
 #define DF_SIZE 56
 #define SF_SIZE 24
-#else
-#define DF_SIZE 0
-#define SF_SIZE 0
-#endif
-#endif
 #endif
 
-
 SFtype
 __floatdisf (u)
      DItype u;
@@ -1131,7 +1166,7 @@ __fixunssfsi (SFtype a)
 #ifdef L__gcc_bcmp
 
 /* Like bcmp except the sign is meaningful.
-   Reult is negative if S1 is less than S2,
+   Result is negative if S1 is less than S2,
    positive if S1 is greater, 0 if S1 and S2 are equal.  */
 
 int
@@ -1417,7 +1452,7 @@ BLOCK_PROFILER_CODE
 #ifndef inhibit_libc
 
 /* Simple minded basic block profiling output dumper for
-   systems that don't provde tcov support.  At present,
+   systems that don't provide tcov support.  At present,
    it requires atexit and stdio.  */
 
 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
@@ -1425,7 +1460,11 @@ BLOCK_PROFILER_CODE
 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
@@ -1434,7 +1473,7 @@ extern void on_exit (void*, void*);
 #endif
 #endif
 
-static struct bb *bb_head = (struct bb *)0;
+static struct bb *bb_head;
 
 /* Return the number of digits needed to print a value */
 /* __inline__ */ static int num_digits (long value, int base)
@@ -1600,11 +1639,20 @@ __bb_init_func (struct bb *blocks)
 
 typedef void (*vfp)(void);
 extern vfp __new_handler;
+extern void __default_new_handler (void);
 
+#ifdef WEAK_ALIAS
+void * __builtin_new (size_t sz)
+     __attribute__ ((weak, alias ("___builtin_new")));
+void *
+___builtin_new (size_t sz)
+#else
 void *
 __builtin_new (size_t sz)
+#endif
 {
   void *p;
+  vfp handler = (__new_handler) ? __new_handler : __default_new_handler;
 
   /* malloc (0) is unpredictable; avoid it.  */
   if (sz == 0)
@@ -1612,7 +1660,7 @@ __builtin_new (size_t sz)
   p = (void *) malloc (sz);
   while (p == 0)
     {
-      (*__new_handler) ();
+      (*handler) ();
       p = (void *) malloc (sz);
     }
   
@@ -1626,8 +1674,15 @@ __builtin_new (size_t sz)
 
 extern void * __builtin_new (size_t);
 
+#ifdef WEAK_ALIAS
+void * __builtin_vec_new (size_t sz)
+     __attribute__ ((weak, alias ("___builtin_vec_new")));
+void *
+___builtin_vec_new (size_t sz)
+#else
 void *
 __builtin_vec_new (size_t sz)
+#endif
 {
   return __builtin_new (sz);
 }
@@ -1653,7 +1708,7 @@ __builtin_vec_new (size_t sz)
 typedef void (*vfp)(void);
 void __default_new_handler (void);
 
-vfp __new_handler = __default_new_handler;
+vfp __new_handler = (vfp)0;
 
 vfp
 set_new_handler (vfp handler)
@@ -1688,8 +1743,15 @@ __default_new_handler ()
    by C++ programs to return to the free store a block of memory allocated
    as a single object. */
 
+#ifdef WEAK_ALIAS
+void __builtin_delete (void *ptr)
+     __attribute__ ((weak, alias ("___builtin_delete")));
+void
+___builtin_delete (void *ptr)
+#else
 void
 __builtin_delete (void *ptr)
+#endif
 {
   if (ptr)
     free (ptr);
@@ -1703,8 +1765,15 @@ __builtin_delete (void *ptr)
 
 extern void __builtin_delete (void *);
 
+#ifdef WEAK_ALIAS
+void __builtin_vec_delete (void *ptr)
+     __attribute__ ((weak, alias ("___builtin_vec_delete")));
+void
+___builtin_vec_delete (void *ptr)
+#else
 void
 __builtin_vec_delete (void *ptr)
+#endif
 {
   __builtin_delete (ptr);
 }
@@ -1739,7 +1808,7 @@ __clear_cache (beg, end)
 #else
 #ifdef INSN_CACHE_SIZE
   static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
-  static int initialized = 0;
+  static int initialized;
   int offset;
   void *start_addr
   void *end_addr;
@@ -1978,7 +2047,7 @@ __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 niether. */
+   must define both, or neither. */
 #ifndef NAME__MAIN
 #define NAME__MAIN "__main"
 #define SYMBOL__MAIN __main
@@ -2035,7 +2104,7 @@ void
 SYMBOL__MAIN ()
 {
   /* Support recursive calls to `main': run initializers just once.  */
-  static int initialized = 0;
+  static int initialized;
   if (! initialized)
     {
       initialized = 1;
@@ -2087,7 +2156,9 @@ void
 exit (status)
      int status;
 {
+#if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
   __do_global_dtors ();
+#endif
 #ifdef EXIT_BODY
   EXIT_BODY;
 #else
@@ -2116,9 +2187,9 @@ struct exception_table_node {
   struct exception_table_node *next;
 };
 
-static int except_table_pos = 0;
-static void *except_pc = (void *)0;
-static struct exception_table_node *exception_table_list = 0;
+static int except_table_pos;
+static void *except_pc;
+static struct exception_table_node *exception_table_list;
 
 static exception_table *
 find_exception_table (pc)
@@ -2152,7 +2223,7 @@ find_exception_table (pc)
     return 0;
 
    Assuming a correctly sorted table (ascending order) this routine should
-   return the tighest match...
+   return the tightest match...
 
    In the advent of a tie, we have to give the last entry, as it represents
    an inner block.
@@ -2216,22 +2287,29 @@ void *pc;
   return (void*)0;
 }
 
-int
-__throw_type_match (const char *catch_type, const char *throw_type)
+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
- return strcmp (catch_type, throw_type);
+ if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)
+   return obj;
+ return 0;
 }
 
 void
 __register_exceptions (exception_table *table)
 {
-  struct exception_table_node *node = (struct exception_table_node*)
-      malloc (sizeof (struct exception_table_node));
+  struct exception_table_node *node;
   exception_table *range = table + 1;
+
+  if (range->start == (void*)-1)
+    return;
+
+  node = (struct exception_table_node*)
+    malloc (sizeof (struct exception_table_node));
   node->table = table;
 
   /* This look can be optimized away either if the table
@@ -2250,7 +2328,7 @@ __register_exceptions (exception_table *table)
   exception_table_list = node;
 }
 
-#ifdef __i386
+#if #machine(i386)
 void
 __unwind_function(void *ptr)
 {
@@ -2258,16 +2336,16 @@ __unwind_function(void *ptr)
   /* Undo current frame */
   asm("movl %ebp,%esp");
   asm("popl %ebp");
-  asm("# like ret, but stay here");
+  /* like ret, but stay here */
   asm("addl $4,%esp");
   
   /* 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. */
   asm("leal -16(%ebp),%esp");
-  asm("pop %eax # really for popl %ebx");
-  asm("pop %eax # really for popl %esi");
-  asm("pop %eax # really for popl %edi");
+  asm("pop %eax"); /* really for popl %ebx */
+  asm("pop %eax"); /* really for popl %esi */
+  asm("pop %eax"); /* really for popl %edi */
   asm("movl %ebp,%esp");
   asm("popl %ebp");
 
@@ -2275,6 +2353,42 @@ __unwind_function(void *ptr)
   asm("ret");
 }
 #endif
+
+#if #machine(rs6000)
+__unwind_function(void *ptr)
+{
+  asm("mr 31,1");
+  asm("l 1,0(1)");
+  asm("l 31,-4(1)");
+  asm("# br");
+
+  asm("mr 31,1");
+  asm("l 1,0(1)");
+  /* 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");
+}
+#endif /* rs6000 */
+
+#if #machine(powerpc)
+__unwind_function(void *ptr)
+{
+  asm("mr 31,1");
+  asm("lwz 1,0(1)");
+  asm("lwz 31,-4(1)");
+  asm("# br");
+
+  asm("mr 31,1");
+  asm("lwz 1,0(1)");
+  /* 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");
+  asm("mtctr 3;bctr # b 3");
+}
+#endif /* powerpc */
 #endif /* L_eh */
 \f
 #ifdef L_pure