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);
294 #if defined (sdiv_qrnnd)
296 __udiv_w_sdiv (rp, a1, a0, d)
297 USItype *rp, a1, a0, d;
304 if (a1 < d - a1 - (a0 >> (SI_TYPE_SIZE - 1)))
306 /* dividend, divisor, and quotient are nonnegative */
307 sdiv_qrnnd (q, r, a1, a0, d);
311 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
312 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (SI_TYPE_SIZE - 1));
313 /* Divide (c1*2^32 + c0) by d */
314 sdiv_qrnnd (q, r, c1, c0, d);
315 /* Add 2^31 to quotient */
316 q += (USItype) 1 << (SI_TYPE_SIZE - 1);
321 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
322 c1 = a1 >> 1; /* A/2 */
323 c0 = (a1 << (SI_TYPE_SIZE - 1)) + (a0 >> 1);
325 if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
327 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
329 r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
346 else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
349 c0 = ~c0; /* logical NOT */
351 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
353 q = ~q; /* (A/2)/b1 */
356 r = 2*r + (a0 & 1); /* A/(2*b1) */
374 else /* Implies c1 = b1 */
375 { /* Hence a1 = d - 1 = 2*b1 - 1 */
393 /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */
395 __udiv_w_sdiv (rp, a1, a0, d)
396 USItype *rp, a1, a0, d;
401 #if (defined (L_udivdi3) || defined (L_divdi3) || \
402 defined (L_umoddi3) || defined (L_moddi3))
407 static const UQItype __clz_tab[] =
409 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,
410 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,
411 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,
412 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,
413 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,
414 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,
415 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,
416 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,
419 #if (defined (L_udivdi3) || defined (L_divdi3) || \
420 defined (L_umoddi3) || defined (L_moddi3))
424 __udivmoddi4 (n, d, rp)
431 USItype d0, d1, n0, n1, n2;
443 #if !UDIV_NEEDS_NORMALIZATION
450 udiv_qrnnd (q0, n0, n1, n0, d0);
453 /* Remainder in n0. */
460 d0 = 1 / d0; /* Divide intentionally by zero. */
462 udiv_qrnnd (q1, n1, 0, n1, d0);
463 udiv_qrnnd (q0, n0, n1, n0, d0);
465 /* Remainder in n0. */
476 #else /* UDIV_NEEDS_NORMALIZATION */
484 count_leading_zeros (bm, d0);
488 /* Normalize, i.e. make the most significant bit of the
492 n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
496 udiv_qrnnd (q0, n0, n1, n0, d0);
499 /* Remainder in n0 >> bm. */
506 d0 = 1 / d0; /* Divide intentionally by zero. */
508 count_leading_zeros (bm, d0);
512 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
513 conclude (the most significant bit of n1 is set) /\ (the
514 leading quotient digit q1 = 1).
516 This special case is necessary, not an optimization.
517 (Shifts counts of SI_TYPE_SIZE are undefined.) */
526 b = SI_TYPE_SIZE - bm;
530 n1 = (n1 << bm) | (n0 >> b);
533 udiv_qrnnd (q1, n1, n2, n1, d0);
538 udiv_qrnnd (q0, n0, n1, n0, d0);
540 /* Remainder in n0 >> bm. */
550 #endif /* UDIV_NEEDS_NORMALIZATION */
561 /* Remainder in n1n0. */
573 count_leading_zeros (bm, d1);
576 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
577 conclude (the most significant bit of n1 is set) /\ (the
578 quotient digit q0 = 0 or 1).
580 This special case is necessary, not an optimization. */
582 /* The condition on the next line takes advantage of that
583 n1 >= d1 (true due to program flow). */
584 if (n1 > d1 || n0 >= d0)
587 sub_ddmmss (n1, n0, n1, n0, d1, d0);
606 b = SI_TYPE_SIZE - bm;
608 d1 = (d1 << bm) | (d0 >> b);
611 n1 = (n1 << bm) | (n0 >> b);
614 udiv_qrnnd (q0, n1, n2, n1, d1);
615 umul_ppmm (m1, m0, q0, d0);
617 if (m1 > n1 || (m1 == n1 && m0 > n0))
620 sub_ddmmss (m1, m0, m1, m0, d1, d0);
625 /* Remainder in (n1n0 - m1m0) >> bm. */
628 sub_ddmmss (n1, n0, n1, n0, m1, m0);
629 rr.s.low = (n1 << b) | (n0 >> bm);
630 rr.s.high = n1 >> bm;
644 UDItype __udivmoddi4 ();
659 uu.ll = __negdi2 (uu.ll);
662 vv.ll = __negdi2 (vv.ll);
664 w = __udivmoddi4 (uu.ll, vv.ll, (UDItype *) 0);
673 UDItype __udivmoddi4 ();
687 uu.ll = __negdi2 (uu.ll);
689 vv.ll = __negdi2 (vv.ll);
691 (void) __udivmoddi4 (uu.ll, vv.ll, &w);
700 UDItype __udivmoddi4 ();
707 (void) __udivmoddi4 (u, v, &w);
714 UDItype __udivmoddi4 ();
719 return __udivmoddi4 (n, d, (UDItype *) 0);
730 au.ll = a, bu.ll = b;
732 if (au.s.high < bu.s.high)
734 else if (au.s.high > bu.s.high)
736 if ((USItype) au.s.low < (USItype) bu.s.low)
738 else if ((USItype) au.s.low > (USItype) bu.s.low)
751 au.ll = a, bu.ll = b;
753 if ((USItype) au.s.high < (USItype) bu.s.high)
755 else if ((USItype) au.s.high > (USItype) bu.s.high)
757 if ((USItype) au.s.low < (USItype) bu.s.low)
759 else if ((USItype) au.s.low > (USItype) bu.s.low)
765 #if defined(L_fixunstfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
766 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
767 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
779 /* Compute high word of result, as a flonum. */
780 b = (a / HIGH_WORD_COEFF);
781 /* Convert that to fixed (but not to DItype!),
782 and shift it into the high word. */
785 /* Remove high part from the TFtype, leaving the low part as flonum. */
787 /* Convert that to fixed (but not to DItype!) and add it in.
788 Sometimes A comes out negative. This is significant, since
789 A has more bits than a long int does. */
791 v -= (USItype) (- a);
798 #if defined(L_fixtfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
804 return - __fixunstfdi (-a);
805 return __fixunstfdi (a);
809 #if defined(L_fixunsxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
810 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
811 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
823 /* Compute high word of result, as a flonum. */
824 b = (a / HIGH_WORD_COEFF);
825 /* Convert that to fixed (but not to DItype!),
826 and shift it into the high word. */
829 /* Remove high part from the XFtype, leaving the low part as flonum. */
831 /* Convert that to fixed (but not to DItype!) and add it in.
832 Sometimes A comes out negative. This is significant, since
833 A has more bits than a long int does. */
835 v -= (USItype) (- a);
842 #if defined(L_fixxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
848 return - __fixunsxfdi (-a);
849 return __fixunsxfdi (a);
854 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
855 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
867 /* Compute high word of result, as a flonum. */
868 b = (a / HIGH_WORD_COEFF);
869 /* Convert that to fixed (but not to DItype!),
870 and shift it into the high word. */
873 /* Remove high part from the DFtype, leaving the low part as flonum. */
875 /* Convert that to fixed (but not to DItype!) and add it in.
876 Sometimes A comes out negative. This is significant, since
877 A has more bits than a long int does. */
879 v -= (USItype) (- a);
892 return - __fixunsdfdi (-a);
893 return __fixunsdfdi (a);
898 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
899 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
902 __fixunssfdi (SFtype original_a)
904 /* Convert the SFtype to a DFtype, because that is surely not going
905 to lose any bits. Some day someone else can write a faster version
906 that avoids converting to DFtype, and verify it really works right. */
907 DFtype a = original_a;
914 /* Compute high word of result, as a flonum. */
915 b = (a / HIGH_WORD_COEFF);
916 /* Convert that to fixed (but not to DItype!),
917 and shift it into the high word. */
920 /* Remove high part from the DFtype, leaving the low part as flonum. */
922 /* Convert that to fixed (but not to DItype!) and add it in.
923 Sometimes A comes out negative. This is significant, since
924 A has more bits than a long int does. */
926 v -= (USItype) (- a);
938 return - __fixunssfdi (-a);
939 return __fixunssfdi (a);
943 #if defined(L_floatdixf) && (LONG_DOUBLE_TYPE_SIZE == 96)
944 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
945 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
946 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
958 d = (USItype) (u >> WORD_SIZE);
959 d *= HIGH_HALFWORD_COEFF;
960 d *= HIGH_HALFWORD_COEFF;
961 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
963 return (negate ? -d : d);
967 #if defined(L_floatditf) && (LONG_DOUBLE_TYPE_SIZE == 128)
968 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
969 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
970 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
982 d = (USItype) (u >> WORD_SIZE);
983 d *= HIGH_HALFWORD_COEFF;
984 d *= HIGH_HALFWORD_COEFF;
985 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
987 return (negate ? -d : d);
992 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
993 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
994 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
1006 d = (USItype) (u >> WORD_SIZE);
1007 d *= HIGH_HALFWORD_COEFF;
1008 d *= HIGH_HALFWORD_COEFF;
1009 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
1011 return (negate ? -d : d);
1016 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
1017 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
1018 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
1019 #define DI_SIZE (sizeof (DItype) * BITS_PER_UNIT)
1021 /* Define codes for all the float formats that we know of. Note
1022 that this is copied from real.h. */
1024 #define UNKNOWN_FLOAT_FORMAT 0
1025 #define IEEE_FLOAT_FORMAT 1
1026 #define VAX_FLOAT_FORMAT 2
1027 #define IBM_FLOAT_FORMAT 3
1029 /* Default to IEEE float if not specified. Nearly all machines use it. */
1030 #ifndef HOST_FLOAT_FORMAT
1031 #define HOST_FLOAT_FORMAT IEEE_FLOAT_FORMAT
1034 #if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1039 #if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
1044 #if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
1053 /* Do the calculation in DFmode
1054 so that we don't lose any of the precision of the high word
1055 while multiplying it. */
1062 /* Protect against double-rounding error.
1063 Represent any low-order bits, that might be truncated in DFmode,
1064 by a bit that won't be lost. The bit can go in anywhere below the
1065 rounding position of the SFmode. A fixed mask and bit position
1066 handles all usual configurations. It doesn't handle the case
1067 of 128-bit DImode, however. */
1068 if (DF_SIZE < DI_SIZE
1069 && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1071 #define REP_BIT ((USItype) 1 << (DI_SIZE - DF_SIZE))
1072 if (u >= ((UDItype) 1 << DF_SIZE))
1074 if ((USItype) u & (REP_BIT - 1))
1078 f = (USItype) (u >> WORD_SIZE);
1079 f *= HIGH_HALFWORD_COEFF;
1080 f *= HIGH_HALFWORD_COEFF;
1081 f += (USItype) (u & (HIGH_WORD_COEFF - 1));
1083 return (SFtype) (negate ? -f : f);
1087 #if defined(L_fixunsxfsi) && LONG_DOUBLE_TYPE_SIZE == 96
1088 /* Reenable the normal types, in case limits.h needs them. */
1104 if (a >= - (DFtype) LONG_MIN)
1105 return (SItype) (a + LONG_MIN) - LONG_MIN;
1111 /* Reenable the normal types, in case limits.h needs them. */
1127 if (a >= - (DFtype) LONG_MIN)
1128 return (SItype) (a + LONG_MIN) - LONG_MIN;
1134 /* Reenable the normal types, in case limits.h needs them. */
1147 __fixunssfsi (SFtype a)
1149 if (a >= - (SFtype) LONG_MIN)
1150 return (SItype) (a + LONG_MIN) - LONG_MIN;
1155 /* From here on down, the routines use normal data types. */
1157 #define SItype bogus_type
1158 #define USItype bogus_type
1159 #define DItype bogus_type
1160 #define UDItype bogus_type
1161 #define SFtype bogus_type
1162 #define DFtype bogus_type
1174 /* Like bcmp except the sign is meaningful.
1175 Result is negative if S1 is less than S2,
1176 positive if S1 is greater, 0 if S1 and S2 are equal. */
1179 __gcc_bcmp (s1, s2, size)
1180 unsigned char *s1, *s2;
1185 unsigned char c1 = *s1++, c2 = *s2++;
1197 #if defined(__svr4__) || defined(__alliant__)
1201 /* The Alliant needs the added underscore. */
1202 asm (".globl __builtin_saveregs");
1203 asm ("__builtin_saveregs:");
1204 asm (".globl ___builtin_saveregs");
1205 asm ("___builtin_saveregs:");
1207 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
1208 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
1209 area and also for a new va_list
1211 /* Save all argument registers in the arg reg save area. The
1212 arg reg save area must have the following layout (according
1224 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
1225 asm (" fst.q %f12,16(%sp)");
1227 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
1228 asm (" st.l %r17,36(%sp)");
1229 asm (" st.l %r18,40(%sp)");
1230 asm (" st.l %r19,44(%sp)");
1231 asm (" st.l %r20,48(%sp)");
1232 asm (" st.l %r21,52(%sp)");
1233 asm (" st.l %r22,56(%sp)");
1234 asm (" st.l %r23,60(%sp)");
1235 asm (" st.l %r24,64(%sp)");
1236 asm (" st.l %r25,68(%sp)");
1237 asm (" st.l %r26,72(%sp)");
1238 asm (" st.l %r27,76(%sp)");
1240 asm (" adds 80,%sp,%r16"); /* compute the address of the new
1241 va_list structure. Put in into
1242 r16 so that it will be returned
1245 /* Initialize all fields of the new va_list structure. This
1246 structure looks like:
1249 unsigned long ireg_used;
1250 unsigned long freg_used;
1256 asm (" st.l %r0, 0(%r16)"); /* nfixed */
1257 asm (" st.l %r0, 4(%r16)"); /* nfloating */
1258 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
1259 asm (" bri %r1"); /* delayed return */
1260 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
1262 #else /* not __svr4__ */
1263 #if defined(__PARAGON__)
1265 * we'll use SVR4-ish varargs but need SVR3.2 assembler syntax,
1266 * and we stand a better chance of hooking into libraries
1267 * compiled by PGI. [andyp@ssd.intel.com]
1271 asm (".globl __builtin_saveregs");
1272 asm ("__builtin_saveregs:");
1273 asm (".globl ___builtin_saveregs");
1274 asm ("___builtin_saveregs:");
1276 asm (" andnot 0x0f,sp,sp"); /* round down to 16-byte boundary */
1277 asm (" adds -96,sp,sp"); /* allocate stack space for reg save
1278 area and also for a new va_list
1280 /* Save all argument registers in the arg reg save area. The
1281 arg reg save area must have the following layout (according
1293 asm (" fst.q f8, 0(sp)");
1294 asm (" fst.q f12,16(sp)");
1295 asm (" st.l r16,32(sp)");
1296 asm (" st.l r17,36(sp)");
1297 asm (" st.l r18,40(sp)");
1298 asm (" st.l r19,44(sp)");
1299 asm (" st.l r20,48(sp)");
1300 asm (" st.l r21,52(sp)");
1301 asm (" st.l r22,56(sp)");
1302 asm (" st.l r23,60(sp)");
1303 asm (" st.l r24,64(sp)");
1304 asm (" st.l r25,68(sp)");
1305 asm (" st.l r26,72(sp)");
1306 asm (" st.l r27,76(sp)");
1308 asm (" adds 80,sp,r16"); /* compute the address of the new
1309 va_list structure. Put in into
1310 r16 so that it will be returned
1313 /* Initialize all fields of the new va_list structure. This
1314 structure looks like:
1317 unsigned long ireg_used;
1318 unsigned long freg_used;
1324 asm (" st.l r0, 0(r16)"); /* nfixed */
1325 asm (" st.l r0, 4(r16)"); /* nfloating */
1326 asm (" st.l sp, 8(r16)"); /* __va_ctl points to __va_struct. */
1327 asm (" bri r1"); /* delayed return */
1328 asm (" st.l r28,12(r16)"); /* pointer to overflow args */
1329 #else /* not __PARAGON__ */
1333 asm (".globl ___builtin_saveregs");
1334 asm ("___builtin_saveregs:");
1335 asm (" mov sp,r30");
1336 asm (" andnot 0x0f,sp,sp");
1337 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
1339 /* Fill in the __va_struct. */
1340 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
1341 asm (" st.l r17, 4(sp)"); /* int fixed[12] */
1342 asm (" st.l r18, 8(sp)");
1343 asm (" st.l r19,12(sp)");
1344 asm (" st.l r20,16(sp)");
1345 asm (" st.l r21,20(sp)");
1346 asm (" st.l r22,24(sp)");
1347 asm (" st.l r23,28(sp)");
1348 asm (" st.l r24,32(sp)");
1349 asm (" st.l r25,36(sp)");
1350 asm (" st.l r26,40(sp)");
1351 asm (" st.l r27,44(sp)");
1353 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
1354 asm (" fst.q f12,64(sp)"); /* int floating[8] */
1356 /* Fill in the __va_ctl. */
1357 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
1358 asm (" st.l r28,84(sp)"); /* pointer to more args */
1359 asm (" st.l r0, 88(sp)"); /* nfixed */
1360 asm (" st.l r0, 92(sp)"); /* nfloating */
1362 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
1364 asm (" mov r30,sp");
1365 /* recover stack and pass address to start
1367 #endif /* not __PARAGON__ */
1368 #endif /* not __svr4__ */
1369 #else /* not __i860__ */
1371 asm (".global __builtin_saveregs");
1372 asm ("__builtin_saveregs:");
1373 asm (".global ___builtin_saveregs");
1374 asm ("___builtin_saveregs:");
1375 #ifdef NEED_PROC_COMMAND
1378 asm ("st %i0,[%fp+68]");
1379 asm ("st %i1,[%fp+72]");
1380 asm ("st %i2,[%fp+76]");
1381 asm ("st %i3,[%fp+80]");
1382 asm ("st %i4,[%fp+84]");
1384 asm ("st %i5,[%fp+88]");
1385 #ifdef NEED_TYPE_COMMAND
1386 asm (".type __builtin_saveregs,#function");
1387 asm (".size __builtin_saveregs,.-__builtin_saveregs");
1389 #else /* not __sparc__ */
1390 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1393 asm (" .ent __builtin_saveregs");
1394 asm (" .globl __builtin_saveregs");
1395 asm ("__builtin_saveregs:");
1396 asm (" sw $4,0($30)");
1397 asm (" sw $5,4($30)");
1398 asm (" sw $6,8($30)");
1399 asm (" sw $7,12($30)");
1401 asm (" .end __builtin_saveregs");
1402 #else /* not __mips__, etc. */
1405 __builtin_saveregs ()
1410 #endif /* not __mips__ */
1411 #endif /* not __sparc__ */
1412 #endif /* not __i860__ */
1416 #ifndef inhibit_libc
1418 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1420 /* This is used by the `assert' macro. */
1422 __eprintf (string, expression, line, filename)
1424 const char *expression;
1426 const char *filename;
1428 fprintf (stderr, string, expression, line, filename);
1438 /* Structure emitted by -a */
1442 const char *filename;
1446 const unsigned long *addresses;
1448 /* Older GCC's did not emit these fields. */
1450 const char **functions;
1451 const long *line_nums;
1452 const char **filenames;
1455 #ifdef BLOCK_PROFILER_CODE
1458 #ifndef inhibit_libc
1460 /* Simple minded basic block profiling output dumper for
1461 systems that don't provide tcov support. At present,
1462 it requires atexit and stdio. */
1464 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1470 extern int atexit (void (*) (void));
1472 extern void atexit (void (*) (void));
1474 #define ON_EXIT(FUNC,ARG) atexit ((FUNC))
1477 extern void on_exit (void*, void*);
1478 #define ON_EXIT(FUNC,ARG) on_exit ((FUNC), (ARG))
1482 static struct bb *bb_head;
1484 /* Return the number of digits needed to print a value */
1485 /* __inline__ */ static int num_digits (long value, int base)
1487 int minus = (value < 0 && base != 16);
1488 unsigned long v = (minus) ? -value : value;
1502 __bb_exit_func (void)
1504 FILE *file = fopen ("bb.out", "a");
1514 /* This is somewhat type incorrect, but it avoids worrying about
1515 exactly where time.h is included from. It should be ok unless
1516 a void * differs from other pointer formats, or if sizeof(long)
1517 is < sizeof (time_t). It would be nice if we could assume the
1518 use of rationale standards here. */
1520 time((void *) &time_value);
1521 fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value));
1523 /* We check the length field explicitly in order to allow compatibility
1524 with older GCC's which did not provide it. */
1526 for (ptr = bb_head; ptr != (struct bb *)0; ptr = ptr->next)
1529 int func_p = (ptr->nwords >= sizeof (struct bb) && ptr->nwords <= 1000);
1530 int line_p = (func_p && ptr->line_nums);
1531 int file_p = (func_p && ptr->filenames);
1532 long ncounts = ptr->ncounts;
1538 int blk_len = num_digits (ncounts, 10);
1543 fprintf (file, "File %s, %ld basic blocks \n\n",
1544 ptr->filename, ncounts);
1546 /* Get max values for each field. */
1547 for (i = 0; i < ncounts; i++)
1552 if (cnt_max < ptr->counts[i])
1553 cnt_max = ptr->counts[i];
1555 if (addr_max < ptr->addresses[i])
1556 addr_max = ptr->addresses[i];
1558 if (line_p && line_max < ptr->line_nums[i])
1559 line_max = ptr->line_nums[i];
1563 p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>";
1571 p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>";
1578 addr_len = num_digits (addr_max, 16);
1579 cnt_len = num_digits (cnt_max, 10);
1580 line_len = num_digits (line_max, 10);
1582 /* Now print out the basic block information. */
1583 for (i = 0; i < ncounts; i++)
1586 " Block #%*d: executed %*ld time(s) address= 0x%.*lx",
1588 cnt_len, ptr->counts[i],
1589 addr_len, ptr->addresses[i]);
1592 fprintf (file, " function= %-*s", func_len,
1593 (ptr->functions[i]) ? ptr->functions[i] : "<none>");
1596 fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]);
1599 fprintf (file, " file= %s",
1600 (ptr->filenames[i]) ? ptr->filenames[i] : "<none>");
1602 fprintf (file, "\n");
1605 fprintf (file, "\n");
1609 fprintf (file, "\n\n");
1615 __bb_init_func (struct bb *blocks)
1617 /* User is supposed to check whether the first word is non-0,
1618 but just in case.... */
1620 if (blocks->zero_word)
1624 /* Initialize destructor. */
1626 ON_EXIT (__bb_exit_func, 0);
1629 /* Set up linked list. */
1630 blocks->zero_word = 1;
1631 blocks->next = bb_head;
1635 #endif /* not inhibit_libc */
1636 #endif /* not BLOCK_PROFILER_CODE */
1639 /* Default free-store management functions for C++, per sections 12.5 and
1640 17.3.3 of the Working Paper. */
1643 /* operator new (size_t), described in 17.3.3.5. This function is used by
1644 C++ programs to allocate a block of memory to hold a single object. */
1646 typedef void (*vfp)(void);
1647 extern vfp __new_handler;
1648 extern void __default_new_handler (void);
1651 void * __builtin_new (size_t sz)
1652 __attribute__ ((weak, alias ("___builtin_new")));
1654 ___builtin_new (size_t sz)
1657 __builtin_new (size_t sz)
1661 vfp handler = (__new_handler) ? __new_handler : __default_new_handler;
1663 /* malloc (0) is unpredictable; avoid it. */
1666 p = (void *) malloc (sz);
1670 p = (void *) malloc (sz);
1675 #endif /* L_op_new */
1678 /* void * operator new [] (size_t), described in 17.3.3.6. This function
1679 is used by C++ programs to allocate a block of memory for an array. */
1681 extern void * __builtin_new (size_t);
1684 void * __builtin_vec_new (size_t sz)
1685 __attribute__ ((weak, alias ("___builtin_vec_new")));
1687 ___builtin_vec_new (size_t sz)
1690 __builtin_vec_new (size_t sz)
1693 return __builtin_new (sz);
1695 #endif /* L_op_vnew */
1697 #ifdef L_new_handler
1698 /* set_new_handler (fvoid_t *) and the default new handler, described in
1699 17.3.3.2 and 17.3.3.5. These functions define the result of a failure
1700 to allocate the amount of memory requested from operator new or new []. */
1702 #ifndef inhibit_libc
1703 /* This gets us __GNU_LIBRARY__. */
1704 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1707 #ifdef __GNU_LIBRARY__
1708 /* Avoid forcing the library's meaning of `write' on the user program
1709 by using the "internal" name (for use within the library) */
1710 #define write(fd, buf, n) __write((fd), (buf), (n))
1712 #endif /* inhibit_libc */
1714 typedef void (*vfp)(void);
1715 void __default_new_handler (void);
1717 vfp __new_handler = (vfp)0;
1720 set_new_handler (vfp handler)
1724 prev_handler = __new_handler;
1725 if (handler == 0) handler = __default_new_handler;
1726 __new_handler = handler;
1727 return prev_handler;
1730 #define MESSAGE "Virtual memory exceeded in `new'\n"
1733 __default_new_handler ()
1735 #ifndef inhibit_libc
1736 /* don't use fprintf (stderr, ...) because it may need to call malloc. */
1737 /* This should really print the name of the program, but that is hard to
1738 do. We need a standard, clean way to get at the name. */
1739 write (2, MESSAGE, sizeof (MESSAGE));
1741 /* don't call exit () because that may call global destructors which
1742 may cause a loop. */
1748 /* operator delete (void *), described in 17.3.3.3. This function is used
1749 by C++ programs to return to the free store a block of memory allocated
1750 as a single object. */
1753 void __builtin_delete (void *ptr)
1754 __attribute__ ((weak, alias ("___builtin_delete")));
1756 ___builtin_delete (void *ptr)
1759 __builtin_delete (void *ptr)
1768 /* operator delete [] (void *), described in 17.3.3.4. This function is
1769 used by C++ programs to return to the free store a block of memory
1770 allocated as an array. */
1772 extern void __builtin_delete (void *);
1775 void __builtin_vec_delete (void *ptr)
1776 __attribute__ ((weak, alias ("___builtin_vec_delete")));
1778 ___builtin_vec_delete (void *ptr)
1781 __builtin_vec_delete (void *ptr)
1784 __builtin_delete (ptr);
1788 /* End of C++ free-store management functions */
1791 unsigned int __shtab[] = {
1792 0x00000001, 0x00000002, 0x00000004, 0x00000008,
1793 0x00000010, 0x00000020, 0x00000040, 0x00000080,
1794 0x00000100, 0x00000200, 0x00000400, 0x00000800,
1795 0x00001000, 0x00002000, 0x00004000, 0x00008000,
1796 0x00010000, 0x00020000, 0x00040000, 0x00080000,
1797 0x00100000, 0x00200000, 0x00400000, 0x00800000,
1798 0x01000000, 0x02000000, 0x04000000, 0x08000000,
1799 0x10000000, 0x20000000, 0x40000000, 0x80000000
1803 #ifdef L_clear_cache
1804 /* Clear part of an instruction cache. */
1806 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1809 __clear_cache (beg, end)
1812 #ifdef CLEAR_INSN_CACHE
1813 CLEAR_INSN_CACHE (beg, end);
1815 #ifdef INSN_CACHE_SIZE
1816 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1817 static int initialized;
1821 typedef (*function_ptr) ();
1823 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1824 /* It's cheaper to clear the whole cache.
1825 Put in a series of jump instructions so that calling the beginning
1826 of the cache will clear the whole thing. */
1830 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1831 & -INSN_CACHE_LINE_WIDTH);
1832 int end_ptr = ptr + INSN_CACHE_SIZE;
1834 while (ptr < end_ptr)
1836 *(INSTRUCTION_TYPE *)ptr
1837 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1838 ptr += INSN_CACHE_LINE_WIDTH;
1840 *(INSTRUCTION_TYPE *)(ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1845 /* Call the beginning of the sequence. */
1846 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1847 & -INSN_CACHE_LINE_WIDTH))
1850 #else /* Cache is large. */
1854 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1855 & -INSN_CACHE_LINE_WIDTH);
1857 while (ptr < (int) array + sizeof array)
1859 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1860 ptr += INSN_CACHE_LINE_WIDTH;
1866 /* Find the location in array that occupies the same cache line as BEG. */
1868 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1869 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1870 & -INSN_CACHE_PLANE_SIZE)
1873 /* Compute the cache alignment of the place to stop clearing. */
1874 #if 0 /* This is not needed for gcc's purposes. */
1875 /* If the block to clear is bigger than a cache plane,
1876 we clear the entire cache, and OFFSET is already correct. */
1877 if (end < beg + INSN_CACHE_PLANE_SIZE)
1879 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1880 & -INSN_CACHE_LINE_WIDTH)
1881 & (INSN_CACHE_PLANE_SIZE - 1));
1883 #if INSN_CACHE_DEPTH > 1
1884 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1885 if (end_addr <= start_addr)
1886 end_addr += INSN_CACHE_PLANE_SIZE;
1888 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1890 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1891 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1893 while (addr != stop)
1895 /* Call the return instruction at ADDR. */
1896 ((function_ptr) addr) ();
1898 addr += INSN_CACHE_LINE_WIDTH;
1901 #else /* just one plane */
1904 /* Call the return instruction at START_ADDR. */
1905 ((function_ptr) start_addr) ();
1907 start_addr += INSN_CACHE_LINE_WIDTH;
1909 while ((start_addr % INSN_CACHE_SIZE) != offset);
1910 #endif /* just one plane */
1911 #endif /* Cache is large */
1912 #endif /* Cache exists */
1913 #endif /* CLEAR_INSN_CACHE */
1916 #endif /* L_clear_cache */
1920 /* Jump to a trampoline, loading the static chain address. */
1933 int mprotect(addr, len, prot)
1939 if (prot == 7) np = 0x40;
1940 else if (prot == 5) np = 0x20;
1941 else if (prot == 4) np = 0x10;
1942 else if (prot == 3) np = 0x04;
1943 else if (prot == 1) np = 0x02;
1944 else if (prot == 0) np = 0x01;
1946 if (VirtualProtect (addr, len, np, &op))
1955 #ifdef TRANSFER_FROM_TRAMPOLINE
1956 TRANSFER_FROM_TRAMPOLINE
1959 #if defined (NeXT) && defined (__MACH__)
1961 /* Make stack executable so we can call trampolines on stack.
1962 This is called from INITIALIZE_TRAMPOLINE in next.h. */
1966 #include <mach/mach.h>
1970 __enable_execute_stack (addr)
1974 char *eaddr = addr + TRAMPOLINE_SIZE;
1975 vm_address_t a = (vm_address_t) addr;
1977 /* turn on execute access on stack */
1978 r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
1979 if (r != KERN_SUCCESS)
1981 mach_error("vm_protect VM_PROT_ALL", r);
1985 /* We inline the i-cache invalidation for speed */
1987 #ifdef CLEAR_INSN_CACHE
1988 CLEAR_INSN_CACHE (addr, eaddr);
1990 __clear_cache ((int) addr, (int) eaddr);
1994 #endif /* defined (NeXT) && defined (__MACH__) */
1998 /* Make stack executable so we can call trampolines on stack.
1999 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
2001 #include <sys/mman.h>
2002 #include <sys/vmparam.h>
2003 #include <machine/machparam.h>
2006 __enable_execute_stack ()
2009 static unsigned lowest = USRSTACK;
2010 unsigned current = (unsigned) &fp & -NBPG;
2012 if (lowest > current)
2014 unsigned len = lowest - current;
2015 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
2019 /* Clear instruction cache in case an old trampoline is in it. */
2022 #endif /* __convex__ */
2026 /* Modified from the convex -code above. */
2028 #include <sys/param.h>
2030 #include <sys/m88kbcs.h>
2033 __enable_execute_stack ()
2036 static unsigned long lowest = USRSTACK;
2037 unsigned long current = (unsigned long) &save_errno & -NBPC;
2039 /* Ignore errno being set. memctl sets errno to EINVAL whenever the
2040 address is seen as 'negative'. That is the case with the stack. */
2043 if (lowest > current)
2045 unsigned len=lowest-current;
2046 memctl(current,len,MCT_TEXT);
2050 memctl(current,NBPC,MCT_TEXT);
2054 #endif /* __DOLPHIN__ */
2058 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2060 #include <sys/mman.h>
2061 #include <sys/types.h>
2062 #include <sys/param.h>
2063 #include <sys/vmmac.h>
2065 /* Modified from the convex -code above.
2066 mremap promises to clear the i-cache. */
2069 __enable_execute_stack ()
2072 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
2073 PROT_READ|PROT_WRITE|PROT_EXEC))
2075 perror ("mprotect in __enable_execute_stack");
2080 #endif /* __pyr__ */
2081 #endif /* L_trampoline */
2085 #include "gbl-ctors.h"
2086 /* Some systems use __main in a way incompatible with its use in gcc, in these
2087 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2088 give the same symbol without quotes for an alternative entry point. You
2089 must define both, or neither. */
2091 #define NAME__MAIN "__main"
2092 #define SYMBOL__MAIN __main
2095 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2096 /* Run all the global destructors on exit from the program. */
2099 __do_global_dtors ()
2101 #ifdef DO_GLOBAL_DTORS_BODY
2102 DO_GLOBAL_DTORS_BODY;
2105 for (p = __DTOR_LIST__ + 1; *p; )
2111 #ifndef INIT_SECTION_ASM_OP
2112 /* Run all the global constructors on entry to the program. */
2115 #define ON_EXIT(a, b)
2117 /* Make sure the exit routine is pulled in to define the globals as
2118 bss symbols, just in case the linker does not automatically pull
2119 bss definitions from the library. */
2121 extern int _exit_dummy_decl;
2122 int *_exit_dummy_ref = &_exit_dummy_decl;
2123 #endif /* ON_EXIT */
2126 __do_global_ctors ()
2128 DO_GLOBAL_CTORS_BODY;
2129 ON_EXIT (__do_global_dtors, 0);
2131 #endif /* no INIT_SECTION_ASM_OP */
2133 #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
2134 /* Subroutine called automatically by `main'.
2135 Compiling a global function named `main'
2136 produces an automatic call to this function at the beginning.
2138 For many systems, this routine calls __do_global_ctors.
2139 For systems which support a .init section we use the .init section
2140 to run __do_global_ctors, so we need not do anything here. */
2145 /* Support recursive calls to `main': run initializers just once. */
2146 static int initialized;
2150 __do_global_ctors ();
2153 #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
2155 #endif /* L__main */
2159 #include "gbl-ctors.h"
2161 /* Provide default definitions for the lists of constructors and
2162 destructors, so that we don't get linker errors. These symbols are
2163 intentionally bss symbols, so that gld and/or collect will provide
2164 the right values. */
2166 /* We declare the lists here with two elements each,
2167 so that they are valid empty lists if no other definition is loaded. */
2168 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
2169 #if defined(__NeXT__) || defined(_AIX)
2170 /* After 2.3, try this definition on all systems. */
2171 func_ptr __CTOR_LIST__[2] = {0, 0};
2172 func_ptr __DTOR_LIST__[2] = {0, 0};
2174 func_ptr __CTOR_LIST__[2];
2175 func_ptr __DTOR_LIST__[2];
2177 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
2178 #endif /* L_ctors */
2182 #include "gbl-ctors.h"
2186 /* If we have no known way of registering our own __do_global_dtors
2187 routine so that it will be invoked at program exit time, then we
2188 have to define our own exit routine which will get this to happen. */
2190 extern void __do_global_dtors ();
2191 extern void _cleanup ();
2192 extern void _exit () __attribute__ ((noreturn));
2198 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2199 __do_global_dtors ();
2210 int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */
2219 void *exception_handler;
2222 struct exception_table_node {
2223 exception_table *table;
2226 struct exception_table_node *next;
2229 static int except_table_pos;
2230 static void *except_pc;
2231 static struct exception_table_node *exception_table_list;
2233 static exception_table *
2234 find_exception_table (pc)
2237 register struct exception_table_node *table = exception_table_list;
2238 for ( ; table != 0; table = table->next)
2240 if (table->start <= pc && table->end > pc)
2241 return table->table;
2246 /* this routine takes a pc, and the address of the exception handler associated
2247 with the closest exception table handler entry associated with that PC,
2248 or 0 if there are no table entries the PC fits in. The algorithm works
2249 something like this:
2251 while(current_entry exists) {
2252 if(current_entry.start < pc )
2253 current_entry = next_entry;
2255 if(prev_entry.start <= pc && prev_entry.end > pc) {
2256 save pointer to prev_entry;
2257 return prev_entry.exception_handler;
2264 Assuming a correctly sorted table (ascending order) this routine should
2265 return the tightest match...
2267 In the advent of a tie, we have to give the last entry, as it represents
2273 __find_first_exception_table_match(pc)
2276 exception_table *table = find_exception_table (pc);
2282 printf("find_first_exception_table_match(): pc = %x!\n",pc);
2288 /* We can't do this yet, as we don't know that the table is sorted. */
2291 if (table[pos].start > except_pc)
2292 /* found the first table[pos].start > except_pc, so the previous
2293 entry better be the one we want! */
2295 } while(table[pos].exception_handler != (void*)-1);
2298 if (table[pos].start <= except_pc && table[pos].end > except_pc)
2300 except_table_pos = pos;
2302 printf("find_first_eh_table_match(): found match: %x\n",table[pos].exception_handler);
2304 return table[pos].exception_handler;
2307 while (table[++pos].exception_handler != (void*)-1) {
2308 if (table[pos].start <= except_pc && table[pos].end > except_pc)
2310 /* This can apply. Make sure it is better or as good as the previous
2312 /* The best one ends first. */
2313 if (best == 0 || (table[pos].end <= table[best].end
2314 /* The best one starts last. */
2315 && table[pos].start >= table[best].start))
2320 return table[best].exception_handler;
2324 printf("find_first_eh_table_match(): else: returning NULL!\n");
2330 __throw_type_match (void *catch_type, void *throw_type, void* obj)
2333 printf("__throw_type_match (): catch_type = %s, throw_type = %s\n",
2334 catch_type, throw_type);
2336 if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)
2342 __register_exceptions (exception_table *table)
2344 struct exception_table_node *node;
2345 exception_table *range = table + 1;
2347 if (range->start == (void*)-1)
2350 node = (struct exception_table_node*)
2351 malloc (sizeof (struct exception_table_node));
2352 node->table = table;
2354 /* This look can be optimized away either if the table
2355 is sorted, or if we pass in extra parameters. */
2356 node->start = range->start;
2357 node->end = range->end;
2358 for (range++ ; range->start != (void*)(-1); range++)
2360 if (range->start < node->start)
2361 node->start = range->start;
2362 if (range->end > node->end)
2363 node->end = range->end;
2366 node->next = exception_table_list;
2367 exception_table_list = node;
2377 __unwind_function(void *ptr)
2379 asm("movl 8(%esp),%ecx");
2380 /* Undo current frame */
2381 asm("movl %ebp,%esp");
2383 /* like ret, but stay here */
2384 asm("addl $4,%esp");
2386 /* Now, undo previous frame. */
2387 /* This is a test routine, as we have to dynamically probe to find out
2388 what to pop for certain, this is just a guess. */
2389 asm("leal -16(%ebp),%esp");
2393 asm("movl %ebp,%esp");
2396 asm("movl %ecx,0(%esp)");
2399 #elif #machine(rs6000)
2400 __unwind_function(void *ptr)
2409 /* use 31 as a scratch register to restore the link register. */
2410 asm("l 31, 8(1);mtlr 31 # l lr,8(1)");
2413 asm("mtctr 3;bctr # b 3");
2415 #elif #machine(powerpc)
2416 __unwind_function(void *ptr)
2420 asm("lwz 31,-4(1)");
2425 /* use 31 as a scratch register to restore the link register. */
2426 asm("lwz 31, 8(1);mtlr 31 # l lr,8(1)");
2427 asm("lwz 31,-4(1)");
2429 asm("mtctr 3;bctr # b 3");
2432 __unwind_function(void *ptr)
2434 __label__ return_again;
2436 /* Replace our frame's return address with the label below.
2437 During execution, we will first return here instead of to
2438 caller, then second return takes caller's frame off the stack.
2439 Two returns matches two actual calls, so is less likely to
2440 confuse debuggers. `16' corresponds to RETURN_ADDRESS_OFFSET. */
2441 __asm ("movl %0,16(fp)" : : "p" (&& return_again));
2448 __unwind_function(void *ptr)
2452 #endif /* powerpc */
2456 #ifndef inhibit_libc
2457 /* This gets us __GNU_LIBRARY__. */
2458 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2461 #ifdef __GNU_LIBRARY__
2462 /* Avoid forcing the library's meaning of `write' on the user program
2463 by using the "internal" name (for use within the library) */
2464 #define write(fd, buf, n) __write((fd), (buf), (n))
2466 #endif /* inhibit_libc */
2468 #define MESSAGE "pure virtual method called\n"
2473 #ifndef inhibit_libc
2474 write (2, MESSAGE, sizeof (MESSAGE) - 1);