libgcc2.c: Delete sysV68 L_trampoline section.
[platform/upstream/gcc.git] / gcc / libgcc2.c
index 4260e25..f898ba9 100644 (file)
@@ -1,7 +1,7 @@
 /* More subroutines needed by GCC output code on some machines.  */
 /* Compile this one with gcc.  */
 /* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002  Free Software Foundation, Inc.
+   2000, 2001, 2002, 2003  Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -129,7 +129,7 @@ DWtype
 __subvdi3 (DWtype a, DWtype b)
 {
 #ifdef L_addvdi3
-  return (a, (-b));
+  return __addvdi3 (a, (-b));
 #else
   DWtype w;
 
@@ -340,9 +340,27 @@ __ashrdi3 (DWtype u, word_type b)
 }
 #endif
 \f
+#ifdef L_ffssi2
+#undef int
+extern int __ffsSI2 (UWtype u);
+int
+__ffsSI2 (UWtype u)
+{
+  UWtype count;
+
+  if (u == 0)
+    return 0;
+
+  count_trailing_zeros (count, u);
+  return count + 1;
+}
+#endif
+\f
 #ifdef L_ffsdi2
-Wtype
-__ffsdi2 (DWtype u)
+#undef int
+extern int __ffsDI2 (DWtype u);
+int
+__ffsDI2 (DWtype u)
 {
   DWunion uu;
   UWtype word, count, add;
@@ -520,38 +538,34 @@ const UQItype __clz_tab[] =
 #endif
 \f
 #ifdef L_clzsi2
-Wtype
-__clzsi2 (USItype x)
+#undef int
+extern int __clzSI2 (UWtype x);
+int
+__clzSI2 (UWtype x)
 {
-  UWtype w = x;
   Wtype ret;
 
-  count_leading_zeros (ret, w);
-  ret -= (sizeof(w) - sizeof(x)) * BITS_PER_UNIT;
+  count_leading_zeros (ret, x);
 
   return ret;
 }
 #endif
 \f
 #ifdef L_clzdi2
-Wtype
-__clzdi2 (UDItype x)
+#undef int
+extern int __clzDI2 (UDWtype x);
+int
+__clzDI2 (UDWtype x)
 {
+  DWunion uu;
   UWtype word;
   Wtype ret, add;
 
-  if (sizeof(x) > sizeof(word))
-    {
-      DWunion uu;
-
-      uu.ll = x;
-      if (uu.s.high)
-       word = uu.s.high, add = 0;
-      else
-       word = uu.s.low, add = W_TYPE_SIZE;
-    }
+  uu.ll = x;
+  if (uu.s.high)
+    word = uu.s.high, add = 0;
   else
-    word = x, add = (Wtype)(sizeof(x) - sizeof(word)) * BITS_PER_UNIT;
+    word = uu.s.low, add = W_TYPE_SIZE;
 
   count_leading_zeros (ret, word);
   return ret + add;
@@ -559,8 +573,10 @@ __clzdi2 (UDItype x)
 #endif
 \f
 #ifdef L_ctzsi2
-Wtype
-__ctzsi2 (USItype x)
+#undef int
+extern int __ctzSI2 (UWtype x);
+int
+__ctzSI2 (UWtype x)
 {
   Wtype ret;
 
@@ -571,24 +587,20 @@ __ctzsi2 (USItype x)
 #endif
 \f
 #ifdef L_ctzdi2
-Wtype
-__ctzdi2 (UDItype x)
+#undef int
+extern int __ctzDI2 (UDWtype x);
+int
+__ctzDI2 (UDWtype x)
 {
+  DWunion uu;
   UWtype word;
   Wtype ret, add;
 
-  if (sizeof(x) > sizeof(word))
-    {
-      DWunion uu;
-
-      uu.ll = x;
-      if (uu.s.low)
-       word = uu.s.low, add = 0;
-      else
-       word = uu.s.high, add = W_TYPE_SIZE;
-    }
+  uu.ll = x;
+  if (uu.s.low)
+    word = uu.s.low, add = 0;
   else
-    word = x, add = 0;
+    word = uu.s.high, add = W_TYPE_SIZE;
 
   count_trailing_zeros (ret, word);
   return ret + add;
@@ -615,56 +627,82 @@ const UQItype __popcount_tab[] =
 #endif
 \f
 #ifdef L_popcountsi2
-Wtype
-__popcountsi2 (USItype x)
+#undef int
+extern int __popcountSI2 (UWtype x);
+int
+__popcountSI2 (UWtype x)
 {
-  return __popcount_tab[(x >>  0) & 0xff]
-       + __popcount_tab[(x >>  8) & 0xff]
-       + __popcount_tab[(x >> 16) & 0xff]
-       + __popcount_tab[(x >> 24) & 0xff];
+  UWtype i, ret = 0;
+
+  for (i = 0; i < W_TYPE_SIZE; i += 8)
+    ret += __popcount_tab[(x >> i) & 0xff];
+
+  return ret;
 }
 #endif
 \f
 #ifdef L_popcountdi2
-Wtype
-__popcountdi2 (UDItype x)
+#undef int
+extern int __popcountDI2 (UDWtype x);
+int
+__popcountDI2 (UDWtype x)
 {
-  return __popcount_tab[(x >>  0) & 0xff]
-       + __popcount_tab[(x >>  8) & 0xff]
-       + __popcount_tab[(x >> 16) & 0xff]
-       + __popcount_tab[(x >> 24) & 0xff]
-       + __popcount_tab[(x >> 32) & 0xff]
-       + __popcount_tab[(x >> 40) & 0xff]
-       + __popcount_tab[(x >> 48) & 0xff]
-       + __popcount_tab[(x >> 56) & 0xff];
+  UWtype i, ret = 0;
+
+  for (i = 0; i < 2*W_TYPE_SIZE; i += 8)
+    ret += __popcount_tab[(x >> i) & 0xff];
+
+  return ret;
 }
 #endif
 \f
 #ifdef L_paritysi2
-Wtype
-__paritysi2 (USItype x)
+#undef int
+extern int __paritySI2 (UWtype x);
+int
+__paritySI2 (UWtype x)
 {
-  UWtype nx = x;
-  nx ^= nx >> 16;
-  nx ^= nx >> 8;
-  nx ^= nx >> 4;
-  nx ^= nx >> 2;
-  nx ^= nx >> 1;
-  return nx & 1;
+#if W_TYPE_SIZE > 64
+# error "fill out the table"
+#endif
+#if W_TYPE_SIZE > 32
+  x ^= x >> 32;
+#endif
+#if W_TYPE_SIZE > 16
+  x ^= x >> 16;
+#endif
+  x ^= x >> 8;
+  x ^= x >> 4;
+  x &= 0xf;
+  return (0x6996 >> x) & 1;
 }
 #endif
 \f
 #ifdef L_paritydi2
-Wtype
-__paritydi2 (UDItype x)
+#undef int
+extern int __parityDI2 (UDWtype x);
+int
+__parityDI2 (UDWtype x)
 {
-  UWtype nx = x ^ (x >> 32);
+  DWunion uu;
+  UWtype nx;
+
+  uu.ll = x;
+  nx = uu.s.low ^ uu.s.high;
+
+#if W_TYPE_SIZE > 64
+# error "fill out the table"
+#endif
+#if W_TYPE_SIZE > 32
+  nx ^= nx >> 32;
+#endif
+#if W_TYPE_SIZE > 16
   nx ^= nx >> 16;
+#endif
   nx ^= nx >> 8;
   nx ^= nx >> 4;
-  nx ^= nx >> 2;
-  nx ^= nx >> 1;
-  return nx & 1;
+  nx &= 0xf;
+  return (0x6996 >> nx) & 1;
 }
 #endif
 
@@ -1398,113 +1436,12 @@ __eprintf (const char *string, const char *expression,
 #ifdef L_clear_cache
 /* Clear part of an instruction cache.  */
 
