1 /* More subroutines needed by GCC output code on some machines. */
2 /* Compile this one with gcc. */
3 /* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* As a special exception, if you link this library with other files,
23 some of which are compiled with GCC, to produce an executable,
24 this library does not by itself cause the resulting executable
25 to be covered by the GNU General Public License.
26 This exception does not however invalidate any other reasons why
27 the executable file might be covered by the GNU General Public License. */
29 /* It is incorrect to include config.h here, because this file is being
30 compiled for the target, and hence definitions concerning only the host
40 /* Don't use `fancy_abort' here even if config.h says to use it. */
45 #if (SUPPORTS_WEAK == 1) && defined (ASM_OUTPUT_DEF)
49 /* Permit the tm.h file to select the endianness to use just for this
50 file. This is used when the endianness is determined when the
53 #ifndef LIBGCC2_WORDS_BIG_ENDIAN
54 #define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
57 /* In the first part of this file, we are interfacing to calls generated
58 by the compiler itself. These calls pass values into these routines
59 which have very specific modes (rather than very specific types), and
60 these compiler-generated calls also expect any return values to have
61 very specific modes (rather than very specific types). Thus, we need
62 to avoid using regular C language type names in this part of the file
63 because the sizes for those types can be configured to be anything.
64 Instead we use the following special type names. */
66 typedef unsigned int UQItype __attribute__ ((mode (QI)));
67 typedef int SItype __attribute__ ((mode (SI)));
68 typedef unsigned int USItype __attribute__ ((mode (SI)));
69 typedef int DItype __attribute__ ((mode (DI)));
70 typedef unsigned int UDItype __attribute__ ((mode (DI)));
72 typedef float SFtype __attribute__ ((mode (SF)));
73 typedef float DFtype __attribute__ ((mode (DF)));
75 #if LONG_DOUBLE_TYPE_SIZE == 96
76 typedef float XFtype __attribute__ ((mode (XF)));
78 #if LONG_DOUBLE_TYPE_SIZE == 128
79 typedef float TFtype __attribute__ ((mode (TF)));
82 typedef int word_type __attribute__ ((mode (__word__)));
84 /* Make sure that we don't accidentally use any normal C language built-in
85 type names in the first part of this file. Instead we want to use *only*
86 the type names defined above. The following macro definitions insure
87 that if we *do* accidentally use some normal C language built-in type name,
88 we will get a syntax error. */
90 #define char bogus_type
91 #define short bogus_type
92 #define int bogus_type
93 #define long bogus_type
94 #define unsigned bogus_type
95 #define float bogus_type
96 #define double bogus_type
98 #define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
100 /* DIstructs are pairs of SItype values in the order determined by
101 LIBGCC2_WORDS_BIG_ENDIAN. */
103 #if LIBGCC2_WORDS_BIG_ENDIAN
104 struct DIstruct {SItype high, low;};
106 struct DIstruct {SItype low, high;};
109 /* We need this union to unpack/pack DImode values, since we don't have
110 any arithmetic yet. Incoming DImode parameters are stored into the
111 `ll' field, and the unpacked result is read from the struct `s'. */
119 #if (defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_w_sdiv)\
120 || defined (L_divdi3) || defined (L_udivdi3) \
121 || defined (L_moddi3) || defined (L_umoddi3))
123 #include "longlong.h"
125 #endif /* udiv or mul */
127 extern DItype __fixunssfdi (SFtype a);
128 extern DItype __fixunsdfdi (DFtype a);
129 #if LONG_DOUBLE_TYPE_SIZE == 96
130 extern DItype __fixunsxfdi (XFtype a);
132 #if LONG_DOUBLE_TYPE_SIZE == 128
133 extern DItype __fixunstfdi (TFtype a);
136 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
137 #if defined (L_divdi3) || defined (L_moddi3)
150 w.s.high = -uu.s.high - ((USItype) w.s.low > 0);
171 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
175 w.s.low = (USItype)uu.s.high >> -bm;
179 USItype carries = (USItype)uu.s.high << bm;
180 w.s.high = (USItype)uu.s.high >> b;
181 w.s.low = ((USItype)uu.s.low >> b) | carries;
203 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
207 w.s.high = (USItype)uu.s.low << -bm;
211 USItype carries = (USItype)uu.s.low >> bm;
212 w.s.low = (USItype)uu.s.low << b;
213 w.s.high = ((USItype)uu.s.high << b) | carries;
235 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
238 /* w.s.high = 1..1 or 0..0 */
239 w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
240 w.s.low = uu.s.high >> -bm;
244 USItype carries = (USItype)uu.s.high << bm;
245 w.s.high = uu.s.high >> b;
246 w.s.low = ((USItype)uu.s.low >> b) | carries;
261 w.s.low = ffs (uu.s.low);
264 w.s.low = ffs (uu.s.high);
267 w.s.low += BITS_PER_UNIT * sizeof (SItype);
285 w.ll = __umulsidi3 (uu.s.low, vv.s.low);
286 w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
287 + (USItype) uu.s.high * (USItype) vv.s.low);
295 __udiv_w_sdiv (rp, a1, a0, d)
296 USItype *rp, a1, a0, d;
303 if (a1 < d - a1 - (a0 >> (SI_TYPE_SIZE - 1)))
305 /* dividend, divisor, and quotient are nonnegative */
306 sdiv_qrnnd (q, r, a1, a0, d);
310 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
311 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (SI_TYPE_SIZE - 1));
312 /* Divide (c1*2^32 + c0) by d */
313 sdiv_qrnnd (q, r, c1, c0, d);
314 /* Add 2^31 to quotient */
315 q += (USItype) 1 << (SI_TYPE_SIZE - 1);
320 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
321 c1 = a1 >> 1; /* A/2 */
322 c0 = (a1 << (SI_TYPE_SIZE - 1)) + (a0 >> 1);
324 if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
326 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
328 r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
345 else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
348 c0 = ~c0; /* logical NOT */
350 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
352 q = ~q; /* (A/2)/b1 */
355 r = 2*r + (a0 & 1); /* A/(2*b1) */
373 else /* Implies c1 = b1 */
374 { /* Hence a1 = d - 1 = 2*b1 - 1 */
393 #if (defined (L_udivdi3) || defined (L_divdi3) || \
394 defined (L_umoddi3) || defined (L_moddi3))
399 static const UQItype __clz_tab[] =
401 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,
402 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,
403 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,
404 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,
405 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,
406 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,
407 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,
408 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,
411 #if (defined (L_udivdi3) || defined (L_divdi3) || \
412 defined (L_umoddi3) || defined (L_moddi3))
416 __udivmoddi4 (n, d, rp)
423 USItype d0, d1, n0, n1, n2;
435 #if !UDIV_NEEDS_NORMALIZATION
442 udiv_qrnnd (q0, n0, n1, n0, d0);
445 /* Remainder in n0. */
452 d0 = 1 / d0; /* Divide intentionally by zero. */
454 udiv_qrnnd (q1, n1, 0, n1, d0);
455 udiv_qrnnd (q0, n0, n1, n0, d0);
457 /* Remainder in n0. */
468 #else /* UDIV_NEEDS_NORMALIZATION */
476 count_leading_zeros (bm, d0);
480 /* Normalize, i.e. make the most significant bit of the
484 n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
488 udiv_qrnnd (q0, n0, n1, n0, d0);
491 /* Remainder in n0 >> bm. */
498 d0 = 1 / d0; /* Divide intentionally by zero. */
500 count_leading_zeros (bm, d0);
504 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
505 conclude (the most significant bit of n1 is set) /\ (the
506 leading quotient digit q1 = 1).
508 This special case is necessary, not an optimization.
509 (Shifts counts of SI_TYPE_SIZE are undefined.) */
518 b = SI_TYPE_SIZE - bm;
522 n1 = (n1 << bm) | (n0 >> b);
525 udiv_qrnnd (q1, n1, n2, n1, d0);
530 udiv_qrnnd (q0, n0, n1, n0, d0);
532 /* Remainder in n0 >> bm. */
542 #endif /* UDIV_NEEDS_NORMALIZATION */
553 /* Remainder in n1n0. */
565 count_leading_zeros (bm, d1);
568 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
569 conclude (the most significant bit of n1 is set) /\ (the
570 quotient digit q0 = 0 or 1).
572 This special case is necessary, not an optimization. */
574 /* The condition on the next line takes advantage of that
575 n1 >= d1 (true due to program flow). */
576 if (n1 > d1 || n0 >= d0)
579 sub_ddmmss (n1, n0, n1, n0, d1, d0);
598 b = SI_TYPE_SIZE - bm;
600 d1 = (d1 << bm) | (d0 >> b);
603 n1 = (n1 << bm) | (n0 >> b);
606 udiv_qrnnd (q0, n1, n2, n1, d1);
607 umul_ppmm (m1, m0, q0, d0);
609 if (m1 > n1 || (m1 == n1 && m0 > n0))
612 sub_ddmmss (m1, m0, m1, m0, d1, d0);
617 /* Remainder in (n1n0 - m1m0) >> bm. */
620 sub_ddmmss (n1, n0, n1, n0, m1, m0);
621 rr.s.low = (n1 << b) | (n0 >> bm);
622 rr.s.high = n1 >> bm;
636 UDItype __udivmoddi4 ();
651 uu.ll = __negdi2 (uu.ll);
654 vv.ll = __negdi2 (vv.ll);
656 w = __udivmoddi4 (uu.ll, vv.ll, (UDItype *) 0);
665 UDItype __udivmoddi4 ();
679 uu.ll = __negdi2 (uu.ll);
681 vv.ll = __negdi2 (vv.ll);
683 (void) __udivmoddi4 (uu.ll, vv.ll, &w);
692 UDItype __udivmoddi4 ();
699 (void) __udivmoddi4 (u, v, &w);
706 UDItype __udivmoddi4 ();
711 return __udivmoddi4 (n, d, (UDItype *) 0);
722 au.ll = a, bu.ll = b;
724 if (au.s.high < bu.s.high)
726 else if (au.s.high > bu.s.high)
728 if ((USItype) au.s.low < (USItype) bu.s.low)
730 else if ((USItype) au.s.low > (USItype) bu.s.low)
743 au.ll = a, bu.ll = b;
745 if ((USItype) au.s.high < (USItype) bu.s.high)
747 else if ((USItype) au.s.high > (USItype) bu.s.high)
749 if ((USItype) au.s.low < (USItype) bu.s.low)
751 else if ((USItype) au.s.low > (USItype) bu.s.low)
757 #if defined(L_fixunstfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
758 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
759 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
771 /* Compute high word of result, as a flonum. */
772 b = (a / HIGH_WORD_COEFF);
773 /* Convert that to fixed (but not to DItype!),
774 and shift it into the high word. */
777 /* Remove high part from the TFtype, leaving the low part as flonum. */
779 /* Convert that to fixed (but not to DItype!) and add it in.
780 Sometimes A comes out negative. This is significant, since
781 A has more bits than a long int does. */
783 v -= (USItype) (- a);
790 #if defined(L_fixtfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
796 return - __fixunstfdi (-a);
797 return __fixunstfdi (a);
801 #if defined(L_fixunsxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
802 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
803 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
815 /* Compute high word of result, as a flonum. */
816 b = (a / HIGH_WORD_COEFF);
817 /* Convert that to fixed (but not to DItype!),
818 and shift it into the high word. */
821 /* Remove high part from the XFtype, leaving the low part as flonum. */
823 /* Convert that to fixed (but not to DItype!) and add it in.
824 Sometimes A comes out negative. This is significant, since
825 A has more bits than a long int does. */
827 v -= (USItype) (- a);
834 #if defined(L_fixxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
840 return - __fixunsxfdi (-a);
841 return __fixunsxfdi (a);
846 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
847 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
859 /* Compute high word of result, as a flonum. */
860 b = (a / HIGH_WORD_COEFF);
861 /* Convert that to fixed (but not to DItype!),
862 and shift it into the high word. */
865 /* Remove high part from the DFtype, leaving the low part as flonum. */
867 /* Convert that to fixed (but not to DItype!) and add it in.
868 Sometimes A comes out negative. This is significant, since
869 A has more bits than a long int does. */
871 v -= (USItype) (- a);
884 return - __fixunsdfdi (-a);
885 return __fixunsdfdi (a);
890 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
891 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
894 __fixunssfdi (SFtype original_a)
896 /* Convert the SFtype to a DFtype, because that is surely not going
897 to lose any bits. Some day someone else can write a faster version
898 that avoids converting to DFtype, and verify it really works right. */
899 DFtype a = original_a;
906 /* Compute high word of result, as a flonum. */
907 b = (a / HIGH_WORD_COEFF);
908 /* Convert that to fixed (but not to DItype!),
909 and shift it into the high word. */
912 /* Remove high part from the DFtype, leaving the low part as flonum. */
914 /* Convert that to fixed (but not to DItype!) and add it in.
915 Sometimes A comes out negative. This is significant, since
916 A has more bits than a long int does. */
918 v -= (USItype) (- a);
930 return - __fixunssfdi (-a);
931 return __fixunssfdi (a);
935 #if defined(L_floatdixf) && (LONG_DOUBLE_TYPE_SIZE == 96)
936 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
937 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
938 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
950 d = (USItype) (u >> WORD_SIZE);
951 d *= HIGH_HALFWORD_COEFF;
952 d *= HIGH_HALFWORD_COEFF;
953 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
955 return (negate ? -d : d);
959 #if defined(L_floatditf) && (LONG_DOUBLE_TYPE_SIZE == 128)
960 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
961 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
962 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
974 d = (USItype) (u >> WORD_SIZE);
975 d *= HIGH_HALFWORD_COEFF;
976 d *= HIGH_HALFWORD_COEFF;
977 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
979 return (negate ? -d : d);
984 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
985 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
986 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
998 d = (USItype) (u >> WORD_SIZE);
999 d *= HIGH_HALFWORD_COEFF;
1000 d *= HIGH_HALFWORD_COEFF;
1001 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
1003 return (negate ? -d : d);
1008 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
1009 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
1010 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
1011 #define DI_SIZE (sizeof (DItype) * BITS_PER_UNIT)
1013 /* Define codes for all the float formats that we know of. Note
1014 that this is copied from real.h. */
1016 #define UNKNOWN_FLOAT_FORMAT 0
1017 #define IEEE_FLOAT_FORMAT 1
1018 #define VAX_FLOAT_FORMAT 2
1019 #define IBM_FLOAT_FORMAT 3
1021 /* Default to IEEE float if not specified. Nearly all machines use it. */
1022 #ifndef HOST_FLOAT_FORMAT
1023 #define HOST_FLOAT_FORMAT IEEE_FLOAT_FORMAT
1026 #if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1031 #if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
1036 #if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
1045 /* Do the calculation in DFmode
1046 so that we don't lose any of the precision of the high word
1047 while multiplying it. */
1054 /* Protect against double-rounding error.
1055 Represent any low-order bits, that might be truncated in DFmode,
1056 by a bit that won't be lost. The bit can go in anywhere below the
1057 rounding position of the SFmode. A fixed mask and bit position
1058 handles all usual configurations. It doesn't handle the case
1059 of 128-bit DImode, however. */
1060 if (DF_SIZE < DI_SIZE
1061 && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1063 #define REP_BIT ((USItype) 1 << (DI_SIZE - DF_SIZE))
1064 if (u >= ((UDItype) 1 << DF_SIZE))
1066 if ((USItype) u & (REP_BIT - 1))
1070 f = (USItype) (u >> WORD_SIZE);
1071 f *= HIGH_HALFWORD_COEFF;
1072 f *= HIGH_HALFWORD_COEFF;
1073 f += (USItype) (u & (HIGH_WORD_COEFF - 1));
1075 return (SFtype) (negate ? -f : f);
1079 #if defined(L_fixunsxfsi) && LONG_DOUBLE_TYPE_SIZE == 96
1080 /* Reenable the normal types, in case limits.h needs them. */
1094 if (a >= - (DFtype) LONG_MIN)
1095 return (SItype) (a + LONG_MIN) - LONG_MIN;
1101 /* Reenable the normal types, in case limits.h needs them. */
1115 if (a >= - (DFtype) LONG_MIN)
1116 return (SItype) (a + LONG_MIN) - LONG_MIN;
1122 /* Reenable the normal types, in case limits.h needs them. */
1133 __fixunssfsi (SFtype a)
1135 if (a >= - (SFtype) LONG_MIN)
1136 return (SItype) (a + LONG_MIN) - LONG_MIN;
1141 /* From here on down, the routines use normal data types. */
1143 #define SItype bogus_type
1144 #define USItype bogus_type
1145 #define DItype bogus_type
1146 #define UDItype bogus_type
1147 #define SFtype bogus_type
1148 #define DFtype bogus_type
1160 /* Like bcmp except the sign is meaningful.
1161 Result is negative if S1 is less than S2,
1162 positive if S1 is greater, 0 if S1 and S2 are equal. */
1165 __gcc_bcmp (s1, s2, size)
1166 unsigned char *s1, *s2;
1171 unsigned char c1 = *s1++, c2 = *s2++;
1183 #if defined(__svr4__) || defined(__alliant__)
1187 /* The Alliant needs the added underscore. */
1188 asm (".globl __builtin_saveregs");
1189 asm ("__builtin_saveregs:");
1190 asm (".globl ___builtin_saveregs");
1191 asm ("___builtin_saveregs:");
1193 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
1194 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
1195 area and also for a new va_list
1197 /* Save all argument registers in the arg reg save area. The
1198 arg reg save area must have the following layout (according
1210 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
1211 asm (" fst.q %f12,16(%sp)");
1213 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
1214 asm (" st.l %r17,36(%sp)");
1215 asm (" st.l %r18,40(%sp)");
1216 asm (" st.l %r19,44(%sp)");
1217 asm (" st.l %r20,48(%sp)");
1218 asm (" st.l %r21,52(%sp)");
1219 asm (" st.l %r22,56(%sp)");
1220 asm (" st.l %r23,60(%sp)");
1221 asm (" st.l %r24,64(%sp)");
1222 asm (" st.l %r25,68(%sp)");
1223 asm (" st.l %r26,72(%sp)");
1224 asm (" st.l %r27,76(%sp)");
1226 asm (" adds 80,%sp,%r16"); /* compute the address of the new
1227 va_list structure. Put in into
1228 r16 so that it will be returned
1231 /* Initialize all fields of the new va_list structure. This
1232 structure looks like:
1235 unsigned long ireg_used;
1236 unsigned long freg_used;
1242 asm (" st.l %r0, 0(%r16)"); /* nfixed */
1243 asm (" st.l %r0, 4(%r16)"); /* nfloating */
1244 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
1245 asm (" bri %r1"); /* delayed return */
1246 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
1248 #else /* not __svr4__ */
1249 #if defined(__PARAGON__)
1251 * we'll use SVR4-ish varargs but need SVR3.2 assembler syntax,
1252 * and we stand a better chance of hooking into libraries
1253 * compiled by PGI. [andyp@ssd.intel.com]
1257 asm (".globl __builtin_saveregs");
1258 asm ("__builtin_saveregs:");
1259 asm (".globl ___builtin_saveregs");
1260 asm ("___builtin_saveregs:");
1262 asm (" andnot 0x0f,sp,sp"); /* round down to 16-byte boundary */
1263 asm (" adds -96,sp,sp"); /* allocate stack space for reg save
1264 area and also for a new va_list
1266 /* Save all argument registers in the arg reg save area. The
1267 arg reg save area must have the following layout (according
1279 asm (" fst.q f8, 0(sp)");
1280 asm (" fst.q f12,16(sp)");
1281 asm (" st.l r16,32(sp)");
1282 asm (" st.l r17,36(sp)");
1283 asm (" st.l r18,40(sp)");
1284 asm (" st.l r19,44(sp)");
1285 asm (" st.l r20,48(sp)");
1286 asm (" st.l r21,52(sp)");
1287 asm (" st.l r22,56(sp)");
1288 asm (" st.l r23,60(sp)");
1289 asm (" st.l r24,64(sp)");
1290 asm (" st.l r25,68(sp)");
1291 asm (" st.l r26,72(sp)");
1292 asm (" st.l r27,76(sp)");
1294 asm (" adds 80,sp,r16"); /* compute the address of the new
1295 va_list structure. Put in into
1296 r16 so that it will be returned
1299 /* Initialize all fields of the new va_list structure. This
1300 structure looks like:
1303 unsigned long ireg_used;
1304 unsigned long freg_used;
1310 asm (" st.l r0, 0(r16)"); /* nfixed */
1311 asm (" st.l r0, 4(r16)"); /* nfloating */
1312 asm (" st.l sp, 8(r16)"); /* __va_ctl points to __va_struct. */
1313 asm (" bri r1"); /* delayed return */
1314 asm (" st.l r28,12(r16)"); /* pointer to overflow args */
1315 #else /* not __PARAGON__ */
1319 asm (".globl ___builtin_saveregs");
1320 asm ("___builtin_saveregs:");
1321 asm (" mov sp,r30");
1322 asm (" andnot 0x0f,sp,sp");
1323 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
1325 /* Fill in the __va_struct. */
1326 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
1327 asm (" st.l r17, 4(sp)"); /* int fixed[12] */
1328 asm (" st.l r18, 8(sp)");
1329 asm (" st.l r19,12(sp)");
1330 asm (" st.l r20,16(sp)");
1331 asm (" st.l r21,20(sp)");
1332 asm (" st.l r22,24(sp)");
1333 asm (" st.l r23,28(sp)");
1334 asm (" st.l r24,32(sp)");
1335 asm (" st.l r25,36(sp)");
1336 asm (" st.l r26,40(sp)");
1337 asm (" st.l r27,44(sp)");
1339 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
1340 asm (" fst.q f12,64(sp)"); /* int floating[8] */
1342 /* Fill in the __va_ctl. */
1343 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
1344 asm (" st.l r28,84(sp)"); /* pointer to more args */
1345 asm (" st.l r0, 88(sp)"); /* nfixed */
1346 asm (" st.l r0, 92(sp)"); /* nfloating */
1348 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
1350 asm (" mov r30,sp");
1351 /* recover stack and pass address to start
1353 #endif /* not __PARAGON__ */
1354 #endif /* not __svr4__ */
1355 #else /* not __i860__ */
1357 asm (".global __builtin_saveregs");
1358 asm ("__builtin_saveregs:");
1359 asm (".global ___builtin_saveregs");
1360 asm ("___builtin_saveregs:");
1361 #ifdef NEED_PROC_COMMAND
1364 asm ("st %i0,[%fp+68]");
1365 asm ("st %i1,[%fp+72]");
1366 asm ("st %i2,[%fp+76]");
1367 asm ("st %i3,[%fp+80]");
1368 asm ("st %i4,[%fp+84]");
1370 asm ("st %i5,[%fp+88]");
1371 #ifdef NEED_TYPE_COMMAND
1372 asm (".type __builtin_saveregs,#function");
1373 asm (".size __builtin_saveregs,.-__builtin_saveregs");
1375 #else /* not __sparc__ */
1376 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1379 asm (" .ent __builtin_saveregs");
1380 asm (" .globl __builtin_saveregs");
1381 asm ("__builtin_saveregs:");
1382 asm (" sw $4,0($30)");
1383 asm (" sw $5,4($30)");
1384 asm (" sw $6,8($30)");
1385 asm (" sw $7,12($30)");
1387 asm (" .end __builtin_saveregs");
1388 #else /* not __mips__, etc. */
1391 __builtin_saveregs ()
1396 #endif /* not __mips__ */
1397 #endif /* not __sparc__ */
1398 #endif /* not __i860__ */
1402 #ifndef inhibit_libc
1404 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1406 /* This is used by the `assert' macro. */
1408 __eprintf (string, expression, line, filename)
1410 const char *expression;
1412 const char *filename;
1414 fprintf (stderr, string, expression, line, filename);
1424 /* Structure emitted by -a */
1428 const char *filename;
1432 const unsigned long *addresses;
1434 /* Older GCC's did not emit these fields. */
1436 const char **functions;
1437 const long *line_nums;
1438 const char **filenames;
1441 #ifdef BLOCK_PROFILER_CODE
1444 #ifndef inhibit_libc
1446 /* Simple minded basic block profiling output dumper for
1447 systems that don't provide tcov support. At present,
1448 it requires atexit and stdio. */
1450 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1456 extern int atexit (void (*) (void));
1458 extern void atexit (void (*) (void));
1460 #define ON_EXIT(FUNC,ARG) atexit ((FUNC))
1463 extern void on_exit (void*, void*);
1464 #define ON_EXIT(FUNC,ARG) on_exit ((FUNC), (ARG))
1468 static struct bb *bb_head;
1470 /* Return the number of digits needed to print a value */
1471 /* __inline__ */ static int num_digits (long value, int base)
1473 int minus = (value < 0 && base != 16);
1474 unsigned long v = (minus) ? -value : value;
1488 __bb_exit_func (void)
1490 FILE *file = fopen ("bb.out", "a");
1500 /* This is somewhat type incorrect, but it avoids worrying about
1501 exactly where time.h is included from. It should be ok unless
1502 a void * differs from other pointer formats, or if sizeof(long)
1503 is < sizeof (time_t). It would be nice if we could assume the
1504 use of rationale standards here. */
1506 time((void *) &time_value);
1507 fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value));
1509 /* We check the length field explicitly in order to allow compatibility
1510 with older GCC's which did not provide it. */
1512 for (ptr = bb_head; ptr != (struct bb *)0; ptr = ptr->next)
1515 int func_p = (ptr->nwords >= sizeof (struct bb) && ptr->nwords <= 1000);
1516 int line_p = (func_p && ptr->line_nums);
1517 int file_p = (func_p && ptr->filenames);
1518 long ncounts = ptr->ncounts;
1524 int blk_len = num_digits (ncounts, 10);
1529 fprintf (file, "File %s, %ld basic blocks \n\n",
1530 ptr->filename, ncounts);
1532 /* Get max values for each field. */
1533 for (i = 0; i < ncounts; i++)
1538 if (cnt_max < ptr->counts[i])
1539 cnt_max = ptr->counts[i];
1541 if (addr_max < ptr->addresses[i])
1542 addr_max = ptr->addresses[i];
1544 if (line_p && line_max < ptr->line_nums[i])
1545 line_max = ptr->line_nums[i];
1549 p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>";
1557 p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>";
1564 addr_len = num_digits (addr_max, 16);
1565 cnt_len = num_digits (cnt_max, 10);
1566 line_len = num_digits (line_max, 10);
1568 /* Now print out the basic block information. */
1569 for (i = 0; i < ncounts; i++)
1572 " Block #%*d: executed %*ld time(s) address= 0x%.*lx",
1574 cnt_len, ptr->counts[i],
1575 addr_len, ptr->addresses[i]);
1578 fprintf (file, " function= %-*s", func_len,
1579 (ptr->functions[i]) ? ptr->functions[i] : "<none>");
1582 fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]);
1585 fprintf (file, " file= %s",
1586 (ptr->filenames[i]) ? ptr->filenames[i] : "<none>");
1588 fprintf (file, "\n");
1591 fprintf (file, "\n");
1595 fprintf (file, "\n\n");
1601 __bb_init_func (struct bb *blocks)
1603 /* User is supposed to check whether the first word is non-0,
1604 but just in case.... */
1606 if (blocks->zero_word)
1610 /* Initialize destructor. */
1612 ON_EXIT (__bb_exit_func, 0);
1615 /* Set up linked list. */
1616 blocks->zero_word = 1;
1617 blocks->next = bb_head;
1621 #endif /* not inhibit_libc */
1622 #endif /* not BLOCK_PROFILER_CODE */
1625 /* Default free-store management functions for C++, per sections 12.5 and
1626 17.3.3 of the Working Paper. */
1629 /* operator new (size_t), described in 17.3.3.5. This function is used by
1630 C++ programs to allocate a block of memory to hold a single object. */
1632 typedef void (*vfp)(void);
1633 extern vfp __new_handler;
1634 extern void __default_new_handler (void);
1637 void * __builtin_new (size_t sz)
1638 __attribute__ ((weak, alias ("___builtin_new")));
1640 ___builtin_new (size_t sz)
1643 __builtin_new (size_t sz)
1647 vfp handler = (__new_handler) ? __new_handler : __default_new_handler;
1649 /* malloc (0) is unpredictable; avoid it. */
1652 p = (void *) malloc (sz);
1656 p = (void *) malloc (sz);
1661 #endif /* L_op_new */
1664 /* void * operator new [] (size_t), described in 17.3.3.6. This function
1665 is used by C++ programs to allocate a block of memory for an array. */
1667 extern void * __builtin_new (size_t);
1670 void * __builtin_vec_new (size_t sz)
1671 __attribute__ ((weak, alias ("___builtin_vec_new")));
1673 ___builtin_vec_new (size_t sz)
1676 __builtin_vec_new (size_t sz)
1679 return __builtin_new (sz);
1681 #endif /* L_op_vnew */
1683 #ifdef L_new_handler
1684 /* set_new_handler (fvoid_t *) and the default new handler, described in
1685 17.3.3.2 and 17.3.3.5. These functions define the result of a failure
1686 to allocate the amount of memory requested from operator new or new []. */
1688 #ifndef inhibit_libc
1689 /* This gets us __GNU_LIBRARY__. */
1690 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1693 #ifdef __GNU_LIBRARY__
1694 /* Avoid forcing the library's meaning of `write' on the user program
1695 by using the "internal" name (for use within the library) */
1696 #define write(fd, buf, n) __write((fd), (buf), (n))
1698 #endif /* inhibit_libc */
1700 typedef void (*vfp)(void);
1701 void __default_new_handler (void);
1703 vfp __new_handler = (vfp)0;
1706 set_new_handler (vfp handler)
1710 prev_handler = __new_handler;
1711 if (handler == 0) handler = __default_new_handler;
1712 __new_handler = handler;
1713 return prev_handler;
1716 #define MESSAGE "Virtual memory exceeded in `new'\n"
1719 __default_new_handler ()
1721 #ifndef inhibit_libc
1722 /* don't use fprintf (stderr, ...) because it may need to call malloc. */
1723 /* This should really print the name of the program, but that is hard to
1724 do. We need a standard, clean way to get at the name. */
1725 write (2, MESSAGE, sizeof (MESSAGE));
1727 /* don't call exit () because that may call global destructors which
1728 may cause a loop. */
1734 /* operator delete (void *), described in 17.3.3.3. This function is used
1735 by C++ programs to return to the free store a block of memory allocated
1736 as a single object. */
1739 void __builtin_delete (void *ptr)
1740 __attribute__ ((weak, alias ("___builtin_delete")));
1742 ___builtin_delete (void *ptr)
1745 __builtin_delete (void *ptr)
1754 /* operator delete [] (void *), described in 17.3.3.4. This function is
1755 used by C++ programs to return to the free store a block of memory
1756 allocated as an array. */
1758 extern void __builtin_delete (void *);
1761 void __builtin_vec_delete (void *ptr)
1762 __attribute__ ((weak, alias ("___builtin_vec_delete")));
1764 ___builtin_vec_delete (void *ptr)
1767 __builtin_vec_delete (void *ptr)
1770 __builtin_delete (ptr);
1774 /* End of C++ free-store management functions */
1777 unsigned int __shtab[] = {
1778 0x00000001, 0x00000002, 0x00000004, 0x00000008,
1779 0x00000010, 0x00000020, 0x00000040, 0x00000080,
1780 0x00000100, 0x00000200, 0x00000400, 0x00000800,
1781 0x00001000, 0x00002000, 0x00004000, 0x00008000,
1782 0x00010000, 0x00020000, 0x00040000, 0x00080000,
1783 0x00100000, 0x00200000, 0x00400000, 0x00800000,
1784 0x01000000, 0x02000000, 0x04000000, 0x08000000,
1785 0x10000000, 0x20000000, 0x40000000, 0x80000000
1789 #ifdef L_clear_cache
1790 /* Clear part of an instruction cache. */
1792 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1795 __clear_cache (beg, end)
1798 #ifdef CLEAR_INSN_CACHE
1799 CLEAR_INSN_CACHE (beg, end);
1801 #ifdef INSN_CACHE_SIZE
1802 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1803 static int initialized;
1807 typedef (*function_ptr) ();
1809 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1810 /* It's cheaper to clear the whole cache.
1811 Put in a series of jump instructions so that calling the beginning
1812 of the cache will clear the whole thing. */
1816 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1817 & -INSN_CACHE_LINE_WIDTH);
1818 int end_ptr = ptr + INSN_CACHE_SIZE;
1820 while (ptr < end_ptr)
1822 *(INSTRUCTION_TYPE *)ptr
1823 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1824 ptr += INSN_CACHE_LINE_WIDTH;
1826 *(INSTRUCTION_TYPE *)(ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1831 /* Call the beginning of the sequence. */
1832 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1833 & -INSN_CACHE_LINE_WIDTH))
1836 #else /* Cache is large. */
1840 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1841 & -INSN_CACHE_LINE_WIDTH);
1843 while (ptr < (int) array + sizeof array)
1845 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1846 ptr += INSN_CACHE_LINE_WIDTH;
1852 /* Find the location in array that occupies the same cache line as BEG. */
1854 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1855 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1856 & -INSN_CACHE_PLANE_SIZE)
1859 /* Compute the cache alignment of the place to stop clearing. */
1860 #if 0 /* This is not needed for gcc's purposes. */
1861 /* If the block to clear is bigger than a cache plane,
1862 we clear the entire cache, and OFFSET is already correct. */
1863 if (end < beg + INSN_CACHE_PLANE_SIZE)
1865 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1866 & -INSN_CACHE_LINE_WIDTH)
1867 & (INSN_CACHE_PLANE_SIZE - 1));
1869 #if INSN_CACHE_DEPTH > 1
1870 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1871 if (end_addr <= start_addr)
1872 end_addr += INSN_CACHE_PLANE_SIZE;
1874 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1876 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1877 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1879 while (addr != stop)
1881 /* Call the return instruction at ADDR. */
1882 ((function_ptr) addr) ();
1884 addr += INSN_CACHE_LINE_WIDTH;
1887 #else /* just one plane */
1890 /* Call the return instruction at START_ADDR. */
1891 ((function_ptr) start_addr) ();
1893 start_addr += INSN_CACHE_LINE_WIDTH;
1895 while ((start_addr % INSN_CACHE_SIZE) != offset);
1896 #endif /* just one plane */
1897 #endif /* Cache is large */
1898 #endif /* Cache exists */
1899 #endif /* CLEAR_INSN_CACHE */
1902 #endif /* L_clear_cache */
1906 /* Jump to a trampoline, loading the static chain address. */
1908 #ifdef TRANSFER_FROM_TRAMPOLINE
1909 TRANSFER_FROM_TRAMPOLINE
1912 #if defined (NeXT) && defined (__MACH__)
1914 /* Make stack executable so we can call trampolines on stack.
1915 This is called from INITIALIZE_TRAMPOLINE in next.h. */
1919 #include <mach/mach.h>
1923 __enable_execute_stack (addr)
1927 char *eaddr = addr + TRAMPOLINE_SIZE;
1928 vm_address_t a = (vm_address_t) addr;
1930 /* turn on execute access on stack */
1931 r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
1932 if (r != KERN_SUCCESS)
1934 mach_error("vm_protect VM_PROT_ALL", r);
1938 /* We inline the i-cache invalidation for speed */
1940 #ifdef CLEAR_INSN_CACHE
1941 CLEAR_INSN_CACHE (addr, eaddr);
1943 __clear_cache ((int) addr, (int) eaddr);
1947 #endif /* defined (NeXT) && defined (__MACH__) */
1951 /* Make stack executable so we can call trampolines on stack.
1952 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
1954 #include <sys/mman.h>
1955 #include <sys/vmparam.h>
1956 #include <machine/machparam.h>
1959 __enable_execute_stack ()
1962 static unsigned lowest = USRSTACK;
1963 unsigned current = (unsigned) &fp & -NBPG;
1965 if (lowest > current)
1967 unsigned len = lowest - current;
1968 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
1972 /* Clear instruction cache in case an old trampoline is in it. */
1975 #endif /* __convex__ */
1979 /* Modified from the convex -code above. */
1981 #include <sys/param.h>
1983 #include <sys/m88kbcs.h>
1986 __enable_execute_stack ()
1989 static unsigned long lowest = USRSTACK;
1990 unsigned long current = (unsigned long) &save_errno & -NBPC;
1992 /* Ignore errno being set. memctl sets errno to EINVAL whenever the
1993 address is seen as 'negative'. That is the case with the stack. */
1996 if (lowest > current)
1998 unsigned len=lowest-current;
1999 memctl(current,len,MCT_TEXT);
2003 memctl(current,NBPC,MCT_TEXT);
2007 #endif /* __DOLPHIN__ */
2011 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2013 #include <sys/mman.h>
2014 #include <sys/types.h>
2015 #include <sys/param.h>
2016 #include <sys/vmmac.h>
2018 /* Modified from the convex -code above.
2019 mremap promises to clear the i-cache. */
2022 __enable_execute_stack ()
2025 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
2026 PROT_READ|PROT_WRITE|PROT_EXEC))
2028 perror ("mprotect in __enable_execute_stack");
2033 #endif /* __pyr__ */
2034 #endif /* L_trampoline */
2038 #include "gbl-ctors.h"
2039 /* Some systems use __main in a way incompatible with its use in gcc, in these
2040 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2041 give the same symbol without quotes for an alternative entry point. You
2042 must define both, or neither. */
2044 #define NAME__MAIN "__main"
2045 #define SYMBOL__MAIN __main
2048 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2049 /* Run all the global destructors on exit from the program. */
2052 __do_global_dtors ()
2054 #ifdef DO_GLOBAL_DTORS_BODY
2055 DO_GLOBAL_DTORS_BODY;
2058 for (p = __DTOR_LIST__ + 1; *p; )
2064 #ifndef INIT_SECTION_ASM_OP
2065 /* Run all the global constructors on entry to the program. */
2068 #define ON_EXIT(a, b)
2070 /* Make sure the exit routine is pulled in to define the globals as
2071 bss symbols, just in case the linker does not automatically pull
2072 bss definitions from the library. */
2074 extern int _exit_dummy_decl;
2075 int *_exit_dummy_ref = &_exit_dummy_decl;
2076 #endif /* ON_EXIT */
2079 __do_global_ctors ()
2081 DO_GLOBAL_CTORS_BODY;
2082 ON_EXIT (__do_global_dtors, 0);
2084 #endif /* no INIT_SECTION_ASM_OP */
2086 #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
2087 /* Subroutine called automatically by `main'.
2088 Compiling a global function named `main'
2089 produces an automatic call to this function at the beginning.
2091 For many systems, this routine calls __do_global_ctors.
2092 For systems which support a .init section we use the .init section
2093 to run __do_global_ctors, so we need not do anything here. */
2098 /* Support recursive calls to `main': run initializers just once. */
2099 static int initialized;
2103 __do_global_ctors ();
2106 #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
2108 #endif /* L__main */
2112 #include "gbl-ctors.h"
2114 /* Provide default definitions for the lists of constructors and
2115 destructors, so that we don't get linker errors. These symbols are
2116 intentionally bss symbols, so that gld and/or collect will provide
2117 the right values. */
2119 /* We declare the lists here with two elements each,
2120 so that they are valid empty lists if no other definition is loaded. */
2121 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
2123 /* After 2.3, try this definition on all systems. */
2124 func_ptr __CTOR_LIST__[2] = {0, 0};
2125 func_ptr __DTOR_LIST__[2] = {0, 0};
2127 func_ptr __CTOR_LIST__[2];
2128 func_ptr __DTOR_LIST__[2];
2130 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
2131 #endif /* L_ctors */
2135 #include "gbl-ctors.h"
2139 /* If we have no known way of registering our own __do_global_dtors
2140 routine so that it will be invoked at program exit time, then we
2141 have to define our own exit routine which will get this to happen. */
2143 extern void __do_global_dtors ();
2144 extern void _cleanup ();
2145 extern void _exit () __attribute__ ((noreturn));
2151 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2152 __do_global_dtors ();
2163 int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */
2172 void *exception_handler;
2175 struct exception_table_node {
2176 exception_table *table;
2179 struct exception_table_node *next;
2182 static int except_table_pos;
2183 static void *except_pc;
2184 static struct exception_table_node *exception_table_list;
2186 static exception_table *
2187 find_exception_table (pc)
2190 register struct exception_table_node *table = exception_table_list;
2191 for ( ; table != 0; table = table->next)
2193 if (table->start <= pc && table->end > pc)
2194 return table->table;
2199 /* this routine takes a pc, and the address of the exception handler associated
2200 with the closest exception table handler entry associated with that PC,
2201 or 0 if there are no table entries the PC fits in. The algorithm works
2202 something like this:
2204 while(current_entry exists) {
2205 if(current_entry.start < pc )
2206 current_entry = next_entry;
2208 if(prev_entry.start <= pc && prev_entry.end > pc) {
2209 save pointer to prev_entry;
2210 return prev_entry.exception_handler;
2217 Assuming a correctly sorted table (ascending order) this routine should
2218 return the tightest match...
2220 In the advent of a tie, we have to give the last entry, as it represents
2226 __find_first_exception_table_match(pc)
2229 exception_table *table = find_exception_table (pc);
2235 printf("find_first_exception_table_match(): pc = %x!\n",pc);
2241 /* We can't do this yet, as we don't know that the table is sorted. */
2244 if (table[pos].start > except_pc)
2245 /* found the first table[pos].start > except_pc, so the previous
2246 entry better be the one we want! */
2248 } while(table[pos].exception_handler != (void*)-1);
2251 if (table[pos].start <= except_pc && table[pos].end > except_pc)
2253 except_table_pos = pos;
2255 printf("find_first_eh_table_match(): found match: %x\n",table[pos].exception_handler);
2257 return table[pos].exception_handler;
2260 while (table[++pos].exception_handler != (void*)-1) {
2261 if (table[pos].start <= except_pc && table[pos].end > except_pc)
2263 /* This can apply. Make sure it is better or as good as the previous
2265 /* The best one ends first. */
2266 if (best == 0 || (table[pos].end <= table[best].end
2267 /* The best one starts last. */
2268 && table[pos].start >= table[best].start))
2273 return table[best].exception_handler;
2277 printf("find_first_eh_table_match(): else: returning NULL!\n");
2283 __throw_type_match (void *catch_type, void *throw_type, void* obj)
2286 printf("__throw_type_match (): catch_type = %s, throw_type = %s\n",
2287 catch_type, throw_type);
2289 if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)
2295 __register_exceptions (exception_table *table)
2297 struct exception_table_node *node;
2298 exception_table *range = table + 1;
2300 if (range->start == (void*)-1)
2303 node = (struct exception_table_node*)
2304 malloc (sizeof (struct exception_table_node));
2305 node->table = table;
2307 /* This look can be optimized away either if the table
2308 is sorted, or if we pass in extra parameters. */
2309 node->start = range->start;
2310 node->end = range->end;
2311 for (range++ ; range->start != (void*)(-1); range++)
2313 if (range->start < node->start)
2314 node->start = range->start;
2315 if (range->end > node->end)
2316 node->end = range->end;
2319 node->next = exception_table_list;
2320 exception_table_list = node;
2325 __unwind_function(void *ptr)
2327 asm("movl 8(%esp),%ecx");
2328 /* Undo current frame */
2329 asm("movl %ebp,%esp");
2331 /* like ret, but stay here */
2332 asm("addl $4,%esp");
2334 /* Now, undo previous frame. */
2335 /* This is a test routine, as we have to dynamically probe to find out
2336 what to pop for certain, this is just a guess. */
2337 asm("leal -16(%ebp),%esp");
2338 asm("pop %eax"); /* really for popl %ebx */
2339 asm("pop %eax"); /* really for popl %esi */
2340 asm("pop %eax"); /* really for popl %edi */
2341 asm("movl %ebp,%esp");
2344 asm("movl %ecx,0(%esp)");
2349 #if #machine(rs6000)
2350 __unwind_function(void *ptr)
2359 /* use 31 as a scratch register to restore the link register. */
2360 asm("l 31, 8(1);mtlr 31 # l lr,8(1)");
2363 asm("mtctr 3;bctr # b 3");
2367 #if #machine(powerpc)
2368 __unwind_function(void *ptr)
2372 asm("lwz 31,-4(1)");
2377 /* use 31 as a scratch register to restore the link register. */
2378 asm("lwz 31, 8(1);mtlr 31 # l lr,8(1)");
2379 asm("lwz 31,-4(1)");
2381 asm("mtctr 3;bctr # b 3");
2383 #endif /* powerpc */
2387 #ifndef inhibit_libc
2388 /* This gets us __GNU_LIBRARY__. */
2389 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2392 #ifdef __GNU_LIBRARY__
2393 /* Avoid forcing the library's meaning of `write' on the user program
2394 by using the "internal" name (for use within the library) */
2395 #define write(fd, buf, n) __write((fd), (buf), (n))
2397 #endif /* inhibit_libc */
2399 #define MESSAGE "pure virtual method called\n"
2404 #ifndef inhibit_libc
2405 write (2, MESSAGE, sizeof (MESSAGE) - 1);