summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin/cc/libgcc
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1994-08-02 20:15:59 +0000
committerphk <phk@FreeBSD.org>1994-08-02 20:15:59 +0000
commit5ba9f35203b5fe0daba8f1ded6df2bcb38880681 (patch)
tree5a7e9c8d4cf5d1bd3b4c8577610d406f89f85545 /gnu/usr.bin/cc/libgcc
parentceb5ca06c6ed8827fe5069db7033fc696325b681 (diff)
downloadFreeBSD-src-5ba9f35203b5fe0daba8f1ded6df2bcb38880681.zip
FreeBSD-src-5ba9f35203b5fe0daba8f1ded6df2bcb38880681.tar.gz
Here comes the right import of gcc-2.6.0.
Diffstat (limited to 'gnu/usr.bin/cc/libgcc')
-rw-r--r--gnu/usr.bin/cc/libgcc/Makefile46
-rw-r--r--gnu/usr.bin/cc/libgcc/libgcc1.c608
-rw-r--r--gnu/usr.bin/cc/libgcc/libgcc2.c2151
3 files changed, 2805 insertions, 0 deletions
diff --git a/gnu/usr.bin/cc/libgcc/Makefile b/gnu/usr.bin/cc/libgcc/Makefile
new file mode 100644
index 0000000..4b2c5a4
--- /dev/null
+++ b/gnu/usr.bin/cc/libgcc/Makefile
@@ -0,0 +1,46 @@
+#
+# $FreeBSD$
+#
+
+LIB= gcc
+INSTALL_PIC_ARCHIVE= yes
+SHLIB_MAJOR= 26
+SHLIB_MINOR= 0
+
+LIB1OBJS= _mulsi3.o _udivsi3.o _divsi3.o _umodsi3.o _modsi3.o _lshrsi3.o _lshlsi3.o _ashrsi3.o _ashlsi3.o _divdf3.o _muldf3.o _negdf2.o _adddf3.o _subdf3.o _fixdfsi.o _fixsfsi.o _floatsidf.o _floatsisf.o _truncdfsf2.o _extendsfdf2.o _addsf3.o _negsf2.o _subsf3.o _mulsf3.o _divsf3.o _eqdf2.o _nedf2.o _gtdf2.o _gedf2.o _ltdf2.o _ledf2.o _eqsf2.o _nesf2.o _gtsf2.o _gesf2.o _ltsf2.o _lesf2.o
+LIB2OBJS= _muldi3.o _divdi3.o _moddi3.o _udivdi3.o _umoddi3.o _negdi2.o _lshrdi3.o _lshldi3.o _ashldi3.o _ashrdi3.o _ffsdi2.o _udiv_w_sdiv.o _udivmoddi4.o _cmpdi2.o _ucmpdi2.o _floatdidf.o _floatdisf.o _fixunsdfsi.o _fixunssfsi.o _fixunsdfdi.o _fixdfdi.o _fixunssfdi.o _fixsfdi.o _fixxfdi.o _fixunsxfdi.o _floatdixf.o _fixunsxfsi.o _fixtfdi.o _fixunstfdi.o _floatditf.o __gcc_bcmp.o _varargs.o _eprintf.o _op_new.o _op_vnew.o _new_handler.o _op_delete.o _op_vdel.o _bb.o _shtab.o _clear_cache.o _trampoline.o __main.o _exit.o _ctors.o
+
+OBJS= ${LIB1OBJS} ${LIB2OBJS}
+LIB1SOBJS=${LIB1OBJS:.o=.so}
+LIB2SOBJS=${LIB2OBJS:.o=.so}
+P1OBJS=${LIB1OBJS:.o=.po}
+P2OBJS=${LIB2OBJS:.o=.po}
+
+${LIB1OBJS}: libgcc1.c
+ ${CC} -c ${CFLAGS} -DL${.PREFIX} -o ${.TARGET} ${.CURDIR}/libgcc1.c
+ @${LD} -x -r ${.TARGET}
+ @mv a.out ${.TARGET}
+
+${LIB2OBJS}: libgcc2.c
+ ${CC} -c ${CFLAGS} -DL${.PREFIX} -o ${.TARGET} ${.CURDIR}/libgcc2.c
+ @${LD} -x -r ${.TARGET}
+ @mv a.out ${.TARGET}
+
+.if !defined(NOPIC)
+${LIB1SOBJS}: libgcc1.c
+ ${CC} -c -fpic ${CFLAGS} -DL${.PREFIX} -o ${.TARGET} ${.CURDIR}/libgcc1.c
+
+${LIB2SOBJS}: libgcc2.c
+ ${CC} -c -fpic ${CFLAGS} -DL${.PREFIX} -o ${.TARGET} ${.CURDIR}/libgcc2.c
+.endif
+
+.if !defined(NOPROFILE)
+${P1OBJS}: libgcc1.c
+ ${CC} -c -p ${CFLAGS} -DL${.PREFIX} -o ${.TARGET} ${.CURDIR}/libgcc1.c
+
+${P2OBJS}: libgcc2.c
+ ${CC} -c -p ${CFLAGS} -DL${.PREFIX} -o ${.TARGET} ${.CURDIR}/libgcc2.c
+.endif
+
+.include <bsd.lib.mk>
+
diff --git a/gnu/usr.bin/cc/libgcc/libgcc1.c b/gnu/usr.bin/cc/libgcc/libgcc1.c
new file mode 100644
index 0000000..7c0e0c1
--- /dev/null
+++ b/gnu/usr.bin/cc/libgcc/libgcc1.c
@@ -0,0 +1,608 @@
+/* Subroutines needed by GCC output code on some machines. */
+/* Compile this file with the Unix C compiler! */
+/* Copyright (C) 1987, 1988, 1992, 1994 Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file with other programs, and to distribute
+those programs without any restriction coming from the use of this
+file. (The General Public License restrictions do apply in other
+respects; for example, they cover modification of the file, and
+distribution when not linked into another program.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; 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 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 "config.h"
+
+/* Don't use `fancy_abort' here even if config.h says to use it. */
+#ifdef abort
+#undef abort
+#endif
+
+/* On some machines, cc is really GCC. For these machines, we can't
+ expect these functions to be properly compiled unless GCC open codes
+ the operation (which is precisely when the function won't be used).
+ So allow tm.h to specify ways of accomplishing the operations
+ by defining the macros perform_*.
+
+ On a machine where cc is some other compiler, there is usually no
+ reason to define perform_*. The other compiler normally has other ways
+ of implementing all of these operations.
+
+ In some cases a certain machine may come with GCC installed as cc
+ or may have some other compiler. Then it may make sense for tm.h
+ to define perform_* only if __GNUC__ is defined. */
+
+#ifndef perform_mulsi3
+#define perform_mulsi3(a, b) return a * b
+#endif
+
+#ifndef perform_divsi3
+#define perform_divsi3(a, b) return a / b
+#endif
+
+#ifndef perform_udivsi3
+#define perform_udivsi3(a, b) return a / b
+#endif
+
+#ifndef perform_modsi3
+#define perform_modsi3(a, b) return a % b
+#endif
+
+#ifndef perform_umodsi3
+#define perform_umodsi3(a, b) return a % b
+#endif
+
+#ifndef perform_lshrsi3
+#define perform_lshrsi3(a, b) return a >> b
+#endif
+
+#ifndef perform_lshlsi3
+#define perform_lshlsi3(a, b) return a << b
+#endif
+
+#ifndef perform_ashrsi3
+#define perform_ashrsi3(a, b) return a >> b
+#endif
+
+#ifndef perform_ashlsi3
+#define perform_ashlsi3(a, b) return a << b
+#endif
+
+#ifndef perform_adddf3
+#define perform_adddf3(a, b) return a + b
+#endif
+
+#ifndef perform_subdf3
+#define perform_subdf3(a, b) return a - b
+#endif
+
+#ifndef perform_muldf3
+#define perform_muldf3(a, b) return a * b
+#endif
+
+#ifndef perform_divdf3
+#define perform_divdf3(a, b) return a / b
+#endif
+
+#ifndef perform_addsf3
+#define perform_addsf3(a, b) return INTIFY (a + b)
+#endif
+
+#ifndef perform_subsf3
+#define perform_subsf3(a, b) return INTIFY (a - b)
+#endif
+
+#ifndef perform_mulsf3
+#define perform_mulsf3(a, b) return INTIFY (a * b)
+#endif
+
+#ifndef perform_divsf3
+#define perform_divsf3(a, b) return INTIFY (a / b)
+#endif
+
+#ifndef perform_negdf2
+#define perform_negdf2(a) return -a
+#endif
+
+#ifndef perform_negsf2
+#define perform_negsf2(a) return INTIFY (-a)
+#endif
+
+#ifndef perform_fixdfsi
+#define perform_fixdfsi(a) return (nongcc_SI_type) a;
+#endif
+
+#ifndef perform_fixsfsi
+#define perform_fixsfsi(a) return (nongcc_SI_type) a
+#endif
+
+#ifndef perform_floatsidf
+#define perform_floatsidf(a) return (double) a
+#endif
+
+#ifndef perform_floatsisf
+#define perform_floatsisf(a) return INTIFY ((float) a)
+#endif
+
+#ifndef perform_extendsfdf2
+#define perform_extendsfdf2(a) return a
+#endif
+
+#ifndef perform_truncdfsf2
+#define perform_truncdfsf2(a) return INTIFY (a)
+#endif
+
+/* Note that eqdf2 returns a value for "true" that is == 0,
+ nedf2 returns a value for "true" that is != 0,
+ gtdf2 returns a value for "true" that is > 0,
+ and so on. */
+
+#ifndef perform_eqdf2
+#define perform_eqdf2(a, b) return !(a == b)
+#endif
+
+#ifndef perform_nedf2
+#define perform_nedf2(a, b) return a != b
+#endif
+
+#ifndef perform_gtdf2
+#define perform_gtdf2(a, b) return a > b
+#endif
+
+#ifndef perform_gedf2
+#define perform_gedf2(a, b) return (a >= b) - 1
+#endif
+
+#ifndef perform_ltdf2
+#define perform_ltdf2(a, b) return -(a < b)
+#endif
+
+#ifndef perform_ledf2
+#define perform_ledf2(a, b) return 1 - (a <= b)
+#endif
+
+#ifndef perform_eqsf2
+#define perform_eqsf2(a, b) return !(a == b)
+#endif
+
+#ifndef perform_nesf2
+#define perform_nesf2(a, b) return a != b
+#endif
+
+#ifndef perform_gtsf2
+#define perform_gtsf2(a, b) return a > b
+#endif
+
+#ifndef perform_gesf2
+#define perform_gesf2(a, b) return (a >= b) - 1
+#endif
+
+#ifndef perform_ltsf2
+#define perform_ltsf2(a, b) return -(a < b)
+#endif
+
+#ifndef perform_lesf2
+#define perform_lesf2(a, b) return 1 - (a <= b);
+#endif
+
+/* Define the C data type to use for an SImode value. */
+
+#ifndef nongcc_SI_type
+#define nongcc_SI_type long int
+#endif
+
+/* Define the C data type to use for a value of word size */
+#ifndef nongcc_word_type
+#define nongcc_word_type nongcc_SI_type
+#endif
+
+/* Define the type to be used for returning an SF mode value
+ and the method for turning a float into that type.
+ These definitions work for machines where an SF value is
+ returned in the same register as an int. */
+
+#ifndef FLOAT_VALUE_TYPE
+#define FLOAT_VALUE_TYPE int
+#endif
+
+#ifndef INTIFY
+#define INTIFY(FLOATVAL) (intify.f = (FLOATVAL), intify.i)
+#endif
+
+#ifndef FLOATIFY
+#define FLOATIFY(INTVAL) ((INTVAL).f)
+#endif
+
+#ifndef FLOAT_ARG_TYPE
+#define FLOAT_ARG_TYPE union flt_or_int
+#endif
+
+union flt_or_value { FLOAT_VALUE_TYPE i; float f; };
+
+union flt_or_int { int i; float f; };
+
+
+#ifdef L_mulsi3
+nongcc_SI_type
+__mulsi3 (a, b)
+ nongcc_SI_type a, b;
+{
+ perform_mulsi3 (a, b);
+}
+#endif
+
+#ifdef L_udivsi3
+nongcc_SI_type
+__udivsi3 (a, b)
+ unsigned nongcc_SI_type a, b;
+{
+ perform_udivsi3 (a, b);
+}
+#endif
+
+#ifdef L_divsi3
+nongcc_SI_type
+__divsi3 (a, b)
+ nongcc_SI_type a, b;
+{
+ perform_divsi3 (a, b);
+}
+#endif
+
+#ifdef L_umodsi3
+nongcc_SI_type
+__umodsi3 (a, b)
+ unsigned nongcc_SI_type a, b;
+{
+ perform_umodsi3 (a, b);
+}
+#endif
+
+#ifdef L_modsi3
+nongcc_SI_type
+__modsi3 (a, b)
+ nongcc_SI_type a, b;
+{
+ perform_modsi3 (a, b);
+}
+#endif
+
+#ifdef L_lshrsi3
+nongcc_SI_type
+__lshrsi3 (a, b)
+ unsigned nongcc_SI_type a, b;
+{
+ perform_lshrsi3 (a, b);
+}
+#endif
+
+#ifdef L_lshlsi3
+nongcc_SI_type
+__lshlsi3 (a, b)
+ unsigned nongcc_SI_type a, b;
+{
+ perform_lshlsi3 (a, b);
+}
+#endif
+
+#ifdef L_ashrsi3
+nongcc_SI_type
+__ashrsi3 (a, b)
+ nongcc_SI_type a, b;
+{
+ perform_ashrsi3 (a, b);
+}
+#endif
+
+#ifdef L_ashlsi3
+nongcc_SI_type
+__ashlsi3 (a, b)
+ nongcc_SI_type a, b;
+{
+ perform_ashlsi3 (a, b);
+}
+#endif
+
+#ifdef L_divdf3
+double
+__divdf3 (a, b)
+ double a, b;
+{
+ perform_divdf3 (a, b);
+}
+#endif
+
+#ifdef L_muldf3
+double
+__muldf3 (a, b)
+ double a, b;
+{
+ perform_muldf3 (a, b);
+}
+#endif
+
+#ifdef L_negdf2
+double
+__negdf2 (a)
+ double a;
+{
+ perform_negdf2 (a);
+}
+#endif
+
+#ifdef L_adddf3
+double
+__adddf3 (a, b)
+ double a, b;
+{
+ perform_adddf3 (a, b);
+}
+#endif
+
+#ifdef L_subdf3
+double
+__subdf3 (a, b)
+ double a, b;
+{
+ perform_subdf3 (a, b);
+}
+#endif
+
+/* Note that eqdf2 returns a value for "true" that is == 0,
+ nedf2 returns a value for "true" that is != 0,
+ gtdf2 returns a value for "true" that is > 0,
+ and so on. */
+
+#ifdef L_eqdf2
+nongcc_word_type
+__eqdf2 (a, b)
+ double a, b;
+{
+ /* Value == 0 iff a == b. */
+ perform_eqdf2 (a, b);
+}
+#endif
+
+#ifdef L_nedf2
+nongcc_word_type
+__nedf2 (a, b)
+ double a, b;
+{
+ /* Value != 0 iff a != b. */
+ perform_nedf2 (a, b);
+}
+#endif
+
+#ifdef L_gtdf2
+nongcc_word_type
+__gtdf2 (a, b)
+ double a, b;
+{
+ /* Value > 0 iff a > b. */
+ perform_gtdf2 (a, b);
+}
+#endif
+
+#ifdef L_gedf2
+nongcc_word_type
+__gedf2 (a, b)
+ double a, b;
+{
+ /* Value >= 0 iff a >= b. */
+ perform_gedf2 (a, b);
+}
+#endif
+
+#ifdef L_ltdf2
+nongcc_word_type
+__ltdf2 (a, b)
+ double a, b;
+{
+ /* Value < 0 iff a < b. */
+ perform_ltdf2 (a, b);
+}
+#endif
+
+#ifdef L_ledf2
+nongcc_word_type
+__ledf2 (a, b)
+ double a, b;
+{
+ /* Value <= 0 iff a <= b. */
+ perform_ledf2 (a, b);
+}
+#endif
+
+#ifdef L_fixdfsi
+nongcc_SI_type
+__fixdfsi (a)
+ double a;
+{
+ perform_fixdfsi (a);
+}
+#endif
+
+#ifdef L_fixsfsi
+nongcc_SI_type
+__fixsfsi (a)
+ FLOAT_ARG_TYPE a;
+{
+ union flt_or_value intify;
+ perform_fixsfsi (FLOATIFY (a));
+}
+#endif
+
+#ifdef L_floatsidf
+double
+__floatsidf (a)
+ nongcc_SI_type a;
+{
+ perform_floatsidf (a);
+}
+#endif
+
+#ifdef L_floatsisf
+FLOAT_VALUE_TYPE
+__floatsisf (a)
+ nongcc_SI_type a;
+{
+ union flt_or_value intify;
+ perform_floatsisf (a);
+}
+#endif
+
+#ifdef L_addsf3
+FLOAT_VALUE_TYPE
+__addsf3 (a, b)
+ FLOAT_ARG_TYPE a, b;
+{
+ union flt_or_value intify;
+ perform_addsf3 (FLOATIFY (a), FLOATIFY (b));
+}
+#endif
+
+#ifdef L_negsf2
+FLOAT_VALUE_TYPE
+__negsf2 (a)
+ FLOAT_ARG_TYPE a;
+{
+ union flt_or_value intify;
+ perform_negsf2 (FLOATIFY (a));
+}
+#endif
+
+#ifdef L_subsf3
+FLOAT_VALUE_TYPE
+__subsf3 (a, b)
+ FLOAT_ARG_TYPE a, b;
+{
+ union flt_or_value intify;
+ perform_subsf3 (FLOATIFY (a), FLOATIFY (b));
+}
+#endif
+
+#ifdef L_eqsf2
+nongcc_word_type
+__eqsf2 (a, b)
+ FLOAT_ARG_TYPE a, b;
+{
+ union flt_or_int intify;
+ /* Value == 0 iff a == b. */
+ perform_eqsf2 (FLOATIFY (a), FLOATIFY (b));
+}
+#endif
+
+#ifdef L_nesf2
+nongcc_word_type
+__nesf2 (a, b)
+ FLOAT_ARG_TYPE a, b;
+{
+ union flt_or_int intify;
+ /* Value != 0 iff a != b. */
+ perform_nesf2 (FLOATIFY (a), FLOATIFY (b));
+}
+#endif
+
+#ifdef L_gtsf2
+nongcc_word_type
+__gtsf2 (a, b)
+ FLOAT_ARG_TYPE a, b;
+{
+ union flt_or_int intify;
+ /* Value > 0 iff a > b. */
+ perform_gtsf2 (FLOATIFY (a), FLOATIFY (b));
+}
+#endif
+
+#ifdef L_gesf2
+nongcc_word_type
+__gesf2 (a, b)
+ FLOAT_ARG_TYPE a, b;
+{
+ union flt_or_int intify;
+ /* Value >= 0 iff a >= b. */
+ perform_gesf2 (FLOATIFY (a), FLOATIFY (b));
+}
+#endif
+
+#ifdef L_ltsf2
+nongcc_word_type
+__ltsf2 (a, b)
+ FLOAT_ARG_TYPE a, b;
+{
+ union flt_or_int intify;
+ /* Value < 0 iff a < b. */
+ perform_ltsf2 (FLOATIFY (a), FLOATIFY (b));
+}
+#endif
+
+#ifdef L_lesf2
+nongcc_word_type
+__lesf2 (a, b)
+ FLOAT_ARG_TYPE a, b;
+{
+ union flt_or_int intify;
+ /* Value <= 0 iff a <= b. */
+ perform_lesf2 (FLOATIFY (a), FLOATIFY (b));
+}
+#endif
+
+#ifdef L_mulsf3
+FLOAT_VALUE_TYPE
+__mulsf3 (a, b)
+ FLOAT_ARG_TYPE a, b;
+{
+ union flt_or_value intify;
+ perform_mulsf3 (FLOATIFY (a), FLOATIFY (b));
+}
+#endif
+
+#ifdef L_divsf3
+FLOAT_VALUE_TYPE
+__divsf3 (a, b)
+ FLOAT_ARG_TYPE a, b;
+{
+ union flt_or_value intify;
+ perform_divsf3 (FLOATIFY (a), FLOATIFY (b));
+}
+#endif
+
+#ifdef L_truncdfsf2
+FLOAT_VALUE_TYPE
+__truncdfsf2 (a)
+ double a;
+{
+ union flt_or_value intify;
+ perform_truncdfsf2 (a);
+}
+#endif
+
+#ifdef L_extendsfdf2
+double
+__extendsfdf2 (a)
+ FLOAT_ARG_TYPE a;
+{
+ union flt_or_value intify;
+ perform_extendsfdf2 (FLOATIFY (a));
+}
+#endif
diff --git a/gnu/usr.bin/cc/libgcc/libgcc2.c b/gnu/usr.bin/cc/libgcc/libgcc2.c
new file mode 100644
index 0000000..fc2e1ac
--- /dev/null
+++ b/gnu/usr.bin/cc/libgcc/libgcc2.c
@@ -0,0 +1,2151 @@
+/* More subroutines needed by GCC output code on some machines. */
+/* Compile this one with gcc. */
+/* Copyright (C) 1989, 1992, 1993, 1994 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+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. */
+
+/* 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. */
+
+/* It is incorrect to include config.h here, because this file is being
+ compiled for the target, and hence definitions concerning only the host
+ do not apply. */
+
+#include "tconfig.h"
+#include "machmode.h"
+#ifndef L_trampoline
+#include <stddef.h>
+#endif
+
+/* Don't use `fancy_abort' here even if config.h says to use it. */
+#ifdef abort
+#undef abort
+#endif
+
+/* In the first part of this file, we are interfacing to calls generated
+ by the compiler itself. These calls pass values into these routines
+ which have very specific modes (rather than very specific types), and
+ these compiler-generated calls also expect any return values to have
+ very specific modes (rather than very specific types). Thus, we need
+ to avoid using regular C language type names in this part of the file
+ 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)));
+#if LONG_DOUBLE_TYPE_SIZE == 96
+typedef float XFtype __attribute__ ((mode (XF)));
+#endif
+#if LONG_DOUBLE_TYPE_SIZE == 128
+typedef float TFtype __attribute__ ((mode (TF)));
+#endif
+
+#if BITS_PER_WORD==16
+typedef int word_type __attribute__ ((mode (HI)));
+#endif
+#if BITS_PER_WORD==32
+typedef int word_type __attribute__ ((mode (SI)));
+#endif
+#if BITS_PER_WORD==64
+typedef int word_type __attribute__ ((mode (DI)));
+#endif
+
+/* Make sure that we don't accidentally use any normal C language built-in
+ type names in the first part of this file. Instead we want to use *only*
+ the type names defined above. The following macro definitions insure
+ that if we *do* accidentally use some normal C language built-in type name,
+ we will get a syntax error. */
+
+#define char bogus_type
+#define short bogus_type
+#define int bogus_type
+#define long bogus_type
+#define unsigned bogus_type
+#define float bogus_type
+#define double bogus_type
+
+#define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
+
+/* DIstructs are pairs of SItype values in the order determined by
+ WORDS_BIG_ENDIAN. */
+
+#if WORDS_BIG_ENDIAN
+ struct DIstruct {SItype high, low;};
+#else
+ struct DIstruct {SItype low, high;};
+#endif
+
+/* We need this union to unpack/pack DImode values, since we don't have
+ any arithmetic yet. Incoming DImode parameters are stored into the
+ `ll' field, and the unpacked result is read from the struct `s'. */
+
+typedef union
+{
+ struct DIstruct s;
+ DItype ll;
+} DIunion;
+
+#if defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_w_sdiv)
+
+#include "longlong.h"
+
+#endif /* udiv or mul */
+
+extern DItype __fixunssfdi (SFtype a);
+extern DItype __fixunsdfdi (DFtype a);
+#if LONG_DOUBLE_TYPE_SIZE == 96
+extern DItype __fixunsxfdi (XFtype a);
+#endif
+#if LONG_DOUBLE_TYPE_SIZE == 128
+extern DItype __fixunstfdi (TFtype a);
+#endif
+
+#if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
+#if defined (L_divdi3) || defined (L_moddi3)
+static inline
+#endif
+DItype
+__negdi2 (u)
+ DItype u;
+{
+ DIunion w;
+ DIunion uu;
+
+ uu.ll = u;
+
+ w.s.low = -uu.s.low;
+ w.s.high = -uu.s.high - ((USItype) w.s.low > 0);
+
+ return w.ll;
+}
+#endif
+
+#ifdef L_lshldi3
+DItype
+__lshldi3 (u, b)
+ DItype u;
+ SItype b;
+{
+ DIunion w;
+ SItype bm;
+ DIunion uu;
+
+ if (b == 0)
+ return u;
+
+ uu.ll = u;
+
+ bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
+ if (bm <= 0)
+ {
+ w.s.low = 0;
+ w.s.high = (USItype)uu.s.low << -bm;
+ }
+ else
+ {
+ USItype carries = (USItype)uu.s.low >> bm;
+ w.s.low = (USItype)uu.s.low << b;
+ w.s.high = ((USItype)uu.s.high << b) | carries;
+ }
+
+ return w.ll;
+}
+#endif
+
+#ifdef L_lshrdi3
+DItype
+__lshrdi3 (u, b)
+ DItype u;
+ SItype b;
+{
+ DIunion w;
+ SItype bm;
+ DIunion uu;
+
+ if (b == 0)
+ return u;
+
+ uu.ll = u;
+
+ bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
+ if (bm <= 0)
+ {
+ w.s.high = 0;
+ w.s.low = (USItype)uu.s.high >> -bm;
+ }
+ else
+ {
+ USItype carries = (USItype)uu.s.high << bm;
+ w.s.high = (USItype)uu.s.high >> b;
+ w.s.low = ((USItype)uu.s.low >> b) | carries;
+ }
+
+ return w.ll;
+}
+#endif
+
+#ifdef L_ashldi3
+DItype
+__ashldi3 (u, b)
+ DItype u;
+ SItype b;
+{
+ DIunion w;
+ SItype bm;
+ DIunion uu;
+
+ if (b == 0)
+ return u;
+
+ uu.ll = u;
+
+ bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
+ if (bm <= 0)
+ {
+ w.s.low = 0;
+ w.s.high = (USItype)uu.s.low << -bm;
+ }
+ else
+ {
+ USItype carries = (USItype)uu.s.low >> bm;
+ w.s.low = (USItype)uu.s.low << b;
+ w.s.high = ((USItype)uu.s.high << b) | carries;
+ }
+
+ return w.ll;
+}
+#endif
+
+#ifdef L_ashrdi3
+DItype
+__ashrdi3 (u, b)
+ DItype u;
+ SItype b;
+{
+ DIunion w;
+ SItype bm;
+ DIunion uu;
+
+ if (b == 0)
+ return u;
+
+ uu.ll = u;
+
+ bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
+ if (bm <= 0)
+ {
+ /* w.s.high = 1..1 or 0..0 */
+ w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
+ w.s.low = uu.s.high >> -bm;
+ }
+ else
+ {
+ USItype carries = (USItype)uu.s.high << bm;
+ w.s.high = uu.s.high >> b;
+ w.s.low = ((USItype)uu.s.low >> b) | carries;
+ }
+
+ return w.ll;
+}
+#endif
+
+#ifdef L_ffsdi2
+DItype
+__ffsdi2 (u)
+ DItype u;
+{
+ DIunion uu, w;
+ uu.ll = u;
+ w.s.high = 0;
+ w.s.low = ffs (uu.s.low);
+ if (w.s.low != 0)
+ return w.ll;
+ w.s.low = ffs (uu.s.high);
+ if (w.s.low != 0)
+ {
+ w.s.low += BITS_PER_UNIT * sizeof (SItype);
+ return w.ll;
+ }
+ return w.ll;
+}
+#endif
+
+#ifdef L_muldi3
+DItype
+__muldi3 (u, v)
+ DItype u, v;
+{
+ DIunion w;
+ DIunion uu, vv;
+
+ uu.ll = u,
+ vv.ll = v;
+
+ w.ll = __umulsidi3 (uu.s.low, vv.s.low);
+ w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
+ + (USItype) uu.s.high * (USItype) vv.s.low);
+
+ return w.ll;
+}
+#endif
+
+#ifdef L_udiv_w_sdiv
+USItype
+__udiv_w_sdiv (rp, a1, a0, d)
+ USItype *rp, a1, a0, d;
+{
+ USItype q, r;
+ USItype c0, c1, b1;
+
+ if ((SItype) d >= 0)
+ {
+ if (a1 < d - a1 - (a0 >> (SI_TYPE_SIZE - 1)))
+ {
+ /* dividend, divisor, and quotient are nonnegative */
+ sdiv_qrnnd (q, r, a1, a0, d);
+ }
+ else
+ {
+ /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
+ sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (SI_TYPE_SIZE - 1));
+ /* Divide (c1*2^32 + c0) by d */
+ sdiv_qrnnd (q, r, c1, c0, d);
+ /* Add 2^31 to quotient */
+ q += (USItype) 1 << (SI_TYPE_SIZE - 1);
+ }
+ }
+ else
+ {
+ b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
+ c1 = a1 >> 1; /* A/2 */
+ c0 = (a1 << (SI_TYPE_SIZE - 1)) + (a0 >> 1);
+
+ if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
+ {
+ sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
+
+ r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
+ if ((d & 1) != 0)
+ {
+ if (r >= q)
+ r = r - q;
+ else if (q - r <= d)
+ {
+ r = r - q + d;
+ q--;
+ }
+ else
+ {
+ r = r - q + 2*d;
+ q -= 2;
+ }
+ }
+ }
+ else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
+ {
+ c1 = (b1 - 1) - c1;
+ c0 = ~c0; /* logical NOT */
+
+ sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
+
+ q = ~q; /* (A/2)/b1 */
+ r = (b1 - 1) - r;
+
+ r = 2*r + (a0 & 1); /* A/(2*b1) */
+
+ if ((d & 1) != 0)
+ {
+ if (r >= q)
+ r = r - q;
+ else if (q - r <= d)
+ {
+ r = r - q + d;
+ q--;
+ }
+ else
+ {
+ r = r - q + 2*d;
+ q -= 2;
+ }
+ }
+ }
+ else /* Implies c1 = b1 */
+ { /* Hence a1 = d - 1 = 2*b1 - 1 */
+ if (a0 >= -d)
+ {
+ q = -1;
+ r = a0 + d;
+ }
+ else
+ {
+ q = -2;
+ r = a0 + 2*d;
+ }
+ }
+ }
+
+ *rp = r;
+ return q;
+}
+#endif
+
+#ifdef L_udivmoddi4
+static const UQItype __clz_tab[] =
+{
+ 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 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,
+ 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,
+ 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,
+ 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,
+};
+
+UDItype
+__udivmoddi4 (n, d, rp)
+ UDItype n, d;
+ UDItype *rp;
+{
+ DIunion ww;
+ DIunion nn, dd;
+ DIunion rr;
+ USItype d0, d1, n0, n1, n2;
+ USItype q0, q1;
+ USItype b, bm;
+
+ nn.ll = n;
+ dd.ll = d;
+
+ d0 = dd.s.low;
+ d1 = dd.s.high;
+ n0 = nn.s.low;
+ n1 = nn.s.high;
+
+#if !UDIV_NEEDS_NORMALIZATION
+ if (d1 == 0)
+ {
+ if (d0 > n1)
+ {
+ /* 0q = nn / 0D */
+
+ udiv_qrnnd (q0, n0, n1, n0, d0);
+ q1 = 0;
+
+ /* Remainder in n0. */
+ }
+ else
+ {
+ /* qq = NN / 0d */
+
+ if (d0 == 0)
+ d0 = 1 / d0; /* Divide intentionally by zero. */
+
+ udiv_qrnnd (q1, n1, 0, n1, d0);
+ udiv_qrnnd (q0, n0, n1, n0, d0);
+
+ /* Remainder in n0. */
+ }
+
+ if (rp != 0)
+ {
+ rr.s.low = n0;
+ rr.s.high = 0;
+ *rp = rr.ll;
+ }
+ }
+
+#else /* UDIV_NEEDS_NORMALIZATION */
+
+ if (d1 == 0)
+ {
+ if (d0 > n1)
+ {
+ /* 0q = nn / 0D */
+
+ count_leading_zeros (bm, d0);
+
+ if (bm != 0)
+ {
+ /* Normalize, i.e. make the most significant bit of the
+ denominator set. */
+
+ d0 = d0 << bm;
+ n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
+ n0 = n0 << bm;
+ }
+
+ udiv_qrnnd (q0, n0, n1, n0, d0);
+ q1 = 0;
+
+ /* Remainder in n0 >> bm. */
+ }
+ else
+ {
+ /* qq = NN / 0d */
+
+ if (d0 == 0)
+ d0 = 1 / d0; /* Divide intentionally by zero. */
+
+ count_leading_zeros (bm, d0);
+
+ if (bm == 0)
+ {
+ /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
+ conclude (the most significant bit of n1 is set) /\ (the
+ leading quotient digit q1 = 1).
+
+ This special case is necessary, not an optimization.
+ (Shifts counts of SI_TYPE_SIZE are undefined.) */
+
+ n1 -= d0;
+ q1 = 1;
+ }
+ else
+ {
+ /* Normalize. */
+
+ b = SI_TYPE_SIZE - bm;
+
+ d0 = d0 << bm;
+ n2 = n1 >> b;
+ n1 = (n1 << bm) | (n0 >> b);
+ n0 = n0 << bm;
+
+ udiv_qrnnd (q1, n1, n2, n1, d0);
+ }
+
+ /* n1 != d0... */
+
+ udiv_qrnnd (q0, n0, n1, n0, d0);
+
+ /* Remainder in n0 >> bm. */
+ }
+
+ if (rp != 0)
+ {
+ rr.s.low = n0 >> bm;
+ rr.s.high = 0;
+ *rp = rr.ll;
+ }
+ }
+#endif /* UDIV_NEEDS_NORMALIZATION */
+
+ else
+ {
+ if (d1 > n1)
+ {
+ /* 00 = nn / DD */
+
+ q0 = 0;
+ q1 = 0;
+
+ /* Remainder in n1n0. */
+ if (rp != 0)
+ {
+ rr.s.low = n0;
+ rr.s.high = n1;
+ *rp = rr.ll;
+ }
+ }
+ else
+ {
+ /* 0q = NN / dd */
+
+ count_leading_zeros (bm, d1);
+ if (bm == 0)
+ {
+ /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
+ conclude (the most significant bit of n1 is set) /\ (the
+ quotient digit q0 = 0 or 1).
+
+ This special case is necessary, not an optimization. */
+
+ /* The condition on the next line takes advantage of that
+ n1 >= d1 (true due to program flow). */
+ if (n1 > d1 || n0 >= d0)
+ {
+ q0 = 1;
+ sub_ddmmss (n1, n0, n1, n0, d1, d0);
+ }
+ else
+ q0 = 0;
+
+ q1 = 0;
+
+ if (rp != 0)
+ {
+ rr.s.low = n0;
+ rr.s.high = n1;
+ *rp = rr.ll;
+ }
+ }
+ else
+ {
+ USItype m1, m0;
+ /* Normalize. */
+
+ b = SI_TYPE_SIZE - bm;
+
+ d1 = (d1 << bm) | (d0 >> b);
+ d0 = d0 << bm;
+ n2 = n1 >> b;
+ n1 = (n1 << bm) | (n0 >> b);
+ n0 = n0 << bm;
+
+ udiv_qrnnd (q0, n1, n2, n1, d1);
+ umul_ppmm (m1, m0, q0, d0);
+
+ if (m1 > n1 || (m1 == n1 && m0 > n0))
+ {
+ q0--;
+ sub_ddmmss (m1, m0, m1, m0, d1, d0);
+ }
+
+ q1 = 0;
+
+ /* Remainder in (n1n0 - m1m0) >> bm. */
+ if (rp != 0)
+ {
+ sub_ddmmss (n1, n0, n1, n0, m1, m0);
+ rr.s.low = (n1 << b) | (n0 >> bm);
+ rr.s.high = n1 >> bm;
+ *rp = rr.ll;
+ }
+ }
+ }
+ }
+
+ ww.s.low = q0;
+ ww.s.high = q1;
+ return ww.ll;
+}
+#endif
+
+#ifdef L_divdi3
+UDItype __udivmoddi4 ();
+
+DItype
+__divdi3 (u, v)
+ DItype u, v;
+{
+ SItype c = 0;
+ DIunion uu, vv;
+ DItype w;
+
+ uu.ll = u;
+ vv.ll = v;
+
+ if (uu.s.high < 0)
+ c = ~c,
+ uu.ll = __negdi2 (uu.ll);
+ if (vv.s.high < 0)
+ c = ~c,
+ vv.ll = __negdi2 (vv.ll);
+
+ w = __udivmoddi4 (uu.ll, vv.ll, (UDItype *) 0);
+ if (c)
+ w = __negdi2 (w);
+
+ return w;
+}
+#endif
+
+#ifdef L_moddi3
+UDItype __udivmoddi4 ();
+DItype
+__moddi3 (u, v)
+ DItype u, v;
+{
+ SItype c = 0;
+ DIunion uu, vv;
+ DItype w;
+
+ uu.ll = u;
+ vv.ll = v;
+
+ if (uu.s.high < 0)
+ c = ~c,
+ uu.ll = __negdi2 (uu.ll);
+ if (vv.s.high < 0)
+ vv.ll = __negdi2 (vv.ll);
+
+ (void) __udivmoddi4 (uu.ll, vv.ll, &w);
+ if (c)
+ w = __negdi2 (w);
+
+ return w;
+}
+#endif
+
+#ifdef L_umoddi3
+UDItype __udivmoddi4 ();
+UDItype
+__umoddi3 (u, v)
+ UDItype u, v;
+{
+ UDItype w;
+
+ (void) __udivmoddi4 (u, v, &w);
+
+ return w;
+}
+#endif
+
+#ifdef L_udivdi3
+UDItype __udivmoddi4 ();
+UDItype
+__udivdi3 (n, d)
+ UDItype n, d;
+{
+ return __udivmoddi4 (n, d, (UDItype *) 0);
+}
+#endif
+
+#ifdef L_cmpdi2
+word_type
+__cmpdi2 (a, b)
+ DItype a, b;
+{
+ DIunion au, bu;
+
+ au.ll = a, bu.ll = b;
+
+ if (au.s.high < bu.s.high)
+ return 0;
+ else if (au.s.high > bu.s.high)
+ return 2;
+ if ((USItype) au.s.low < (USItype) bu.s.low)
+ return 0;
+ else if ((USItype) au.s.low > (USItype) bu.s.low)
+ return 2;
+ return 1;
+}
+#endif
+
+#ifdef L_ucmpdi2
+word_type
+__ucmpdi2 (a, b)
+ DItype a, b;
+{
+ DIunion au, bu;
+
+ au.ll = a, bu.ll = b;
+
+ if ((USItype) au.s.high < (USItype) bu.s.high)
+ return 0;
+ else if ((USItype) au.s.high > (USItype) bu.s.high)
+ return 2;
+ if ((USItype) au.s.low < (USItype) bu.s.low)
+ return 0;
+ else if ((USItype) au.s.low > (USItype) bu.s.low)
+ return 2;
+ return 1;
+}
+#endif
+
+#if defined(L_fixunstfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
+#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
+#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
+
+DItype
+__fixunstfdi (a)
+ TFtype a;
+{
+ TFtype b;
+ UDItype v;
+
+ if (a < 0)
+ return 0;
+
+ /* Compute high word of result, as a flonum. */
+ b = (a / HIGH_WORD_COEFF);
+ /* Convert that to fixed (but not to DItype!),
+ and shift it into the high word. */
+ v = (USItype) b;
+ v <<= WORD_SIZE;
+ /* Remove high part from the TFtype, leaving the low part as flonum. */
+ a -= (TFtype)v;
+ /* Convert that to fixed (but not to DItype!) and add it in.
+ Sometimes A comes out negative. This is significant, since
+ A has more bits than a long int does. */
+ if (a < 0)
+ v -= (USItype) (- a);
+ else
+ v += (USItype) a;
+ return v;
+}
+#endif
+
+#if defined(L_fixtfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
+DItype
+__fixtfdi (a)
+ TFtype a;
+{
+ if (a < 0)
+ return - __fixunstfdi (-a);
+ return __fixunstfdi (a);
+}
+#endif
+
+#if defined(L_fixunsxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
+#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
+#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
+
+DItype
+__fixunsxfdi (a)
+ XFtype a;
+{
+ XFtype b;
+ UDItype v;
+
+ if (a < 0)
+ return 0;
+
+ /* Compute high word of result, as a flonum. */
+ b = (a / HIGH_WORD_COEFF);
+ /* Convert that to fixed (but not to DItype!),
+ and shift it into the high word. */
+ v = (USItype) b;
+ v <<= WORD_SIZE;
+ /* Remove high part from the XFtype, leaving the low part as flonum. */
+ a -= (XFtype)v;
+ /* Convert that to fixed (but not to DItype!) and add it in.
+ Sometimes A comes out negative. This is significant, since
+ A has more bits than a long int does. */
+ if (a < 0)
+ v -= (USItype) (- a);
+ else
+ v += (USItype) a;
+ return v;
+}
+#endif
+
+#if defined(L_fixxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
+DItype
+__fixxfdi (a)
+ XFtype a;
+{
+ if (a < 0)
+ return - __fixunsxfdi (-a);
+ return __fixunsxfdi (a);
+}
+#endif
+
+#ifdef L_fixunsdfdi
+#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
+#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
+
+DItype
+__fixunsdfdi (a)
+ DFtype a;
+{
+ DFtype b;
+ UDItype v;
+
+ if (a < 0)
+ return 0;
+
+ /* Compute high word of result, as a flonum. */
+ b = (a / HIGH_WORD_COEFF);
+ /* Convert that to fixed (but not to DItype!),
+ and shift it into the high word. */
+ v = (USItype) b;
+ v <<= WORD_SIZE;
+ /* Remove high part from the DFtype, leaving the low part as flonum. */
+ a -= (DFtype)v;
+ /* Convert that to fixed (but not to DItype!) and add it in.
+ Sometimes A comes out negative. This is significant, since
+ A has more bits than a long int does. */
+ if (a < 0)
+ v -= (USItype) (- a);
+ else
+ v += (USItype) a;
+ return v;
+}
+#endif
+
+#ifdef L_fixdfdi
+DItype
+__fixdfdi (a)
+ DFtype a;
+{
+ if (a < 0)
+ return - __fixunsdfdi (-a);
+ return __fixunsdfdi (a);
+}
+#endif
+
+#ifdef L_fixunssfdi
+#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
+#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
+
+DItype
+__fixunssfdi (SFtype original_a)
+{
+ /* Convert the SFtype to a DFtype, because that is surely not going
+ to lose any bits. Some day someone else can write a faster version
+ that avoids converting to DFtype, and verify it really works right. */
+ DFtype a = original_a;
+ DFtype b;
+ UDItype v;
+
+ if (a < 0)
+ return 0;
+
+ /* Compute high word of result, as a flonum. */
+ b = (a / HIGH_WORD_COEFF);
+ /* Convert that to fixed (but not to DItype!),
+ and shift it into the high word. */
+ v = (USItype) b;
+ v <<= WORD_SIZE;
+ /* Remove high part from the DFtype, leaving the low part as flonum. */
+ a -= (DFtype)v;
+ /* Convert that to fixed (but not to DItype!) and add it in.
+ Sometimes A comes out negative. This is significant, since
+ A has more bits than a long int does. */
+ if (a < 0)
+ v -= (USItype) (- a);
+ else
+ v += (USItype) a;
+ return v;
+}
+#endif
+
+#ifdef L_fixsfdi
+DItype
+__fixsfdi (SFtype a)
+{
+ if (a < 0)
+ return - __fixunssfdi (-a);
+ return __fixunssfdi (a);
+}
+#endif
+
+#if defined(L_floatdixf) && (LONG_DOUBLE_TYPE_SIZE == 96)
+#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)
+
+XFtype
+__floatdixf (u)
+ DItype u;
+{
+ XFtype d;
+ SItype negate = 0;
+
+ if (u < 0)
+ u = -u, negate = 1;
+
+ d = (USItype) (u >> WORD_SIZE);
+ d *= HIGH_HALFWORD_COEFF;
+ d *= HIGH_HALFWORD_COEFF;
+ d += (USItype) (u & (HIGH_WORD_COEFF - 1));
+
+ return (negate ? -d : d);
+}
+#endif
+
+#if defined(L_floatditf) && (LONG_DOUBLE_TYPE_SIZE == 128)
+#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)
+
+TFtype
+__floatditf (u)
+ DItype u;
+{
+ TFtype d;
+ SItype negate = 0;
+
+ if (u < 0)
+ u = -u, negate = 1;
+
+ d = (USItype) (u >> WORD_SIZE);
+ d *= HIGH_HALFWORD_COEFF;
+ d *= HIGH_HALFWORD_COEFF;
+ d += (USItype) (u & (HIGH_WORD_COEFF - 1));
+
+ return (negate ? -d : d);
+}
+#endif
+
+#ifdef L_floatdidf
+#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)
+
+DFtype
+__floatdidf (u)
+ DItype u;
+{
+ DFtype d;
+ SItype negate = 0;
+
+ if (u < 0)
+ u = -u, negate = 1;
+
+ d = (USItype) (u >> WORD_SIZE);
+ d *= HIGH_HALFWORD_COEFF;
+ d *= HIGH_HALFWORD_COEFF;
+ d += (USItype) (u & (HIGH_WORD_COEFF - 1));
+
+ return (negate ? -d : d);
+}
+#endif
+
+#ifdef L_floatdisf
+#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)
+ DItype u;
+{
+ /* Do the calculation in DFmode
+ so that we don't lose any of the precision of the high word
+ while multiplying it. */
+ DFtype f;
+ SItype negate = 0;
+
+ 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;
+ f += (USItype) (u & (HIGH_WORD_COEFF - 1));
+
+ return (SFtype) (negate ? -f : f);
+}
+#endif
+
+#if defined(L_fixunsxfsi) && LONG_DOUBLE_TYPE_SIZE == 96
+#include "glimits.h"
+
+USItype
+__fixunsxfsi (a)
+ XFtype a;
+{
+ if (a >= - (DFtype) LONG_MIN)
+ return (SItype) (a + LONG_MIN) - LONG_MIN;
+ return (SItype) a;
+}
+#endif
+
+#ifdef L_fixunsdfsi
+#include "glimits.h"
+
+USItype
+__fixunsdfsi (a)
+ DFtype a;
+{
+ if (a >= - (DFtype) LONG_MIN)
+ return (SItype) (a + LONG_MIN) - LONG_MIN;
+ return (SItype) a;
+}
+#endif
+
+#ifdef L_fixunssfsi
+#include "glimits.h"
+
+USItype
+__fixunssfsi (SFtype a)
+{
+ if (a >= - (SFtype) LONG_MIN)
+ return (SItype) (a + LONG_MIN) - LONG_MIN;
+ return (SItype) a;
+}
+#endif
+
+/* From here on down, the routines use normal data types. */
+
+#define SItype bogus_type
+#define USItype bogus_type
+#define DItype bogus_type
+#define UDItype bogus_type
+#define SFtype bogus_type
+#define DFtype bogus_type
+
+#undef char
+#undef short
+#undef int
+#undef long
+#undef unsigned
+#undef float
+#undef double
+
+#ifdef L__gcc_bcmp
+
+/* Like bcmp except the sign is meaningful.
+ Reult is negative if S1 is less than S2,
+ 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;
+{
+ while (size > 0)
+ {
+ unsigned char c1 = *s1++, c2 = *s2++;
+ if (c1 != c2)
+ return c1 - c2;
+ size--;
+ }
+ return 0;
+}
+
+#endif
+
+#ifdef L_varargs
+#ifdef __i860__
+#if defined(__svr4__) || defined(__alliant__)
+ asm (" .text");
+ asm (" .align 4");
+
+/* The Alliant needs the added underscore. */
+ asm (".globl __builtin_saveregs");
+asm ("__builtin_saveregs:");
+ asm (".globl ___builtin_saveregs");
+asm ("___builtin_saveregs:");
+
+ asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
+ asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
+ area and also for a new va_list
+ structure */
+ /* Save all argument registers in the arg reg save area. The
+ arg reg save area must have the following layout (according
+ to the svr4 ABI):
+
+ struct {
+ union {
+ float freg[8];
+ double dreg[4];
+ } float_regs;
+ long ireg[12];
+ };
+ */
+
+ asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
+ asm (" fst.q %f12,16(%sp)");
+
+ asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
+ asm (" st.l %r17,36(%sp)");
+ asm (" st.l %r18,40(%sp)");
+ asm (" st.l %r19,44(%sp)");
+ asm (" st.l %r20,48(%sp)");
+ asm (" st.l %r21,52(%sp)");
+ asm (" st.l %r22,56(%sp)");
+ asm (" st.l %r23,60(%sp)");
+ asm (" st.l %r24,64(%sp)");
+ asm (" st.l %r25,68(%sp)");
+ asm (" st.l %r26,72(%sp)");
+ asm (" st.l %r27,76(%sp)");
+
+ asm (" adds 80,%sp,%r16"); /* compute the address of the new
+ va_list structure. Put in into
+ r16 so that it will be returned
+ to the caller. */
+
+ /* Initialize all fields of the new va_list structure. This
+ structure looks like:
+
+ typedef struct {
+ unsigned long ireg_used;
+ unsigned long freg_used;
+ long *reg_base;
+ long *mem_ptr;
+ } va_list;
+ */
+
+ asm (" st.l %r0, 0(%r16)"); /* nfixed */
+ asm (" st.l %r0, 4(%r16)"); /* nfloating */
+ asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
+ asm (" bri %r1"); /* delayed return */
+ asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
+
+#else /* not __svr4__ */
+#if defined(__PARAGON__)
+ /*
+ * we'll use SVR4-ish varargs but need SVR3.2 assembler syntax,
+ * and we stand a better chance of hooking into libraries
+ * compiled by PGI. [andyp@ssd.intel.com]
+ */
+ asm (" .text");
+ asm (" .align 4");
+ asm (".globl __builtin_saveregs");
+asm ("__builtin_saveregs:");
+ asm (".globl ___builtin_saveregs");
+asm ("___builtin_saveregs:");
+
+ asm (" andnot 0x0f,sp,sp"); /* round down to 16-byte boundary */
+ asm (" adds -96,sp,sp"); /* allocate stack space for reg save
+ area and also for a new va_list
+ structure */
+ /* Save all argument registers in the arg reg save area. The
+ arg reg save area must have the following layout (according
+ to the svr4 ABI):
+
+ struct {
+ union {
+ float freg[8];
+ double dreg[4];
+ } float_regs;
+ long ireg[12];
+ };
+ */
+
+ asm (" fst.q f8, 0(sp)");
+ asm (" fst.q f12,16(sp)");
+ asm (" st.l r16,32(sp)");
+ asm (" st.l r17,36(sp)");
+ asm (" st.l r18,40(sp)");
+ asm (" st.l r19,44(sp)");
+ asm (" st.l r20,48(sp)");
+ asm (" st.l r21,52(sp)");
+ asm (" st.l r22,56(sp)");
+ asm (" st.l r23,60(sp)");
+ asm (" st.l r24,64(sp)");
+ asm (" st.l r25,68(sp)");
+ asm (" st.l r26,72(sp)");
+ asm (" st.l r27,76(sp)");
+
+ asm (" adds 80,sp,r16"); /* compute the address of the new
+ va_list structure. Put in into
+ r16 so that it will be returned
+ to the caller. */
+
+ /* Initialize all fields of the new va_list structure. This
+ structure looks like:
+
+ typedef struct {
+ unsigned long ireg_used;
+ unsigned long freg_used;
+ long *reg_base;
+ long *mem_ptr;
+ } va_list;
+ */
+
+ asm (" st.l r0, 0(r16)"); /* nfixed */
+ asm (" st.l r0, 4(r16)"); /* nfloating */
+ asm (" st.l sp, 8(r16)"); /* __va_ctl points to __va_struct. */
+ asm (" bri r1"); /* delayed return */
+ asm (" st.l r28,12(r16)"); /* pointer to overflow args */
+#else /* not __PARAGON__ */
+ asm (" .text");
+ asm (" .align 4");
+
+ asm (".globl ___builtin_saveregs");
+ asm ("___builtin_saveregs:");
+ asm (" mov sp,r30");
+ asm (" andnot 0x0f,sp,sp");
+ asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
+
+/* Fill in the __va_struct. */
+ asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
+ asm (" st.l r17, 4(sp)"); /* int fixed[12] */
+ asm (" st.l r18, 8(sp)");
+ asm (" st.l r19,12(sp)");
+ asm (" st.l r20,16(sp)");
+ asm (" st.l r21,20(sp)");
+ asm (" st.l r22,24(sp)");
+ asm (" st.l r23,28(sp)");
+ asm (" st.l r24,32(sp)");
+ asm (" st.l r25,36(sp)");
+ asm (" st.l r26,40(sp)");
+ asm (" st.l r27,44(sp)");
+
+ asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
+ asm (" fst.q f12,64(sp)"); /* int floating[8] */
+
+/* Fill in the __va_ctl. */
+ asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
+ asm (" st.l r28,84(sp)"); /* pointer to more args */
+ asm (" st.l r0, 88(sp)"); /* nfixed */
+ asm (" st.l r0, 92(sp)"); /* nfloating */
+
+ asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
+ asm (" bri r1");
+ asm (" mov r30,sp");
+ /* recover stack and pass address to start
+ of data. */
+#endif /* not __PARAGON__ */
+#endif /* not __svr4__ */
+#else /* not __i860__ */
+#ifdef __sparc__
+ asm (".global __builtin_saveregs");
+ asm ("__builtin_saveregs:");
+ asm (".global ___builtin_saveregs");
+ asm ("___builtin_saveregs:");
+#ifdef NEED_PROC_COMMAND
+ asm (".proc 020");
+#endif
+ asm ("st %i0,[%fp+68]");
+ asm ("st %i1,[%fp+72]");
+ asm ("st %i2,[%fp+76]");
+ asm ("st %i3,[%fp+80]");
+ asm ("st %i4,[%fp+84]");
+ asm ("retl");
+ asm ("st %i5,[%fp+88]");
+#ifdef NEED_TYPE_COMMAND
+ asm (".type __builtin_saveregs,#function");
+ asm (".size __builtin_saveregs,.-__builtin_saveregs");
+#endif
+#else /* not __sparc__ */
+#if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
+
+ asm (" .text");
+ asm (" .ent __builtin_saveregs");
+ asm (" .globl __builtin_saveregs");
+ asm ("__builtin_saveregs:");
+ asm (" sw $4,0($30)");
+ asm (" sw $5,4($30)");
+ asm (" sw $6,8($30)");
+ asm (" sw $7,12($30)");
+ asm (" j $31");
+ asm (" .end __builtin_saveregs");
+#else /* not __mips__, etc. */
+
+void *
+__builtin_saveregs ()
+{
+ abort ();
+}
+
+#endif /* not __mips__ */
+#endif /* not __sparc__ */
+#endif /* not __i860__ */
+#endif
+
+#ifdef L_eprintf
+#ifndef inhibit_libc
+
+#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
+#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;
+{
+ fprintf (stderr, string, expression, line, filename);
+ fflush (stderr);
+ abort ();
+}
+
+#endif
+#endif
+
+#ifdef L_bb
+
+/* Structure emitted by -a */
+struct bb
+{
+ long zero_word;
+ const char *filename;
+ long *counts;
+ long ncounts;
+ struct bb *next;
+ const unsigned long *addresses;
+
+ /* Older GCC's did not emit these fields. */
+ long nwords;
+ const char **functions;
+ const long *line_nums;
+ const char **filenames;
+};
+
+#ifdef BLOCK_PROFILER_CODE
+BLOCK_PROFILER_CODE
+#else
+#ifndef inhibit_libc
+
+/* Simple minded basic block profiling output dumper for
+ systems that don't provde tcov support. At present,
+ it requires atexit and stdio. */
+
+#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
+#include <stdio.h>
+
+#ifdef HAVE_ATEXIT
+extern void atexit (void (*) (void));
+#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
+
+static struct bb *bb_head = (struct bb *)0;
+
+/* Return the number of digits needed to print a value */
+/* __inline__ */ static int num_digits (long value, int base)
+{
+ int minus = (value < 0 && base != 16);
+ unsigned long v = (minus) ? -value : value;
+ int ret = minus;
+
+ do
+ {
+ v /= base;
+ ret++;
+ }
+ while (v);
+
+ return ret;
+}
+
+void
+__bb_exit_func (void)
+{
+ FILE *file = fopen ("bb.out", "a");
+ long time_value;
+
+ if (!file)
+ perror ("bb.out");
+
+ else
+ {
+ struct bb *ptr;
+
+ /* This is somewhat type incorrect, but it avoids worrying about
+ exactly where time.h is included from. It should be ok unless
+ a void * differs from other pointer formats, or if sizeof(long)
+ is < sizeof (time_t). It would be nice if we could assume the
+ use of rationale standards here. */
+
+ time((void *) &time_value);
+ fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value));
+
+ /* 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)
+ {
+ int i;
+ int func_p = (ptr->nwords >= sizeof (struct bb) && ptr->nwords <= 1000);
+ int line_p = (func_p && ptr->line_nums);
+ int file_p = (func_p && ptr->filenames);
+ long ncounts = ptr->ncounts;
+ long cnt_max = 0;
+ long line_max = 0;
+ long addr_max = 0;
+ int file_len = 0;
+ int func_len = 0;
+ int blk_len = num_digits (ncounts, 10);
+ int cnt_len;
+ int line_len;
+ int addr_len;
+
+ fprintf (file, "File %s, %ld basic blocks \n\n",
+ ptr->filename, ncounts);
+
+ /* Get max values for each field. */
+ for (i = 0; i < ncounts; i++)
+ {
+ const char *p;
+ int len;
+
+ if (cnt_max < ptr->counts[i])
+ cnt_max = ptr->counts[i];
+
+ if (addr_max < ptr->addresses[i])
+ addr_max = ptr->addresses[i];
+
+ if (line_p && line_max < ptr->line_nums[i])
+ line_max = ptr->line_nums[i];
+
+ if (func_p)
+ {
+ p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>";
+ len = strlen (p);
+ if (func_len < len)
+ func_len = len;
+ }
+
+ if (file_p)
+ {
+ p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>";
+ len = strlen (p);
+ if (file_len < len)
+ file_len = len;
+ }
+ }
+
+ addr_len = num_digits (addr_max, 16);
+ cnt_len = num_digits (cnt_max, 10);
+ line_len = num_digits (line_max, 10);
+
+ /* Now print out the basic block information. */
+ for (i = 0; i < ncounts; i++)
+ {
+ fprintf (file,
+ " Block #%*d: executed %*ld time(s) address= 0x%.*lx",
+ blk_len, i+1,
+ cnt_len, ptr->counts[i],
+ addr_len, ptr->addresses[i]);
+
+ if (func_p)
+ fprintf (file, " function= %-*s", func_len,
+ (ptr->functions[i]) ? ptr->functions[i] : "<none>");
+
+ if (line_p)
+ fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]);
+
+ if (file_p)
+ fprintf (file, " file= %s",
+ (ptr->filenames[i]) ? ptr->filenames[i] : "<none>");
+
+ fprintf (file, "\n");
+ }
+
+ fprintf (file, "\n");
+ fflush (file);
+ }
+
+ fprintf (file, "\n\n");
+ fclose (file);
+ }
+}
+
+void
+__bb_init_func (struct bb *blocks)
+{
+ /* User is supposed to check whether the first word is non-0,
+ but just in case.... */
+
+ if (blocks->zero_word)
+ return;
+
+#ifdef ON_EXIT
+ /* Initialize destructor. */
+ if (!bb_head)
+ ON_EXIT (__bb_exit_func, 0);
+#endif
+
+ /* Set up linked list. */
+ blocks->zero_word = 1;
+ blocks->next = bb_head;
+ bb_head = blocks;
+}
+
+#endif /* not inhibit_libc */
+#endif /* not BLOCK_PROFILER_CODE */
+#endif /* L_bb */
+
+/* Default free-store management functions for C++, per sections 12.5 and
+ 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. */
+
+typedef void (*vfp)(void);
+extern vfp __new_handler;
+
+void *
+__builtin_new (size_t sz)
+{
+ void *p;
+
+ /* malloc (0) is unpredictable; avoid it. */
+ if (sz == 0)
+ sz = 1;
+ p = (void *) malloc (sz);
+ 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__. */
+#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
+#include <stdio.h>
+
+#ifdef __GNU_LIBRARY__
+ /* Avoid forcing the library's meaning of `write' on the user program
+ by using the "internal" name (for use within the library) */
+#define write(fd, buf, n) __write((fd), (buf), (n))
+#endif
+#endif /* inhibit_libc */
+
+typedef void (*vfp)(void);
+void __default_new_handler (void);
+
+vfp __new_handler = __default_new_handler;
+
+vfp
+set_new_handler (vfp handler)
+{
+ vfp prev_handler;
+
+ prev_handler = __new_handler;
+ if (handler == 0) handler = __default_new_handler;
+ __new_handler = handler;
+ return prev_handler;
+}
+
+#define MESSAGE "Virtual memory exceeded in `new'\n"
+
+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
+ do. We need a standard, clean way to get at the name. */
+ write (2, MESSAGE, sizeof (MESSAGE));
+ /* don't call exit () because that may call global destructors which
+ may cause a loop. */
+ _exit (-1);
+}
+#endif
+
+#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. */
+
+void
+__builtin_delete (void *ptr)
+{
+ if (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 */
+
+#ifdef L_shtab
+unsigned int __shtab[] = {
+ 0x00000001, 0x00000002, 0x00000004, 0x00000008,
+ 0x00000010, 0x00000020, 0x00000040, 0x00000080,
+ 0x00000100, 0x00000200, 0x00000400, 0x00000800,
+ 0x00001000, 0x00002000, 0x00004000, 0x00008000,
+ 0x00010000, 0x00020000, 0x00040000, 0x00080000,
+ 0x00100000, 0x00200000, 0x00400000, 0x00800000,
+ 0x01000000, 0x02000000, 0x04000000, 0x08000000,
+ 0x10000000, 0x20000000, 0x40000000, 0x80000000
+ };
+#endif
+
+#ifdef L_clear_cache
+/* Clear part of an instruction cache. */
+
+#define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
+
+void
+__clear_cache (beg, end)
+ char *beg, *end;
+{
+#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 = 0;
+ int offset;
+ void *start_addr
+ void *end_addr;
+ typedef (*function_ptr) ();
+
+#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 */
+}
+
+#endif /* L_clear_cache */
+
+#ifdef L_trampoline
+
+/* Jump to a trampoline, loading the static chain address. */
+
+#ifdef TRANSFER_FROM_TRAMPOLINE
+TRANSFER_FROM_TRAMPOLINE
+#endif
+
+#if defined (NeXT) && defined (__MACH__)
+
+/* Make stack executable so we can call trampolines on stack.
+ This is called from INITIALIZE_TRAMPOLINE in next.h. */
+#ifdef NeXTStep21
+ #include <mach.h>
+#else
+ #include <mach/mach.h>
+#endif
+
+void
+__enable_execute_stack (addr)
+ char *addr;
+{
+ kern_return_t r;
+ char *eaddr = addr + TRAMPOLINE_SIZE;
+ vm_address_t a = (vm_address_t) addr;
+
+ /* turn on execute access on stack */
+ r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
+ if (r != KERN_SUCCESS)
+ {
+ mach_error("vm_protect VM_PROT_ALL", r);
+ exit(1);
+ }
+
+ /* We inline the i-cache invalidation for speed */
+
+#ifdef CLEAR_INSN_CACHE
+ CLEAR_INSN_CACHE (addr, eaddr);
+#else
+ __clear_cache ((int) addr, (int) eaddr);
+#endif
+}
+
+#endif /* defined (NeXT) && defined (__MACH__) */
+
+#ifdef __convex__
+
+/* Make stack executable so we can call trampolines on stack.
+ This is called from INITIALIZE_TRAMPOLINE in convex.h. */
+
+#include <sys/mman.h>
+#include <sys/vmparam.h>
+#include <machine/machparam.h>
+
+void
+__enable_execute_stack ()
+{
+ int fp;
+ static unsigned lowest = USRSTACK;
+ unsigned current = (unsigned) &fp & -NBPG;
+
+ if (lowest > current)
+ {
+ unsigned len = lowest - current;
+ mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
+ lowest = current;
+ }
+
+ /* Clear instruction cache in case an old trampoline is in it. */
+ asm ("pich");
+}
+#endif /* __convex__ */
+
+#ifdef __DOLPHIN__
+
+/* Modified from the convex -code above. */
+
+#include <sys/param.h>
+#include <errno.h>
+#include <sys/m88kbcs.h>
+
+void
+__enable_execute_stack ()
+{
+ int save_errno;
+ static unsigned long lowest = USRSTACK;
+ unsigned long current = (unsigned long) &save_errno & -NBPC;
+
+ /* Ignore errno being set. memctl sets errno to EINVAL whenever the
+ address is seen as 'negative'. That is the case with the stack. */
+
+ save_errno=errno;
+ if (lowest > current)
+ {
+ unsigned len=lowest-current;
+ memctl(current,len,MCT_TEXT);
+ lowest = current;
+ }
+ else
+ memctl(current,NBPC,MCT_TEXT);
+ errno=save_errno;
+}
+
+#endif /* __DOLPHIN__ */
+
+#ifdef __pyr__
+
+#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
+#include <stdio.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/vmmac.h>
+
+/* Modified from the convex -code above.
+ mremap promises to clear the i-cache. */
+
+void
+__enable_execute_stack ()
+{
+ int fp;
+ if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
+ PROT_READ|PROT_WRITE|PROT_EXEC))
+ {
+ perror ("mprotect in __enable_execute_stack");
+ fflush (stderr);
+ abort ();
+ }
+}
+#endif /* __pyr__ */
+#endif /* L_trampoline */
+
+#ifdef L__main
+
+#include "gbl-ctors.h"
+/* 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. */
+#ifndef NAME__MAIN
+#define NAME__MAIN "__main"
+#define SYMBOL__MAIN __main
+#endif
+
+/* Run all the global destructors on exit from the program. */
+
+void
+__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] ();
+#endif
+}
+
+#ifndef INIT_SECTION_ASM_OP
+/* Run all the global constructors on entry to the program. */
+
+#ifndef ON_EXIT
+#define ON_EXIT(a, b)
+#else
+/* Make sure the exit routine is pulled in to define the globals as
+ bss symbols, just in case the linker does not automatically pull
+ bss definitions from the library. */
+
+extern int _exit_dummy_decl;
+int *_exit_dummy_ref = &_exit_dummy_decl;
+#endif /* ON_EXIT */
+
+void
+__do_global_ctors ()
+{
+ DO_GLOBAL_CTORS_BODY;
+ ON_EXIT (__do_global_dtors, 0);
+}
+#endif /* no INIT_SECTION_ASM_OP */
+
+#if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
+/* Subroutine called automatically by `main'.
+ Compiling a global function named `main'
+ produces an automatic call to this function at the beginning.
+
+ For many systems, this routine calls __do_global_ctors.
+ For systems which support a .init section we use the .init section
+ to run __do_global_ctors, so we need not do anything here. */
+
+void
+SYMBOL__MAIN ()
+{
+ /* Support recursive calls to `main': run initializers just once. */
+ static int initialized = 0;
+ if (! initialized)
+ {
+ initialized = 1;
+ __do_global_ctors ();
+ }
+}
+#endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
+
+#endif /* L__main */
+
+#ifdef L_ctors
+
+#include "gbl-ctors.h"
+
+/* Provide default definitions for the lists of constructors and
+ destructors, so that we don't get linker errors. These symbols are
+ intentionally bss symbols, so that gld and/or collect will provide
+ the right values. */
+
+/* We declare the lists here with two elements each,
+ so that they are valid empty lists if no other definition is loaded. */
+#if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
+#ifdef __NeXT__
+/* After 2.3, try this definition on all systems. */
+func_ptr __CTOR_LIST__[2] = {0, 0};
+func_ptr __DTOR_LIST__[2] = {0, 0};
+#else
+func_ptr __CTOR_LIST__[2];
+func_ptr __DTOR_LIST__[2];
+#endif
+#endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
+#endif /* L_ctors */
+
+#ifdef L_exit
+
+#include "gbl-ctors.h"
+
+#ifndef ON_EXIT
+
+/* 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 _cleanup ();
+extern void _exit () __attribute__ ((noreturn));
+
+void
+exit (status)
+ int status;
+{
+ __do_global_dtors ();
+#ifdef EXIT_BODY
+ EXIT_BODY;
+#else
+ _cleanup ();
+#endif
+ _exit (status);
+}
+
+#else
+int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */
+#endif
+
+#endif /* L_exit */
+
+/* In a.out systems, we need to have these dummy constructor and destructor
+ lists in the library.
+
+ When using `collect', the first link will resolve __CTOR_LIST__
+ and __DTOR_LIST__ to these symbols. We will then run "nm" on the
+ result, build the correct __CTOR_LIST__ and __DTOR_LIST__, and relink.
+ Since we don't do the second link if no constructors existed, these
+ dummies must be fully functional empty lists.
+
+ When using `gnu ld', these symbols will be used if there are no
+ constructors. If there are constructors, the N_SETV symbol defined
+ by the linker from the N_SETT's in input files will define __CTOR_LIST__
+ and __DTOR_LIST__ rather than its being allocated as common storage
+ by the definitions below.
+
+ When using a linker that supports constructor and destructor segments,
+ these definitions will not be used, since crtbegin.o and crtend.o
+ (from crtstuff.c) will have already defined __CTOR_LIST__ and
+ __DTOR_LIST__. The crt*.o files are passed directly to the linker
+ on its command line, by gcc. */
+
+/* The list needs two elements: one is ignored (the old count); the
+ second is the terminating zero. Since both values are zero, this
+ declaration is not initialized, and it becomes `common'. */
+
+#ifdef L_ctor_list
+#include "gbl-ctors.h"
+func_ptr __CTOR_LIST__[2];
+#endif
+
+#ifdef L_dtor_list
+#include "gbl-ctors.h"
+func_ptr __DTOR_LIST__[2];
+#endif
OpenPOWER on IntegriCloud