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. */
1922 #ifdef TRANSFER_FROM_TRAMPOLINE
1923 TRANSFER_FROM_TRAMPOLINE
1926 #if defined (NeXT) && defined (__MACH__)
1928 /* Make stack executable so we can call trampolines on stack.
1929 This is called from INITIALIZE_TRAMPOLINE in next.h. */
1933 #include <mach/mach.h>
1937 __enable_execute_stack (addr)
1941 char *eaddr = addr + TRAMPOLINE_SIZE;
1942 vm_address_t a = (vm_address_t) addr;
1944 /* turn on execute access on stack */
1945 r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
1946 if (r != KERN_SUCCESS)
1948 mach_error("vm_protect VM_PROT_ALL", r);
1952 /* We inline the i-cache invalidation for speed */
1954 #ifdef CLEAR_INSN_CACHE
1955 CLEAR_INSN_CACHE (addr, eaddr);
1957 __clear_cache ((int) addr, (int) eaddr);
1961 #endif /* defined (NeXT) && defined (__MACH__) */
1965 /* Make stack executable so we can call trampolines on stack.
1966 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
1968 #include <sys/mman.h>
1969 #include <sys/vmparam.h>
1970 #include <machine/machparam.h>
1973 __enable_execute_stack ()
1976 static unsigned lowest = USRSTACK;
1977 unsigned current = (unsigned) &fp & -NBPG;
1979 if (lowest > current)
1981 unsigned len = lowest - current;
1982 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
1986 /* Clear instruction cache in case an old trampoline is in it. */
1989 #endif /* __convex__ */
1993 /* Modified from the convex -code above. */
1995 #include <sys/param.h>
1997 #include <sys/m88kbcs.h>
2000 __enable_execute_stack ()
2003 static unsigned long lowest = USRSTACK;
2004 unsigned long current = (unsigned long) &save_errno & -NBPC;
2006 /* Ignore errno being set. memctl sets errno to EINVAL whenever the
2007 address is seen as 'negative'. That is the case with the stack. */
2010 if (lowest > current)
2012 unsigned len=lowest-current;
2013 memctl(current,len,MCT_TEXT);
2017 memctl(current,NBPC,MCT_TEXT);
2021 #endif /* __DOLPHIN__ */
2025 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2027 #include <sys/mman.h>
2028 #include <sys/types.h>
2029 #include <sys/param.h>
2030 #include <sys/vmmac.h>
2032 /* Modified from the convex -code above.
2033 mremap promises to clear the i-cache. */
2036 __enable_execute_stack ()
2039 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
2040 PROT_READ|PROT_WRITE|PROT_EXEC))
2042 perror ("mprotect in __enable_execute_stack");
2047 #endif /* __pyr__ */
2048 #endif /* L_trampoline */
2052 #include "gbl-ctors.h"
2053 /* Some systems use __main in a way incompatible with its use in gcc, in these
2054 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2055 give the same symbol without quotes for an alternative entry point. You
2056 must define both, or neither. */
2058 #define NAME__MAIN "__main"
2059 #define SYMBOL__MAIN __main
2062 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2063 /* Run all the global destructors on exit from the program. */
2066 __do_global_dtors ()
2068 #ifdef DO_GLOBAL_DTORS_BODY
2069 DO_GLOBAL_DTORS_BODY;
2072 for (p = __DTOR_LIST__ + 1; *p; )
2078 #ifndef INIT_SECTION_ASM_OP
2079 /* Run all the global constructors on entry to the program. */
2082 #define ON_EXIT(a, b)
2084 /* Make sure the exit routine is pulled in to define the globals as
2085 bss symbols, just in case the linker does not automatically pull
2086 bss definitions from the library. */
2088 extern int _exit_dummy_decl;
2089 int *_exit_dummy_ref = &_exit_dummy_decl;
2090 #endif /* ON_EXIT */
2093 __do_global_ctors ()
2095 DO_GLOBAL_CTORS_BODY;
2096 ON_EXIT (__do_global_dtors, 0);
2098 #endif /* no INIT_SECTION_ASM_OP */
2100 #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
2101 /* Subroutine called automatically by `main'.
2102 Compiling a global function named `main'
2103 produces an automatic call to this function at the beginning.
2105 For many systems, this routine calls __do_global_ctors.
2106 For systems which support a .init section we use the .init section
2107 to run __do_global_ctors, so we need not do anything here. */
2112 /* Support recursive calls to `main': run initializers just once. */
2113 static int initialized;
2117 __do_global_ctors ();
2120 #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
2122 #endif /* L__main */
2126 #include "gbl-ctors.h"
2128 /* Provide default definitions for the lists of constructors and
2129 destructors, so that we don't get linker errors. These symbols are
2130 intentionally bss symbols, so that gld and/or collect will provide
2131 the right values. */
2133 /* We declare the lists here with two elements each,
2134 so that they are valid empty lists if no other definition is loaded. */
2135 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
2137 /* After 2.3, try this definition on all systems. */
2138 func_ptr __CTOR_LIST__[2] = {0, 0};
2139 func_ptr __DTOR_LIST__[2] = {0, 0};
2141 func_ptr __CTOR_LIST__[2];
2142 func_ptr __DTOR_LIST__[2];
2144 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
2145 #endif /* L_ctors */
2149 #include "gbl-ctors.h"
2153 /* If we have no known way of registering our own __do_global_dtors
2154 routine so that it will be invoked at program exit time, then we
2155 have to define our own exit routine which will get this to happen. */
2157 extern void __do_global_dtors ();
2158 extern void _cleanup ();
2159 extern void _exit () __attribute__ ((noreturn));
2165 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2166 __do_global_dtors ();
2177 int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */
2186 void *exception_handler;
2189 struct exception_table_node {
2190 exception_table *table;
2193 struct exception_table_node *next;
2196 static int except_table_pos;
2197 static void *except_pc;
2198 static struct exception_table_node *exception_table_list;
2200 static exception_table *
2201 find_exception_table (pc)
2204 register struct exception_table_node *table = exception_table_list;
2205 for ( ; table != 0; table = table->next)
2207 if (table->start <= pc && table->end > pc)
2208 return table->table;
2213 /* this routine takes a pc, and the address of the exception handler associated
2214 with the closest exception table handler entry associated with that PC,
2215 or 0 if there are no table entries the PC fits in. The algorithm works
2216 something like this:
2218 while(current_entry exists) {
2219 if(current_entry.start < pc )
2220 current_entry = next_entry;
2222 if(prev_entry.start <= pc && prev_entry.end > pc) {
2223 save pointer to prev_entry;
2224 return prev_entry.exception_handler;
2231 Assuming a correctly sorted table (ascending order) this routine should
2232 return the tightest match...
2234 In the advent of a tie, we have to give the last entry, as it represents
2240 __find_first_exception_table_match(pc)
2243 exception_table *table = find_exception_table (pc);
2249 printf("find_first_exception_table_match(): pc = %x!\n",pc);
2255 /* We can't do this yet, as we don't know that the table is sorted. */
2258 if (table[pos].start > except_pc)
2259 /* found the first table[pos].start > except_pc, so the previous
2260 entry better be the one we want! */
2262 } while(table[pos].exception_handler != (void*)-1);
2265 if (table[pos].start <= except_pc && table[pos].end > except_pc)
2267 except_table_pos = pos;
2269 printf("find_first_eh_table_match(): found match: %x\n",table[pos].exception_handler);
2271 return table[pos].exception_handler;
2274 while (table[++pos].exception_handler != (void*)-1) {
2275 if (table[pos].start <= except_pc && table[pos].end > except_pc)
2277 /* This can apply. Make sure it is better or as good as the previous
2279 /* The best one ends first. */
2280 if (best == 0 || (table[pos].end <= table[best].end
2281 /* The best one starts last. */
2282 && table[pos].start >= table[best].start))
2287 return table[best].exception_handler;
2291 printf("find_first_eh_table_match(): else: returning NULL!\n");
2297 __throw_type_match (void *catch_type, void *throw_type, void* obj)
2300 printf("__throw_type_match (): catch_type = %s, throw_type = %s\n",
2301 catch_type, throw_type);
2303 if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)
2309 __register_exceptions (exception_table *table)
2311 struct exception_table_node *node;
2312 exception_table *range = table + 1;
2314 if (range->start == (void*)-1)
2317 node = (struct exception_table_node*)
2318 malloc (sizeof (struct exception_table_node));
2319 node->table = table;
2321 /* This look can be optimized away either if the table
2322 is sorted, or if we pass in extra parameters. */
2323 node->start = range->start;
2324 node->end = range->end;
2325 for (range++ ; range->start != (void*)(-1); range++)
2327 if (range->start < node->start)
2328 node->start = range->start;
2329 if (range->end > node->end)
2330 node->end = range->end;
2333 node->next = exception_table_list;
2334 exception_table_list = node;
2339 __unwind_function(void *ptr)
2341 asm("movl 8(%esp),%ecx");
2342 /* Undo current frame */
2343 asm("movl %ebp,%esp");
2345 /* like ret, but stay here */
2346 asm("addl $4,%esp");
2348 /* Now, undo previous frame. */
2349 /* This is a test routine, as we have to dynamically probe to find out
2350 what to pop for certain, this is just a guess. */
2351 asm("leal -16(%ebp),%esp");
2355 asm("movl %ebp,%esp");
2358 asm("movl %ecx,0(%esp)");
2361 #elif #machine(rs6000)
2362 __unwind_function(void *ptr)
2371 /* use 31 as a scratch register to restore the link register. */
2372 asm("l 31, 8(1);mtlr 31 # l lr,8(1)");
2375 asm("mtctr 3;bctr # b 3");
2377 #elif #machine(powerpc)
2378 __unwind_function(void *ptr)
2382 asm("lwz 31,-4(1)");
2387 /* use 31 as a scratch register to restore the link register. */
2388 asm("lwz 31, 8(1);mtlr 31 # l lr,8(1)");
2389 asm("lwz 31,-4(1)");
2391 asm("mtctr 3;bctr # b 3");
2394 __unwind_function(void *ptr)
2398 #endif /* powerpc */
2402 #ifndef inhibit_libc
2403 /* This gets us __GNU_LIBRARY__. */
2404 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2407 #ifdef __GNU_LIBRARY__
2408 /* Avoid forcing the library's meaning of `write' on the user program
2409 by using the "internal" name (for use within the library) */
2410 #define write(fd, buf, n) __write((fd), (buf), (n))
2412 #endif /* inhibit_libc */
2414 #define MESSAGE "pure virtual method called\n"
2419 #ifndef inhibit_libc
2420 write (2, MESSAGE, sizeof (MESSAGE) - 1);