OSDN Git Service

Add declaration of ctime.
[pf3gnuchains/gcc-fork.git] / gcc / libgcc2.c
index c25d5fb..a39aa3b 100644 (file)
@@ -18,9 +18,10 @@ 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.  */
 
-/* As a special exception, if you link this library with files
-   compiled with GCC to produce an executable, this does not cause
-   the resulting executable to be covered by the GNU General Public License.
+/* 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.  */
 
@@ -48,28 +49,28 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
    because the sizes for those types can be configured to be anything.
    Instead we use the following special type names.  */
 
-typedef unsigned int UQItype   __attribute__ ((mode ("QI")));
-typedef         int SItype     __attribute__ ((mode ("SI")));
-typedef unsigned int USItype   __attribute__ ((mode ("SI")));
-typedef                 int DItype     __attribute__ ((mode ("DI")));
-typedef unsigned int UDItype   __attribute__ ((mode ("DI")));
-typedef        float SFtype    __attribute__ ((mode ("SF")));
-typedef                float DFtype    __attribute__ ((mode ("DF")));
+typedef unsigned int UQItype   __attribute__ ((mode (QI)));
+typedef         int SItype     __attribute__ ((mode (SI)));
+typedef unsigned int USItype   __attribute__ ((mode (SI)));
+typedef                 int DItype     __attribute__ ((mode (DI)));
+typedef unsigned int UDItype   __attribute__ ((mode (DI)));
+typedef        float SFtype    __attribute__ ((mode (SF)));
+typedef                float DFtype    __attribute__ ((mode (DF)));
 #if LONG_DOUBLE_TYPE_SIZE == 96
-typedef                float XFtype    __attribute__ ((mode ("XF")));
+typedef                float XFtype    __attribute__ ((mode (XF)));
 #endif
 #if LONG_DOUBLE_TYPE_SIZE == 128
-typedef                float TFtype    __attribute__ ((mode ("TF")));
+typedef                float TFtype    __attribute__ ((mode (TF)));
 #endif
 
 #if BITS_PER_WORD==16
-typedef int word_type __attribute__ ((mode ("HI")));
+typedef int word_type __attribute__ ((mode (HI)));
 #endif
 #if BITS_PER_WORD==32
-typedef int word_type __attribute__ ((mode ("SI")));
+typedef int word_type __attribute__ ((mode (SI)));
 #endif
 #if BITS_PER_WORD==64
-typedef int word_type __attribute__ ((mode ("DI")));
+typedef int word_type __attribute__ ((mode (DI)));
 #endif
 
 /* Make sure that we don't accidentally use any normal C language built-in
@@ -706,7 +707,7 @@ UDItype
 __umoddi3 (u, v)
      UDItype u, v;
 {
-  DItype w;
+  UDItype w;
 
   (void) __udivmoddi4 (u, v, &w);
 
@@ -1020,6 +1021,25 @@ __floatdidf (u)
 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
 #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 DF_SIZE 53
+#define SF_SIZE 24
+#else
+#if TARGET_FLOAT_FORMAT == IBM_FLOAT_FORMAT
+#define DF_SIZE 56
+#define SF_SIZE 24
+#else
+#if TARGET_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)
@@ -1034,6 +1054,22 @@ __floatdisf (u)
   if (u < 0)
     u = -u, negate = 1;
 
+  /* Protect against double-rounding error.
+     Represent any low-order bits, that might be truncated in DFmode,
+     by a bit that won't be lost.  The bit can go in anywhere below the
+     rounding position of the SFmode.  A fixed mask and bit position
+     handles all usual configurations.  It doesn't handle the case
+     of 128-bit DImode, however.  */
+  if (DF_SIZE < DI_SIZE
+      && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
+    {
+#define REP_BIT ((USItype) 1 << (DI_SIZE - DF_SIZE))
+      if (u >= ((UDItype) 1 << DF_SIZE))
+       {
+         if ((USItype) u & (REP_BIT - 1))
+           u |= REP_BIT;
+       }
+    }
   f = (USItype) (u >> WORD_SIZE);
   f *= HIGH_HALFWORD_COEFF;
   f *= HIGH_HALFWORD_COEFF;
@@ -1392,6 +1428,7 @@ BLOCK_PROFILER_CODE
 
 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
 #include <stdio.h>
+char *ctime ();
 
 #ifdef HAVE_ATEXIT
 extern void atexit (void (*) (void));
@@ -1589,7 +1626,7 @@ __builtin_new (size_t sz)
 }
 #endif /* L_op_new */
 
-#ifdef L_op_vec_new
+#ifdef L_op_vnew
 /* void * operator new [] (size_t), described in 17.3.3.6.  This function
    is used by C++ programs to allocate a block of memory for an array.  */
 
@@ -1600,7 +1637,7 @@ __builtin_vec_new (size_t sz)
 {
   return __builtin_new (sz);
 }
-#endif /* L_op_vec_new */
+#endif /* L_op_vnew */
 
 #ifdef L_new_handler
 /* set_new_handler (fvoid_t *) and the default new handler, described in
@@ -1663,7 +1700,7 @@ __builtin_delete (void *ptr)
 }
 #endif
 
-#ifdef L_op_vec_delete
+#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. */
@@ -1959,21 +1996,9 @@ __do_global_dtors ()
 #ifdef DO_GLOBAL_DTORS_BODY
   DO_GLOBAL_DTORS_BODY;
 #else
-  unsigned nptrs = (unsigned HOST_WIDE_INT) __DTOR_LIST__[0];
-  unsigned i;
-
-  /* Some systems place the number of pointers
-     in the first word of the table.
-     On other systems, that word is -1.
-     In all cases, the table is null-terminated.  */
-
-  /* If the length is not recorded, count up to the null.  */
-  if (nptrs == -1)
-    for (nptrs = 0; __DTOR_LIST__[nptrs + 1] != 0; nptrs++);
-
-  /* GNU LD format.  */
-  for (i = nptrs; i >= 1; i--)
-    __DTOR_LIST__[i] ();
+  func_ptr *p;
+  for (p = __DTOR_LIST__ + 1; *p; )
+    (*p++) ();
 #endif
 }