/* More subroutines needed by GCC output code on some machines. */
/* Compile this one with gcc. */
-/* Copyright (C) 1989, 1992, 1993 Free Software Foundation, Inc.
+/* Copyright (C) 1989, 1992, 1993, 1994 Free Software Foundation, Inc.
This file is part of GNU CC.
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. */
#include "tconfig.h"
#include "machmode.h"
#ifndef L_trampoline
-#include "gstddef.h"
+#include <stddef.h>
#endif
/* Don't use `fancy_abort' here even if config.h says to use it. */
__umoddi3 (u, v)
UDItype u, v;
{
- DItype w;
+ UDItype w;
(void) __udivmoddi4 (u, v, &w);
#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)
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;
asm (" j $31");
asm (" .end __builtin_saveregs");
#else /* not __mips__, etc. */
+
+void *
__builtin_saveregs ()
{
abort ();
}
+
#endif /* not __mips__ */
#endif /* not __sparc__ */
#endif /* not __i860__ */
#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));
#endif /* not BLOCK_PROFILER_CODE */
#endif /* L_bb */
\f
-/* frills for C++ */
+/* Default free-store management functions for C++, per sections 12.5 and
+ 17.3.3 of the Working Paper. */
#ifdef L_op_new
-typedef void (*vfp)(void);
+/* 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. */
+typedef void (*vfp)(void);
extern vfp __new_handler;
-/* void * operator new (size_t sz) */
void *
__builtin_new (size_t sz)
{
if (sz == 0)
sz = 1;
p = (void *) malloc (sz);
- if (p == 0)
- (*__new_handler) ();
+ while (p == 0)
+ {
+ (*__new_handler) ();
+ p = (void *) malloc (sz);
+ }
+
return p;
}
#endif /* L_op_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. */
+
+extern void * __builtin_new (size_t);
+
+void *
+__builtin_vec_new (size_t sz)
+{
+ return __builtin_new (sz);
+}
+#endif /* L_op_vnew */
+
#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 []. */
#ifndef inhibit_libc
/* This gets us __GNU_LIBRARY__. */
#endif /* inhibit_libc */
typedef void (*vfp)(void);
+void __default_new_handler (void);
-extern void *__builtin_new (size_t);
-static void default_new_handler (void);
-
-vfp __new_handler = default_new_handler;
+vfp __new_handler = __default_new_handler;
vfp
-__set_new_handler (handler)
- vfp handler;
+set_new_handler (vfp handler)
{
vfp prev_handler;
prev_handler = __new_handler;
- if (handler == 0) handler = default_new_handler;
+ if (handler == 0) handler = __default_new_handler;
__new_handler = handler;
return prev_handler;
}
-vfp
-set_new_handler (handler)
- vfp handler;
-{
- return __set_new_handler (handler);
-}
-
#define MESSAGE "Virtual memory exceeded in `new'\n"
-static void
-default_new_handler ()
+void
+__default_new_handler ()
{
/* don't use fprintf (stderr, ...) because it may need to call malloc. */
/* This should really print the name of the program, but that is hard to
#endif
#ifdef L_op_delete
-/* void operator delete (void *ptr) */
+/* 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. */
+
void
__builtin_delete (void *ptr)
{
free (ptr);
}
#endif
+
+#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. */
+
+extern void __builtin_delete (void *);
+
+void
+__builtin_vec_delete (void *ptr)
+{
+ __builtin_delete (ptr);
+}
+#endif
+
+/* End of C++ free-store management functions */
\f
#ifdef L_shtab
unsigned int __shtab[] = {
/* Make stack executable so we can call trampolines on stack.
This is called from INITIALIZE_TRAMPOLINE in next.h. */
-
-#include <mach/mach.h>
+#ifdef NeXTStep21
+ #include <mach.h>
+#else
+ #include <mach/mach.h>
+#endif
void
__enable_execute_stack (addr)
#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
}