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. */
1102 if (a >= - (DFtype) LONG_MIN)
1103 return (SItype) (a + LONG_MIN) - LONG_MIN;
1109 /* Reenable the normal types, in case limits.h needs them. */
1123 if (a >= - (DFtype) LONG_MIN)
1124 return (SItype) (a + LONG_MIN) - LONG_MIN;
1130 /* Reenable the normal types, in case limits.h needs them. */
1141 __fixunssfsi (SFtype a)
1143 if (a >= - (SFtype) LONG_MIN)
1144 return (SItype) (a + LONG_MIN) - LONG_MIN;
1149 /* From here on down, the routines use normal data types. */
1151 #define SItype bogus_type
1152 #define USItype bogus_type
1153 #define DItype bogus_type
1154 #define UDItype bogus_type
1155 #define SFtype bogus_type
1156 #define DFtype bogus_type
1168 /* Like bcmp except the sign is meaningful.
1169 Result is negative if S1 is less than S2,
1170 positive if S1 is greater, 0 if S1 and S2 are equal. */
1173 __gcc_bcmp (s1, s2, size)
1174 unsigned char *s1, *s2;
1179 unsigned char c1 = *s1++, c2 = *s2++;
1191 #if defined(__svr4__) || defined(__alliant__)
1195 /* The Alliant needs the added underscore. */
1196 asm (".globl __builtin_saveregs");
1197 asm ("__builtin_saveregs:");
1198 asm (".globl ___builtin_saveregs");
1199 asm ("___builtin_saveregs:");
1201 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
1202 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
1203 area and also for a new va_list
1205 /* Save all argument registers in the arg reg save area. The
1206 arg reg save area must have the following layout (according
1218 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
1219 asm (" fst.q %f12,16(%sp)");
1221 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
1222 asm (" st.l %r17,36(%sp)");
1223 asm (" st.l %r18,40(%sp)");
1224 asm (" st.l %r19,44(%sp)");
1225 asm (" st.l %r20,48(%sp)");
1226 asm (" st.l %r21,52(%sp)");
1227 asm (" st.l %r22,56(%sp)");
1228 asm (" st.l %r23,60(%sp)");
1229 asm (" st.l %r24,64(%sp)");
1230 asm (" st.l %r25,68(%sp)");
1231 asm (" st.l %r26,72(%sp)");
1232 asm (" st.l %r27,76(%sp)");
1234 asm (" adds 80,%sp,%r16"); /* compute the address of the new
1235 va_list structure. Put in into
1236 r16 so that it will be returned
1239 /* Initialize all fields of the new va_list structure. This
1240 structure looks like:
1243 unsigned long ireg_used;
1244 unsigned long freg_used;
1250 asm (" st.l %r0, 0(%r16)"); /* nfixed */
1251 asm (" st.l %r0, 4(%r16)"); /* nfloating */
1252 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
1253 asm (" bri %r1"); /* delayed return */
1254 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
1256 #else /* not __svr4__ */
1257 #if defined(__PARAGON__)
1259 * we'll use SVR4-ish varargs but need SVR3.2 assembler syntax,
1260 * and we stand a better chance of hooking into libraries
1261 * compiled by PGI. [andyp@ssd.intel.com]
1265 asm (".globl __builtin_saveregs");
1266 asm ("__builtin_saveregs:");
1267 asm (".globl ___builtin_saveregs");
1268 asm ("___builtin_saveregs:");
1270 asm (" andnot 0x0f,sp,sp"); /* round down to 16-byte boundary */
1271 asm (" adds -96,sp,sp"); /* allocate stack space for reg save
1272 area and also for a new va_list
1274 /* Save all argument registers in the arg reg save area. The
1275 arg reg save area must have the following layout (according
1287 asm (" fst.q f8, 0(sp)");
1288 asm (" fst.q f12,16(sp)");
1289 asm (" st.l r16,32(sp)");
1290 asm (" st.l r17,36(sp)");
1291 asm (" st.l r18,40(sp)");
1292 asm (" st.l r19,44(sp)");
1293 asm (" st.l r20,48(sp)");
1294 asm (" st.l r21,52(sp)");
1295 asm (" st.l r22,56(sp)");
1296 asm (" st.l r23,60(sp)");
1297 asm (" st.l r24,64(sp)");
1298 asm (" st.l r25,68(sp)");
1299 asm (" st.l r26,72(sp)");
1300 asm (" st.l r27,76(sp)");
1302 asm (" adds 80,sp,r16"); /* compute the address of the new
1303 va_list structure. Put in into
1304 r16 so that it will be returned
1307 /* Initialize all fields of the new va_list structure. This
1308 structure looks like:
1311 unsigned long ireg_used;
1312 unsigned long freg_used;
1318 asm (" st.l r0, 0(r16)"); /* nfixed */
1319 asm (" st.l r0, 4(r16)"); /* nfloating */
1320 asm (" st.l sp, 8(r16)"); /* __va_ctl points to __va_struct. */
1321 asm (" bri r1"); /* delayed return */
1322 asm (" st.l r28,12(r16)"); /* pointer to overflow args */
1323 #else /* not __PARAGON__ */
1327 asm (".globl ___builtin_saveregs");
1328 asm ("___builtin_saveregs:");
1329 asm (" mov sp,r30");
1330 asm (" andnot 0x0f,sp,sp");
1331 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
1333 /* Fill in the __va_struct. */
1334 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
1335 asm (" st.l r17, 4(sp)"); /* int fixed[12] */
1336 asm (" st.l r18, 8(sp)");
1337 asm (" st.l r19,12(sp)");
1338 asm (" st.l r20,16(sp)");
1339 asm (" st.l r21,20(sp)");
1340 asm (" st.l r22,24(sp)");
1341 asm (" st.l r23,28(sp)");
1342 asm (" st.l r24,32(sp)");
1343 asm (" st.l r25,36(sp)");
1344 asm (" st.l r26,40(sp)");
1345 asm (" st.l r27,44(sp)");
1347 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
1348 asm (" fst.q f12,64(sp)"); /* int floating[8] */
1350 /* Fill in the __va_ctl. */
1351 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
1352 asm (" st.l r28,84(sp)"); /* pointer to more args */
1353 asm (" st.l r0, 88(sp)"); /* nfixed */
1354 asm (" st.l r0, 92(sp)"); /* nfloating */
1356 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
1358 asm (" mov r30,sp");
1359 /* recover stack and pass address to start
1361 #endif /* not __PARAGON__ */
1362 #endif /* not __svr4__ */
1363 #else /* not __i860__ */
1365 asm (".global __builtin_saveregs");
1366 asm ("__builtin_saveregs:");
1367 asm (".global ___builtin_saveregs");
1368 asm ("___builtin_saveregs:");
1369 #ifdef NEED_PROC_COMMAND
1372 asm ("st %i0,[%fp+68]");
1373 asm ("st %i1,[%fp+72]");
1374 asm ("st %i2,[%fp+76]");
1375 asm ("st %i3,[%fp+80]");
1376 asm ("st %i4,[%fp+84]");
1378 asm ("st %i5,[%fp+88]");
1379 #ifdef NEED_TYPE_COMMAND
1380 asm (".type __builtin_saveregs,#function");
1381 asm (".size __builtin_saveregs,.-__builtin_saveregs");
1383 #else /* not __sparc__ */
1384 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1387 asm (" .ent __builtin_saveregs");
1388 asm (" .globl __builtin_saveregs");
1389 asm ("__builtin_saveregs:");
1390 asm (" sw $4,0($30)");
1391 asm (" sw $5,4($30)");
1392 asm (" sw $6,8($30)");
1393 asm (" sw $7,12($30)");
1395 asm (" .end __builtin_saveregs");
1396 #else /* not __mips__, etc. */
1399 __builtin_saveregs ()
1404 #endif /* not __mips__ */
1405 #endif /* not __sparc__ */
1406 #endif /* not __i860__ */
1410 #ifndef inhibit_libc
1412 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1414 /* This is used by the `assert' macro. */
1416 __eprintf (string, expression, line, filename)
1418 const char *expression;
1420 const char *filename;
1422 fprintf (stderr, string, expression, line, filename);
1432 /* Structure emitted by -a */
1436 const char *filename;
1440 const unsigned long *addresses;
1442 /* Older GCC's did not emit these fields. */
1444 const char **functions;
1445 const long *line_nums;
1446 const char **filenames;
1449 #ifdef BLOCK_PROFILER_CODE
1452 #ifndef inhibit_libc
1454 /* Simple minded basic block profiling output dumper for
1455 systems that don't provide tcov support. At present,
1456 it requires atexit and stdio. */
1458 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1464 extern int atexit (void (*) (void));
1466 extern void atexit (void (*) (void));
1468 #define ON_EXIT(FUNC,ARG) atexit ((FUNC))
1471 extern void on_exit (void*, void*);
1472 #define ON_EXIT(FUNC,ARG) on_exit ((FUNC), (ARG))
1476 static struct bb *bb_head;
1478 /* Return the number of digits needed to print a value */
1479 /* __inline__ */ static int num_digits (long value, int base)
1481 int minus = (value < 0 && base != 16);
1482 unsigned long v = (minus) ? -value : value;
1496 __bb_exit_func (void)
1498 FILE *file = fopen ("bb.out", "a");
1508 /* This is somewhat type incorrect, but it avoids worrying about
1509 exactly where time.h is included from. It should be ok unless
1510 a void * differs from other pointer formats, or if sizeof(long)
1511 is < sizeof (time_t). It would be nice if we could assume the
1512 use of rationale standards here. */
1514 time((void *) &time_value);
1515 fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value));
1517 /* We check the length field explicitly in order to allow compatibility
1518 with older GCC's which did not provide it. */
1520 for (ptr = bb_head; ptr != (struct bb *)0; ptr = ptr->next)
1523 int func_p = (ptr->nwords >= sizeof (struct bb) && ptr->nwords <= 1000);
1524 int line_p = (func_p && ptr->line_nums);
1525 int file_p = (func_p && ptr->filenames);
1526 long ncounts = ptr->ncounts;
1532 int blk_len = num_digits (ncounts, 10);
1537 fprintf (file, "File %s, %ld basic blocks \n\n",
1538 ptr->filename, ncounts);
1540 /* Get max values for each field. */
1541 for (i = 0; i < ncounts; i++)
1546 if (cnt_max < ptr->counts[i])
1547 cnt_max = ptr->counts[i];
1549 if (addr_max < ptr->addresses[i])
1550 addr_max = ptr->addresses[i];
1552 if (line_p && line_max < ptr->line_nums[i])
1553 line_max = ptr->line_nums[i];
1557 p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>";
1565 p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>";
1572 addr_len = num_digits (addr_max, 16);
1573 cnt_len = num_digits (cnt_max, 10);
1574 line_len = num_digits (line_max, 10);
1576 /* Now print out the basic block information. */
1577 for (i = 0; i < ncounts; i++)
1580 " Block #%*d: executed %*ld time(s) address= 0x%.*lx",
1582 cnt_len, ptr->counts[i],
1583 addr_len, ptr->addresses[i]);
1586 fprintf (file, " function= %-*s", func_len,
1587 (ptr->functions[i]) ? ptr->functions[i] : "<none>");
1590 fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]);
1593 fprintf (file, " file= %s",
1594 (ptr->filenames[i]) ? ptr->filenames[i] : "<none>");
1596 fprintf (file, "\n");
1599 fprintf (file, "\n");
1603 fprintf (file, "\n\n");
1609 __bb_init_func (struct bb *blocks)
1611 /* User is supposed to check whether the first word is non-0,
1612 but just in case.... */
1614 if (blocks->zero_word)
1618 /* Initialize destructor. */
1620 ON_EXIT (__bb_exit_func, 0);
1623 /* Set up linked list. */
1624 blocks->zero_word = 1;
1625 blocks->next = bb_head;
1629 #endif /* not inhibit_libc */
1630 #endif /* not BLOCK_PROFILER_CODE */
1633 /* Default free-store management functions for C++, per sections 12.5 and
1634 17.3.3 of the Working Paper. */
1637 /* operator new (size_t), described in 17.3.3.5. This function is used by
1638 C++ programs to allocate a block of memory to hold a single object. */
1640 typedef void (*vfp)(void);
1641 extern vfp __new_handler;
1642 extern void __default_new_handler (void);
1645 void * __builtin_new (size_t sz)
1646 __attribute__ ((weak, alias ("___builtin_new")));
1648 ___builtin_new (size_t sz)
1651 __builtin_new (size_t sz)
1655 vfp handler = (__new_handler) ? __new_handler : __default_new_handler;
1657 /* malloc (0) is unpredictable; avoid it. */
1660 p = (void *) malloc (sz);
1664 p = (void *) malloc (sz);
1669 #endif /* L_op_new */
1672 /* void * operator new [] (size_t), described in 17.3.3.6. This function
1673 is used by C++ programs to allocate a block of memory for an array. */
1675 extern void * __builtin_new (size_t);
1678 void * __builtin_vec_new (size_t sz)
1679 __attribute__ ((weak, alias ("___builtin_vec_new")));
1681 ___builtin_vec_new (size_t sz)
1684 __builtin_vec_new (size_t sz)
1687 return __builtin_new (sz);
1689 #endif /* L_op_vnew */
1691 #ifdef L_new_handler
1692 /* set_new_handler (fvoid_t *) and the default new handler, described in
1693 17.3.3.2 and 17.3.3.5. These functions define the result of a failure
1694 to allocate the amount of memory requested from operator new or new []. */
1696 #ifndef inhibit_libc
1697 /* This gets us __GNU_LIBRARY__. */
1698 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1701 #ifdef __GNU_LIBRARY__
1702 /* Avoid forcing the library's meaning of `write' on the user program
1703 by using the "internal" name (for use within the library) */
1704 #define write(fd, buf, n) __write((fd), (buf), (n))
1706 #endif /* inhibit_libc */
1708 typedef void (*vfp)(void);
1709 void __default_new_handler (void);
1711 vfp __new_handler = (vfp)0;
1714 set_new_handler (vfp handler)
1718 prev_handler = __new_handler;
1719 if (handler == 0) handler = __default_new_handler;
1720 __new_handler = handler;
1721 return prev_handler;
1724 #define MESSAGE "Virtual memory exceeded in `new'\n"
1727 __default_new_handler ()
1729 #ifndef inhibit_libc
1730 /* don't use fprintf (stderr, ...) because it may need to call malloc. */
1731 /* This should really print the name of the program, but that is hard to
1732 do. We need a standard, clean way to get at the name. */
1733 write (2, MESSAGE, sizeof (MESSAGE));
1735 /* don't call exit () because that may call global destructors which
1736 may cause a loop. */
1742 /* operator delete (void *), described in 17.3.3.3. This function is used
1743 by C++ programs to return to the free store a block of memory allocated
1744 as a single object. */
1747 void __builtin_delete (void *ptr)
1748 __attribute__ ((weak, alias ("___builtin_delete")));
1750 ___builtin_delete (void *ptr)
1753 __builtin_delete (void *ptr)
1762 /* operator delete [] (void *), described in 17.3.3.4. This function is
1763 used by C++ programs to return to the free store a block of memory
1764 allocated as an array. */
1766 extern void __builtin_delete (void *);
1769 void __builtin_vec_delete (void *ptr)
1770 __attribute__ ((weak, alias ("___builtin_vec_delete")));
1772 ___builtin_vec_delete (void *ptr)
1775 __builtin_vec_delete (void *ptr)
1778 __builtin_delete (ptr);
1782 /* End of C++ free-store management functions */
1785 unsigned int __shtab[] = {
1786 0x00000001, 0x00000002, 0x00000004, 0x00000008,
1787 0x00000010, 0x00000020, 0x00000040, 0x00000080,
1788 0x00000100, 0x00000200, 0x00000400, 0x00000800,
1789 0x00001000, 0x00002000, 0x00004000, 0x00008000,
1790 0x00010000, 0x00020000, 0x00040000, 0x00080000,
1791 0x00100000, 0x00200000, 0x00400000, 0x00800000,
1792 0x01000000, 0x02000000, 0x04000000, 0x08000000,
1793 0x10000000, 0x20000000, 0x40000000, 0x80000000
1797 #ifdef L_clear_cache
1798 /* Clear part of an instruction cache. */
1800 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1803 __clear_cache (beg, end)
1806 #ifdef CLEAR_INSN_CACHE
1807 CLEAR_INSN_CACHE (beg, end);
1809 #ifdef INSN_CACHE_SIZE
1810 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1811 static int initialized;
1815 typedef (*function_ptr) ();
1817 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1818 /* It's cheaper to clear the whole cache.
1819 Put in a series of jump instructions so that calling the beginning
1820 of the cache will clear the whole thing. */
1824 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1825 & -INSN_CACHE_LINE_WIDTH);
1826 int end_ptr = ptr + INSN_CACHE_SIZE;
1828 while (ptr < end_ptr)
1830 *(INSTRUCTION_TYPE *)ptr
1831 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1832 ptr += INSN_CACHE_LINE_WIDTH;
1834 *(INSTRUCTION_TYPE *)(ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1839 /* Call the beginning of the sequence. */
1840 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1841 & -INSN_CACHE_LINE_WIDTH))
1844 #else /* Cache is large. */
1848 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1849 & -INSN_CACHE_LINE_WIDTH);
1851 while (ptr < (int) array + sizeof array)
1853 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1854 ptr += INSN_CACHE_LINE_WIDTH;
1860 /* Find the location in array that occupies the same cache line as BEG. */
1862 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1863 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1864 & -INSN_CACHE_PLANE_SIZE)
1867 /* Compute the cache alignment of the place to stop clearing. */
1868 #if 0 /* This is not needed for gcc's purposes. */
1869 /* If the block to clear is bigger than a cache plane,
1870 we clear the entire cache, and OFFSET is already correct. */
1871 if (end < beg + INSN_CACHE_PLANE_SIZE)
1873 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1874 & -INSN_CACHE_LINE_WIDTH)
1875 & (INSN_CACHE_PLANE_SIZE - 1));
1877 #if INSN_CACHE_DEPTH > 1
1878 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1879 if (end_addr <= start_addr)
1880 end_addr += INSN_CACHE_PLANE_SIZE;
1882 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1884 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1885 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1887 while (addr != stop)
1889 /* Call the return instruction at ADDR. */
1890 ((function_ptr) addr) ();
1892 addr += INSN_CACHE_LINE_WIDTH;
1895 #else /* just one plane */
1898 /* Call the return instruction at START_ADDR. */
1899 ((function_ptr) start_addr) ();
1901 start_addr += INSN_CACHE_LINE_WIDTH;
1903 while ((start_addr % INSN_CACHE_SIZE) != offset);
1904 #endif /* just one plane */
1905 #endif /* Cache is large */
1906 #endif /* Cache exists */
1907 #endif /* CLEAR_INSN_CACHE */
1910 #endif /* L_clear_cache */
1914 /* Jump to a trampoline, loading the static chain address. */
1916 #ifdef TRANSFER_FROM_TRAMPOLINE
1917 TRANSFER_FROM_TRAMPOLINE
1920 #if defined (NeXT) && defined (__MACH__)
1922 /* Make stack executable so we can call trampolines on stack.
1923 This is called from INITIALIZE_TRAMPOLINE in next.h. */
1927 #include <mach/mach.h>
1931 __enable_execute_stack (addr)
1935 char *eaddr = addr + TRAMPOLINE_SIZE;
1936 vm_address_t a = (vm_address_t) addr;
1938 /* turn on execute access on stack */
1939 r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
1940 if (r != KERN_SUCCESS)
1942 mach_error("vm_protect VM_PROT_ALL", r);
1946 /* We inline the i-cache invalidation for speed */
1948 #ifdef CLEAR_INSN_CACHE
1949 CLEAR_INSN_CACHE (addr, eaddr);
1951 __clear_cache ((int) addr, (int) eaddr);
1955 #endif /* defined (NeXT) && defined (__MACH__) */
1959 /* Make stack executable so we can call trampolines on stack.
1960 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
1962 #include <sys/mman.h>
1963 #include <sys/vmparam.h>
1964 #include <machine/machparam.h>
1967 __enable_execute_stack ()
1970 static unsigned lowest = USRSTACK;
1971 unsigned current = (unsigned) &fp & -NBPG;
1973 if (lowest > current)
1975 unsigned len = lowest - current;
1976 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
1980 /* Clear instruction cache in case an old trampoline is in it. */
1983 #endif /* __convex__ */
1987 /* Modified from the convex -code above. */
1989 #include <sys/param.h>
1991 #include <sys/m88kbcs.h>
1994 __enable_execute_stack ()
1997 static unsigned long lowest = USRSTACK;
1998 unsigned long current = (unsigned long) &save_errno & -NBPC;
2000 /* Ignore errno being set. memctl sets errno to EINVAL whenever the
2001 address is seen as 'negative'. That is the case with the stack. */
2004 if (lowest > current)
2006 unsigned len=lowest-current;
2007 memctl(current,len,MCT_TEXT);
2011 memctl(current,NBPC,MCT_TEXT);
2015 #endif /* __DOLPHIN__ */
2019 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2021 #include <sys/mman.h>
2022 #include <sys/types.h>
2023 #include <sys/param.h>
2024 #include <sys/vmmac.h>
2026 /* Modified from the convex -code above.
2027 mremap promises to clear the i-cache. */
2030 __enable_execute_stack ()
2033 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
2034 PROT_READ|PROT_WRITE|PROT_EXEC))
2036 perror ("mprotect in __enable_execute_stack");
2041 #endif /* __pyr__ */
2042 #endif /* L_trampoline */
2046 #include "gbl-ctors.h"
2047 /* Some systems use __main in a way incompatible with its use in gcc, in these
2048 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2049 give the same symbol without quotes for an alternative entry point. You
2050 must define both, or neither. */
2052 #define NAME__MAIN "__main"
2053 #define SYMBOL__MAIN __main
2056 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2057 /* Run all the global destructors on exit from the program. */
2060 __do_global_dtors ()
2062 #ifdef DO_GLOBAL_DTORS_BODY
2063 DO_GLOBAL_DTORS_BODY;
2066 for (p = __DTOR_LIST__ + 1; *p; )
2072 #ifndef INIT_SECTION_ASM_OP
2073 /* Run all the global constructors on entry to the program. */
2076 #define ON_EXIT(a, b)
2078 /* Make sure the exit routine is pulled in to define the globals as
2079 bss symbols, just in case the linker does not automatically pull
2080 bss definitions from the library. */
2082 extern int _exit_dummy_decl;
2083 int *_exit_dummy_ref = &_exit_dummy_decl;
2084 #endif /* ON_EXIT */
2087 __do_global_ctors ()
2089 DO_GLOBAL_CTORS_BODY;
2090 ON_EXIT (__do_global_dtors, 0);
2092 #endif /* no INIT_SECTION_ASM_OP */
2094 #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
2095 /* Subroutine called automatically by `main'.
2096 Compiling a global function named `main'
2097 produces an automatic call to this function at the beginning.
2099 For many systems, this routine calls __do_global_ctors.
2100 For systems which support a .init section we use the .init section
2101 to run __do_global_ctors, so we need not do anything here. */
2106 /* Support recursive calls to `main': run initializers just once. */
2107 static int initialized;
2111 __do_global_ctors ();
2114 #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
2116 #endif /* L__main */
2120 #include "gbl-ctors.h"
2122 /* Provide default definitions for the lists of constructors and
2123 destructors, so that we don't get linker errors. These symbols are
2124 intentionally bss symbols, so that gld and/or collect will provide
2125 the right values. */
2127 /* We declare the lists here with two elements each,
2128 so that they are valid empty lists if no other definition is loaded. */
2129 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
2131 /* After 2.3, try this definition on all systems. */
2132 func_ptr __CTOR_LIST__[2] = {0, 0};
2133 func_ptr __DTOR_LIST__[2] = {0, 0};
2135 func_ptr __CTOR_LIST__[2];
2136 func_ptr __DTOR_LIST__[2];
2138 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
2139 #endif /* L_ctors */
2143 #include "gbl-ctors.h"
2147 /* If we have no known way of registering our own __do_global_dtors
2148 routine so that it will be invoked at program exit time, then we
2149 have to define our own exit routine which will get this to happen. */
2151 extern void __do_global_dtors ();
2152 extern void _cleanup ();
2153 extern void _exit () __attribute__ ((noreturn));
2159 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2160 __do_global_dtors ();
2171 int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */
2180 void *exception_handler;
2183 struct exception_table_node {
2184 exception_table *table;
2187 struct exception_table_node *next;
2190 static int except_table_pos;
2191 static void *except_pc;
2192 static struct exception_table_node *exception_table_list;
2194 static exception_table *
2195 find_exception_table (pc)
2198 register struct exception_table_node *table = exception_table_list;
2199 for ( ; table != 0; table = table->next)
2201 if (table->start <= pc && table->end > pc)
2202 return table->table;
2207 /* this routine takes a pc, and the address of the exception handler associated
2208 with the closest exception table handler entry associated with that PC,
2209 or 0 if there are no table entries the PC fits in. The algorithm works
2210 something like this:
2212 while(current_entry exists) {
2213 if(current_entry.start < pc )
2214 current_entry = next_entry;
2216 if(prev_entry.start <= pc && prev_entry.end > pc) {
2217 save pointer to prev_entry;
2218 return prev_entry.exception_handler;
2225 Assuming a correctly sorted table (ascending order) this routine should
2226 return the tightest match...
2228 In the advent of a tie, we have to give the last entry, as it represents
2234 __find_first_exception_table_match(pc)
2237 exception_table *table = find_exception_table (pc);
2243 printf("find_first_exception_table_match(): pc = %x!\n",pc);
2249 /* We can't do this yet, as we don't know that the table is sorted. */
2252 if (table[pos].start > except_pc)
2253 /* found the first table[pos].start > except_pc, so the previous
2254 entry better be the one we want! */
2256 } while(table[pos].exception_handler != (void*)-1);
2259 if (table[pos].start <= except_pc && table[pos].end > except_pc)
2261 except_table_pos = pos;
2263 printf("find_first_eh_table_match(): found match: %x\n",table[pos].exception_handler);
2265 return table[pos].exception_handler;
2268 while (table[++pos].exception_handler != (void*)-1) {
2269 if (table[pos].start <= except_pc && table[pos].end > except_pc)
2271 /* This can apply. Make sure it is better or as good as the previous
2273 /* The best one ends first. */
2274 if (best == 0 || (table[pos].end <= table[best].end
2275 /* The best one starts last. */
2276 && table[pos].start >= table[best].start))
2281 return table[best].exception_handler;
2285 printf("find_first_eh_table_match(): else: returning NULL!\n");
2291 __throw_type_match (void *catch_type, void *throw_type, void* obj)
2294 printf("__throw_type_match (): catch_type = %s, throw_type = %s\n",
2295 catch_type, throw_type);
2297 if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)
2303 __register_exceptions (exception_table *table)
2305 struct exception_table_node *node;
2306 exception_table *range = table + 1;
2308 if (range->start == (void*)-1)
2311 node = (struct exception_table_node*)
2312 malloc (sizeof (struct exception_table_node));
2313 node->table = table;
2315 /* This look can be optimized away either if the table
2316 is sorted, or if we pass in extra parameters. */
2317 node->start = range->start;
2318 node->end = range->end;
2319 for (range++ ; range->start != (void*)(-1); range++)
2321 if (range->start < node->start)
2322 node->start = range->start;
2323 if (range->end > node->end)
2324 node->end = range->end;
2327 node->next = exception_table_list;
2328 exception_table_list = node;
2333 __unwind_function(void *ptr)
2335 asm("movl 8(%esp),%ecx");
2336 /* Undo current frame */
2337 asm("movl %ebp,%esp");
2339 /* like ret, but stay here */
2340 asm("addl $4,%esp");
2342 /* Now, undo previous frame. */
2343 /* This is a test routine, as we have to dynamically probe to find out
2344 what to pop for certain, this is just a guess. */
2345 asm("leal -16(%ebp),%esp");
2346 asm("pop %eax"); /* really for popl %ebx */
2347 asm("pop %eax"); /* really for popl %esi */
2348 asm("pop %eax"); /* really for popl %edi */
2349 asm("movl %ebp,%esp");
2352 asm("movl %ecx,0(%esp)");
2357 #if #machine(rs6000)
2358 __unwind_function(void *ptr)
2367 /* use 31 as a scratch register to restore the link register. */
2368 asm("l 31, 8(1);mtlr 31 # l lr,8(1)");
2371 asm("mtctr 3;bctr # b 3");
2375 #if #machine(powerpc)
2376 __unwind_function(void *ptr)
2380 asm("lwz 31,-4(1)");
2385 /* use 31 as a scratch register to restore the link register. */
2386 asm("lwz 31, 8(1);mtlr 31 # l lr,8(1)");
2387 asm("lwz 31,-4(1)");
2389 asm("mtctr 3;bctr # b 3");
2391 #endif /* powerpc */
2395 #ifndef inhibit_libc
2396 /* This gets us __GNU_LIBRARY__. */
2397 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2400 #ifdef __GNU_LIBRARY__
2401 /* Avoid forcing the library's meaning of `write' on the user program
2402 by using the "internal" name (for use within the library) */
2403 #define write(fd, buf, n) __write((fd), (buf), (n))
2405 #endif /* inhibit_libc */
2407 #define MESSAGE "pure virtual method called\n"
2412 #ifndef inhibit_libc
2413 write (2, MESSAGE, sizeof (MESSAGE) - 1);