-#define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
-
 void
 __clear_cache (char *beg __attribute__((__unused__)),
               char *end __attribute__((__unused__)))
 {
 #ifdef CLEAR_INSN_CACHE
   CLEAR_INSN_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;
-  int offset;
-  void *start_addr
-  void *end_addr;
-  typedef (*function_ptr) (void);
-
-#if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
-  /* It's cheaper to clear the whole cache.
-     Put in a series of jump instructions so that calling the beginning
-     of the cache will clear the whole thing.  */
-
-  if (! initialized)
-    {
-      int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
-                & -INSN_CACHE_LINE_WIDTH);
-      int end_ptr = ptr + INSN_CACHE_SIZE;
-
-      while (ptr < end_ptr)
-       {
-         *(INSTRUCTION_TYPE *)ptr
-           = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
-         ptr += INSN_CACHE_LINE_WIDTH;
-       }
-      *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
-
-      initialized = 1;
-    }
-
-  /* Call the beginning of the sequence.  */
-  (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
-                   & -INSN_CACHE_LINE_WIDTH))
-   ());
-
-#else /* Cache is large.  */
-
-  if (! initialized)
-    {
-      int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
-                & -INSN_CACHE_LINE_WIDTH);
-
-      while (ptr < (int) array + sizeof array)
-       {
-         *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
-         ptr += INSN_CACHE_LINE_WIDTH;
-       }
-
-      initialized = 1;
-    }
-
-  /* Find the location in array that occupies the same cache line as BEG.  */
-
-  offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
-  start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
-                & -INSN_CACHE_PLANE_SIZE)
-               + offset);
-
-  /* Compute the cache alignment of the place to stop clearing.  */
-#if 0  /* This is not needed for gcc's purposes.  */
-  /* If the block to clear is bigger than a cache plane,
-     we clear the entire cache, and OFFSET is already correct.  */
-  if (end < beg + INSN_CACHE_PLANE_SIZE)
-#endif
-    offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
-              & -INSN_CACHE_LINE_WIDTH)
-             & (INSN_CACHE_PLANE_SIZE - 1));
-
-#if INSN_CACHE_DEPTH > 1
-  end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
-  if (end_addr <= start_addr)
-    end_addr += INSN_CACHE_PLANE_SIZE;
-
-  for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
-    {
-      int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
-      int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
-
-      while (addr != stop)
-       {
-         /* Call the return instruction at ADDR.  */
-         ((function_ptr) addr) ();
-
-         addr += INSN_CACHE_LINE_WIDTH;
-       }
-    }
-#else /* just one plane */
-  do
-    {
-      /* Call the return instruction at START_ADDR.  */
-      ((function_ptr) start_addr) ();
-
-      start_addr += INSN_CACHE_LINE_WIDTH;
-    }
-  while ((start_addr % INSN_CACHE_SIZE) != offset);
-#endif /* just one plane */
-#endif /* Cache is large */
-#endif /* Cache exists */
 #endif /* CLEAR_INSN_CACHE */
 }
 
@@ -1559,51 +1496,6 @@ mprotect (char *addr, int len, int prot)
 #ifdef TRANSFER_FROM_TRAMPOLINE
 TRANSFER_FROM_TRAMPOLINE
 #endif
-
-#ifdef __sysV68__
-
-#include <sys/signal.h>
-#include <errno.h>
-
-/* Motorola forgot to put memctl.o in the libp version of libc881.a,
-   so define it here, because we need it in __clear_insn_cache below */
-/* On older versions of this OS, no memctl or MCT_TEXT are defined;
-   hence we enable this stuff only if MCT_TEXT is #define'd.  */
-
-#ifdef MCT_TEXT
-asm("\n\
-       global memctl\n\
-memctl:\n\
-       movq &75,%d0\n\
-       trap &0\n\
-       bcc.b noerror\n\
-       jmp cerror%\n\
-noerror:\n\
-       movq &0,%d0\n\
-       rts");
-#endif
-
-/* Clear instruction cache so we can call trampolines on stack.
-   This is called from FINALIZE_TRAMPOLINE in mot3300.h.  */
-
-void
-__clear_insn_cache (void)
-{
-#ifdef MCT_TEXT
-  int save_errno;
-
-  /* Preserve errno, because users would be surprised to have
-  errno changing without explicitly calling any system-call.  */
-  save_errno = errno;
-
-  /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache.
-     No need to use an address derived from _start or %sp, as 0 works also.  */
-  memctl(0, 4096, MCT_TEXT);
-  errno = save_errno;
-#endif
-}
-
-#endif /* __sysV68__ */
 #endif /* L_trampoline */
 \f
 #ifndef __CYGWIN__
@@ -1731,79 +1623,4 @@ func_ptr __DTOR_LIST__[2];
 #endif
 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
 #endif /* L_ctors */
-\f
-#ifdef L_exit
-
-#include "gbl-ctors.h"
-
-#ifdef NEED_ATEXIT
-
-#ifndef ON_EXIT
-
-# 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 = (func_ptr *) realloc (atexit_chain, atexit_chain_length
-                                            * sizeof (func_ptr));
-      else
-       atexit_chain = (func_ptr *) 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);
-}
-
-extern void _cleanup (void);
-extern void _exit (int) __attribute__ ((__noreturn__));
-
-void
-exit (int status)
-{
-  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;
-    }
-#ifdef EXIT_BODY
-  EXIT_BODY;
-#else
-  _cleanup ();
-#endif
-  _exit (status);
-}
-
-#else /* ON_EXIT */
-
-/* Simple; we just need a wrapper for ON_EXIT.  */
-int
-atexit (func_ptr func)
-{
-  return ON_EXIT (func);
-}
-
-#endif /* ON_EXIT */
-#endif /* NEED_ATEXIT */
 
-#endif /* L_exit */