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, 675 Mass Ave, Cambridge, MA 02139, USA. */
21 /* As a special exception, if you link this library with other files,
22 some of which are compiled with GCC, to produce an executable,
23 this library does not by itself cause the resulting executable
24 to be covered by the GNU General Public License.
25 This exception does not however invalidate any other reasons why
26 the executable file might be covered by the GNU General Public License. */
28 /* It is incorrect to include config.h here, because this file is being
29 compiled for the target, and hence definitions concerning only the host
38 /* Don't use `fancy_abort' here even if config.h says to use it. */
43 /* Permit the tm.h file to select the endianness to use just for this
44 file. This is used when the endianness is determined when the
47 #ifndef LIBGCC2_WORDS_BIG_ENDIAN
48 #define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
51 /* In the first part of this file, we are interfacing to calls generated
52 by the compiler itself. These calls pass values into these routines
53 which have very specific modes (rather than very specific types), and
54 these compiler-generated calls also expect any return values to have
55 very specific modes (rather than very specific types). Thus, we need
56 to avoid using regular C language type names in this part of the file
57 because the sizes for those types can be configured to be anything.
58 Instead we use the following special type names. */
60 typedef unsigned int UQItype __attribute__ ((mode (QI)));
61 typedef int SItype __attribute__ ((mode (SI)));
62 typedef unsigned int USItype __attribute__ ((mode (SI)));
63 typedef int DItype __attribute__ ((mode (DI)));
64 typedef unsigned int UDItype __attribute__ ((mode (DI)));
66 typedef float SFtype __attribute__ ((mode (SF)));
67 typedef float DFtype __attribute__ ((mode (DF)));
69 #if LONG_DOUBLE_TYPE_SIZE == 96
70 typedef float XFtype __attribute__ ((mode (XF)));
72 #if LONG_DOUBLE_TYPE_SIZE == 128
73 typedef float TFtype __attribute__ ((mode (TF)));
76 typedef int word_type __attribute__ ((mode (__word__)));
78 /* Make sure that we don't accidentally use any normal C language built-in
79 type names in the first part of this file. Instead we want to use *only*
80 the type names defined above. The following macro definitions insure
81 that if we *do* accidentally use some normal C language built-in type name,
82 we will get a syntax error. */
84 #define char bogus_type
85 #define short bogus_type
86 #define int bogus_type
87 #define long bogus_type
88 #define unsigned bogus_type
89 #define float bogus_type
90 #define double bogus_type
92 #define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
94 /* DIstructs are pairs of SItype values in the order determined by
95 LIBGCC2_WORDS_BIG_ENDIAN. */
97 #if LIBGCC2_WORDS_BIG_ENDIAN
98 struct DIstruct {SItype high, low;};
100 struct DIstruct {SItype low, high;};
103 /* We need this union to unpack/pack DImode values, since we don't have
104 any arithmetic yet. Incoming DImode parameters are stored into the
105 `ll' field, and the unpacked result is read from the struct `s'. */
113 #if defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_w_sdiv)
115 #include "longlong.h"
117 #endif /* udiv or mul */
119 extern DItype __fixunssfdi (SFtype a);
120 extern DItype __fixunsdfdi (DFtype a);
121 #if LONG_DOUBLE_TYPE_SIZE == 96
122 extern DItype __fixunsxfdi (XFtype a);
124 #if LONG_DOUBLE_TYPE_SIZE == 128
125 extern DItype __fixunstfdi (TFtype a);
128 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
129 #if defined (L_divdi3) || defined (L_moddi3)
142 w.s.high = -uu.s.high - ((USItype) w.s.low > 0);
163 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
167 w.s.low = (USItype)uu.s.high >> -bm;
171 USItype carries = (USItype)uu.s.high << bm;
172 w.s.high = (USItype)uu.s.high >> b;
173 w.s.low = ((USItype)uu.s.low >> b) | carries;
195 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
199 w.s.high = (USItype)uu.s.low << -bm;
203 USItype carries = (USItype)uu.s.low >> bm;
204 w.s.low = (USItype)uu.s.low << b;
205 w.s.high = ((USItype)uu.s.high << b) | carries;
227 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
230 /* w.s.high = 1..1 or 0..0 */
231 w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
232 w.s.low = uu.s.high >> -bm;
236 USItype carries = (USItype)uu.s.high << bm;
237 w.s.high = uu.s.high >> b;
238 w.s.low = ((USItype)uu.s.low >> b) | carries;
253 w.s.low = ffs (uu.s.low);
256 w.s.low = ffs (uu.s.high);
259 w.s.low += BITS_PER_UNIT * sizeof (SItype);
277 w.ll = __umulsidi3 (uu.s.low, vv.s.low);
278 w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
279 + (USItype) uu.s.high * (USItype) vv.s.low);
287 __udiv_w_sdiv (rp, a1, a0, d)
288 USItype *rp, a1, a0, d;
295 if (a1 < d - a1 - (a0 >> (SI_TYPE_SIZE - 1)))
297 /* dividend, divisor, and quotient are nonnegative */
298 sdiv_qrnnd (q, r, a1, a0, d);
302 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
303 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (SI_TYPE_SIZE - 1));
304 /* Divide (c1*2^32 + c0) by d */
305 sdiv_qrnnd (q, r, c1, c0, d);
306 /* Add 2^31 to quotient */
307 q += (USItype) 1 << (SI_TYPE_SIZE - 1);
312 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
313 c1 = a1 >> 1; /* A/2 */
314 c0 = (a1 << (SI_TYPE_SIZE - 1)) + (a0 >> 1);
316 if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
318 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
320 r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
337 else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
340 c0 = ~c0; /* logical NOT */
342 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
344 q = ~q; /* (A/2)/b1 */
347 r = 2*r + (a0 & 1); /* A/(2*b1) */
365 else /* Implies c1 = b1 */
366 { /* Hence a1 = d - 1 = 2*b1 - 1 */
386 static const UQItype __clz_tab[] =
388 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,
389 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,
390 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,
391 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,
392 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,
393 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,
394 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,
395 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,
399 __udivmoddi4 (n, d, rp)
406 USItype d0, d1, n0, n1, n2;
418 #if !UDIV_NEEDS_NORMALIZATION
425 udiv_qrnnd (q0, n0, n1, n0, d0);
428 /* Remainder in n0. */
435 d0 = 1 / d0; /* Divide intentionally by zero. */
437 udiv_qrnnd (q1, n1, 0, n1, d0);
438 udiv_qrnnd (q0, n0, n1, n0, d0);
440 /* Remainder in n0. */
451 #else /* UDIV_NEEDS_NORMALIZATION */
459 count_leading_zeros (bm, d0);
463 /* Normalize, i.e. make the most significant bit of the
467 n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
471 udiv_qrnnd (q0, n0, n1, n0, d0);
474 /* Remainder in n0 >> bm. */
481 d0 = 1 / d0; /* Divide intentionally by zero. */
483 count_leading_zeros (bm, d0);
487 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
488 conclude (the most significant bit of n1 is set) /\ (the
489 leading quotient digit q1 = 1).
491 This special case is necessary, not an optimization.
492 (Shifts counts of SI_TYPE_SIZE are undefined.) */
501 b = SI_TYPE_SIZE - bm;
505 n1 = (n1 << bm) | (n0 >> b);
508 udiv_qrnnd (q1, n1, n2, n1, d0);
513 udiv_qrnnd (q0, n0, n1, n0, d0);
515 /* Remainder in n0 >> bm. */
525 #endif /* UDIV_NEEDS_NORMALIZATION */
536 /* Remainder in n1n0. */
548 count_leading_zeros (bm, d1);
551 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
552 conclude (the most significant bit of n1 is set) /\ (the
553 quotient digit q0 = 0 or 1).
555 This special case is necessary, not an optimization. */
557 /* The condition on the next line takes advantage of that
558 n1 >= d1 (true due to program flow). */
559 if (n1 > d1 || n0 >= d0)
562 sub_ddmmss (n1, n0, n1, n0, d1, d0);
581 b = SI_TYPE_SIZE - bm;
583 d1 = (d1 << bm) | (d0 >> b);
586 n1 = (n1 << bm) | (n0 >> b);
589 udiv_qrnnd (q0, n1, n2, n1, d1);
590 umul_ppmm (m1, m0, q0, d0);
592 if (m1 > n1 || (m1 == n1 && m0 > n0))
595 sub_ddmmss (m1, m0, m1, m0, d1, d0);
600 /* Remainder in (n1n0 - m1m0) >> bm. */
603 sub_ddmmss (n1, n0, n1, n0, m1, m0);
604 rr.s.low = (n1 << b) | (n0 >> bm);
605 rr.s.high = n1 >> bm;
619 UDItype __udivmoddi4 ();
634 uu.ll = __negdi2 (uu.ll);
637 vv.ll = __negdi2 (vv.ll);
639 w = __udivmoddi4 (uu.ll, vv.ll, (UDItype *) 0);
648 UDItype __udivmoddi4 ();
662 uu.ll = __negdi2 (uu.ll);
664 vv.ll = __negdi2 (vv.ll);
666 (void) __udivmoddi4 (uu.ll, vv.ll, &w);
675 UDItype __udivmoddi4 ();
682 (void) __udivmoddi4 (u, v, &w);
689 UDItype __udivmoddi4 ();
694 return __udivmoddi4 (n, d, (UDItype *) 0);
705 au.ll = a, bu.ll = b;
707 if (au.s.high < bu.s.high)
709 else if (au.s.high > bu.s.high)
711 if ((USItype) au.s.low < (USItype) bu.s.low)
713 else if ((USItype) au.s.low > (USItype) bu.s.low)
726 au.ll = a, bu.ll = b;
728 if ((USItype) au.s.high < (USItype) bu.s.high)
730 else if ((USItype) au.s.high > (USItype) bu.s.high)
732 if ((USItype) au.s.low < (USItype) bu.s.low)
734 else if ((USItype) au.s.low > (USItype) bu.s.low)
740 #if defined(L_fixunstfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
741 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
742 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
754 /* Compute high word of result, as a flonum. */
755 b = (a / HIGH_WORD_COEFF);
756 /* Convert that to fixed (but not to DItype!),
757 and shift it into the high word. */
760 /* Remove high part from the TFtype, leaving the low part as flonum. */
762 /* Convert that to fixed (but not to DItype!) and add it in.
763 Sometimes A comes out negative. This is significant, since
764 A has more bits than a long int does. */
766 v -= (USItype) (- a);
773 #if defined(L_fixtfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
779 return - __fixunstfdi (-a);
780 return __fixunstfdi (a);
784 #if defined(L_fixunsxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
785 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
786 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
798 /* Compute high word of result, as a flonum. */
799 b = (a / HIGH_WORD_COEFF);
800 /* Convert that to fixed (but not to DItype!),
801 and shift it into the high word. */
804 /* Remove high part from the XFtype, leaving the low part as flonum. */
806 /* Convert that to fixed (but not to DItype!) and add it in.
807 Sometimes A comes out negative. This is significant, since
808 A has more bits than a long int does. */
810 v -= (USItype) (- a);
817 #if defined(L_fixxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
823 return - __fixunsxfdi (-a);
824 return __fixunsxfdi (a);
829 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
830 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
842 /* Compute high word of result, as a flonum. */
843 b = (a / HIGH_WORD_COEFF);
844 /* Convert that to fixed (but not to DItype!),
845 and shift it into the high word. */
848 /* Remove high part from the DFtype, leaving the low part as flonum. */
850 /* Convert that to fixed (but not to DItype!) and add it in.
851 Sometimes A comes out negative. This is significant, since
852 A has more bits than a long int does. */
854 v -= (USItype) (- a);
867 return - __fixunsdfdi (-a);
868 return __fixunsdfdi (a);
873 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
874 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
877 __fixunssfdi (SFtype original_a)
879 /* Convert the SFtype to a DFtype, because that is surely not going
880 to lose any bits. Some day someone else can write a faster version
881 that avoids converting to DFtype, and verify it really works right. */
882 DFtype a = original_a;
889 /* Compute high word of result, as a flonum. */
890 b = (a / HIGH_WORD_COEFF);
891 /* Convert that to fixed (but not to DItype!),
892 and shift it into the high word. */
895 /* Remove high part from the DFtype, leaving the low part as flonum. */
897 /* Convert that to fixed (but not to DItype!) and add it in.
898 Sometimes A comes out negative. This is significant, since
899 A has more bits than a long int does. */
901 v -= (USItype) (- a);
913 return - __fixunssfdi (-a);
914 return __fixunssfdi (a);
918 #if defined(L_floatdixf) && (LONG_DOUBLE_TYPE_SIZE == 96)
919 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
920 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
921 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
933 d = (USItype) (u >> WORD_SIZE);
934 d *= HIGH_HALFWORD_COEFF;
935 d *= HIGH_HALFWORD_COEFF;
936 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
938 return (negate ? -d : d);
942 #if defined(L_floatditf) && (LONG_DOUBLE_TYPE_SIZE == 128)
943 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
944 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
945 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
957 d = (USItype) (u >> WORD_SIZE);
958 d *= HIGH_HALFWORD_COEFF;
959 d *= HIGH_HALFWORD_COEFF;
960 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
962 return (negate ? -d : d);
967 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
968 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
969 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
981 d = (USItype) (u >> WORD_SIZE);
982 d *= HIGH_HALFWORD_COEFF;
983 d *= HIGH_HALFWORD_COEFF;
984 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
986 return (negate ? -d : d);
991 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
992 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
993 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
994 #define DI_SIZE (sizeof (DItype) * BITS_PER_UNIT)
995 #if TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
999 #if TARGET_FLOAT_FORMAT == IBM_FLOAT_FORMAT
1003 #if TARGET_FLOAT_FORMAT == VAX_FLOAT_FORMAT
1018 /* Do the calculation in DFmode
1019 so that we don't lose any of the precision of the high word
1020 while multiplying it. */
1027 /* Protect against double-rounding error.
1028 Represent any low-order bits, that might be truncated in DFmode,
1029 by a bit that won't be lost. The bit can go in anywhere below the
1030 rounding position of the SFmode. A fixed mask and bit position
1031 handles all usual configurations. It doesn't handle the case
1032 of 128-bit DImode, however. */
1033 if (DF_SIZE < DI_SIZE
1034 && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1036 #define REP_BIT ((USItype) 1 << (DI_SIZE - DF_SIZE))
1037 if (u >= ((UDItype) 1 << DF_SIZE))
1039 if ((USItype) u & (REP_BIT - 1))
1043 f = (USItype) (u >> WORD_SIZE);
1044 f *= HIGH_HALFWORD_COEFF;
1045 f *= HIGH_HALFWORD_COEFF;
1046 f += (USItype) (u & (HIGH_WORD_COEFF - 1));
1048 return (SFtype) (negate ? -f : f);
1052 #if defined(L_fixunsxfsi) && LONG_DOUBLE_TYPE_SIZE == 96
1053 /* Reenable the normal types, in case limits.h needs them. */
1067 if (a >= - (DFtype) LONG_MIN)
1068 return (SItype) (a + LONG_MIN) - LONG_MIN;
1074 /* Reenable the normal types, in case limits.h needs them. */
1088 if (a >= - (DFtype) LONG_MIN)
1089 return (SItype) (a + LONG_MIN) - LONG_MIN;
1095 /* Reenable the normal types, in case limits.h needs them. */
1106 __fixunssfsi (SFtype a)
1108 if (a >= - (SFtype) LONG_MIN)
1109 return (SItype) (a + LONG_MIN) - LONG_MIN;
1114 /* From here on down, the routines use normal data types. */
1116 #define SItype bogus_type
1117 #define USItype bogus_type
1118 #define DItype bogus_type
1119 #define UDItype bogus_type
1120 #define SFtype bogus_type
1121 #define DFtype bogus_type
1133 /* Like bcmp except the sign is meaningful.
1134 Reult is negative if S1 is less than S2,
1135 positive if S1 is greater, 0 if S1 and S2 are equal. */
1138 __gcc_bcmp (s1, s2, size)
1139 unsigned char *s1, *s2;
1144 unsigned char c1 = *s1++, c2 = *s2++;
1156 #if defined(__svr4__) || defined(__alliant__)
1160 /* The Alliant needs the added underscore. */
1161 asm (".globl __builtin_saveregs");
1162 asm ("__builtin_saveregs:");
1163 asm (".globl ___builtin_saveregs");
1164 asm ("___builtin_saveregs:");
1166 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
1167 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
1168 area and also for a new va_list
1170 /* Save all argument registers in the arg reg save area. The
1171 arg reg save area must have the following layout (according
1183 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
1184 asm (" fst.q %f12,16(%sp)");
1186 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
1187 asm (" st.l %r17,36(%sp)");
1188 asm (" st.l %r18,40(%sp)");
1189 asm (" st.l %r19,44(%sp)");
1190 asm (" st.l %r20,48(%sp)");
1191 asm (" st.l %r21,52(%sp)");
1192 asm (" st.l %r22,56(%sp)");
1193 asm (" st.l %r23,60(%sp)");
1194 asm (" st.l %r24,64(%sp)");
1195 asm (" st.l %r25,68(%sp)");
1196 asm (" st.l %r26,72(%sp)");
1197 asm (" st.l %r27,76(%sp)");
1199 asm (" adds 80,%sp,%r16"); /* compute the address of the new
1200 va_list structure. Put in into
1201 r16 so that it will be returned
1204 /* Initialize all fields of the new va_list structure. This
1205 structure looks like:
1208 unsigned long ireg_used;
1209 unsigned long freg_used;
1215 asm (" st.l %r0, 0(%r16)"); /* nfixed */
1216 asm (" st.l %r0, 4(%r16)"); /* nfloating */
1217 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
1218 asm (" bri %r1"); /* delayed return */
1219 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
1221 #else /* not __svr4__ */
1222 #if defined(__PARAGON__)
1224 * we'll use SVR4-ish varargs but need SVR3.2 assembler syntax,
1225 * and we stand a better chance of hooking into libraries
1226 * compiled by PGI. [andyp@ssd.intel.com]
1230 asm (".globl __builtin_saveregs");
1231 asm ("__builtin_saveregs:");
1232 asm (".globl ___builtin_saveregs");
1233 asm ("___builtin_saveregs:");
1235 asm (" andnot 0x0f,sp,sp"); /* round down to 16-byte boundary */
1236 asm (" adds -96,sp,sp"); /* allocate stack space for reg save
1237 area and also for a new va_list
1239 /* Save all argument registers in the arg reg save area. The
1240 arg reg save area must have the following layout (according
1252 asm (" fst.q f8, 0(sp)");
1253 asm (" fst.q f12,16(sp)");
1254 asm (" st.l r16,32(sp)");
1255 asm (" st.l r17,36(sp)");
1256 asm (" st.l r18,40(sp)");
1257 asm (" st.l r19,44(sp)");
1258 asm (" st.l r20,48(sp)");
1259 asm (" st.l r21,52(sp)");
1260 asm (" st.l r22,56(sp)");
1261 asm (" st.l r23,60(sp)");
1262 asm (" st.l r24,64(sp)");
1263 asm (" st.l r25,68(sp)");
1264 asm (" st.l r26,72(sp)");
1265 asm (" st.l r27,76(sp)");
1267 asm (" adds 80,sp,r16"); /* compute the address of the new
1268 va_list structure. Put in into
1269 r16 so that it will be returned
1272 /* Initialize all fields of the new va_list structure. This
1273 structure looks like:
1276 unsigned long ireg_used;
1277 unsigned long freg_used;
1283 asm (" st.l r0, 0(r16)"); /* nfixed */
1284 asm (" st.l r0, 4(r16)"); /* nfloating */
1285 asm (" st.l sp, 8(r16)"); /* __va_ctl points to __va_struct. */
1286 asm (" bri r1"); /* delayed return */
1287 asm (" st.l r28,12(r16)"); /* pointer to overflow args */
1288 #else /* not __PARAGON__ */
1292 asm (".globl ___builtin_saveregs");
1293 asm ("___builtin_saveregs:");
1294 asm (" mov sp,r30");
1295 asm (" andnot 0x0f,sp,sp");
1296 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
1298 /* Fill in the __va_struct. */
1299 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
1300 asm (" st.l r17, 4(sp)"); /* int fixed[12] */
1301 asm (" st.l r18, 8(sp)");
1302 asm (" st.l r19,12(sp)");
1303 asm (" st.l r20,16(sp)");
1304 asm (" st.l r21,20(sp)");
1305 asm (" st.l r22,24(sp)");
1306 asm (" st.l r23,28(sp)");
1307 asm (" st.l r24,32(sp)");
1308 asm (" st.l r25,36(sp)");
1309 asm (" st.l r26,40(sp)");
1310 asm (" st.l r27,44(sp)");
1312 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
1313 asm (" fst.q f12,64(sp)"); /* int floating[8] */
1315 /* Fill in the __va_ctl. */
1316 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
1317 asm (" st.l r28,84(sp)"); /* pointer to more args */
1318 asm (" st.l r0, 88(sp)"); /* nfixed */
1319 asm (" st.l r0, 92(sp)"); /* nfloating */
1321 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
1323 asm (" mov r30,sp");
1324 /* recover stack and pass address to start
1326 #endif /* not __PARAGON__ */
1327 #endif /* not __svr4__ */
1328 #else /* not __i860__ */
1330 asm (".global __builtin_saveregs");
1331 asm ("__builtin_saveregs:");
1332 asm (".global ___builtin_saveregs");
1333 asm ("___builtin_saveregs:");
1334 #ifdef NEED_PROC_COMMAND
1337 asm ("st %i0,[%fp+68]");
1338 asm ("st %i1,[%fp+72]");
1339 asm ("st %i2,[%fp+76]");
1340 asm ("st %i3,[%fp+80]");
1341 asm ("st %i4,[%fp+84]");
1343 asm ("st %i5,[%fp+88]");
1344 #ifdef NEED_TYPE_COMMAND
1345 asm (".type __builtin_saveregs,#function");
1346 asm (".size __builtin_saveregs,.-__builtin_saveregs");
1348 #else /* not __sparc__ */
1349 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1352 asm (" .ent __builtin_saveregs");
1353 asm (" .globl __builtin_saveregs");
1354 asm ("__builtin_saveregs:");
1355 asm (" sw $4,0($30)");
1356 asm (" sw $5,4($30)");
1357 asm (" sw $6,8($30)");
1358 asm (" sw $7,12($30)");
1360 asm (" .end __builtin_saveregs");
1361 #else /* not __mips__, etc. */
1364 __builtin_saveregs ()
1369 #endif /* not __mips__ */
1370 #endif /* not __sparc__ */
1371 #endif /* not __i860__ */
1375 #ifndef inhibit_libc
1377 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1379 /* This is used by the `assert' macro. */
1381 __eprintf (string, expression, line, filename)
1383 const char *expression;
1385 const char *filename;
1387 fprintf (stderr, string, expression, line, filename);
1397 /* Structure emitted by -a */
1401 const char *filename;
1405 const unsigned long *addresses;
1407 /* Older GCC's did not emit these fields. */
1409 const char **functions;
1410 const long *line_nums;
1411 const char **filenames;
1414 #ifdef BLOCK_PROFILER_CODE
1417 #ifndef inhibit_libc
1419 /* Simple minded basic block profiling output dumper for
1420 systems that don't provde tcov support. At present,
1421 it requires atexit and stdio. */
1423 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1428 extern void atexit (void (*) (void));
1429 #define ON_EXIT(FUNC,ARG) atexit ((FUNC))
1432 extern void on_exit (void*, void*);
1433 #define ON_EXIT(FUNC,ARG) on_exit ((FUNC), (ARG))
1437 static struct bb *bb_head = (struct bb *)0;
1439 /* Return the number of digits needed to print a value */
1440 /* __inline__ */ static int num_digits (long value, int base)
1442 int minus = (value < 0 && base != 16);
1443 unsigned long v = (minus) ? -value : value;
1457 __bb_exit_func (void)
1459 FILE *file = fopen ("bb.out", "a");
1469 /* This is somewhat type incorrect, but it avoids worrying about
1470 exactly where time.h is included from. It should be ok unless
1471 a void * differs from other pointer formats, or if sizeof(long)
1472 is < sizeof (time_t). It would be nice if we could assume the
1473 use of rationale standards here. */
1475 time((void *) &time_value);
1476 fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value));
1478 /* We check the length field explicitly in order to allow compatibility
1479 with older GCC's which did not provide it. */
1481 for (ptr = bb_head; ptr != (struct bb *)0; ptr = ptr->next)
1484 int func_p = (ptr->nwords >= sizeof (struct bb) && ptr->nwords <= 1000);
1485 int line_p = (func_p && ptr->line_nums);
1486 int file_p = (func_p && ptr->filenames);
1487 long ncounts = ptr->ncounts;
1493 int blk_len = num_digits (ncounts, 10);
1498 fprintf (file, "File %s, %ld basic blocks \n\n",
1499 ptr->filename, ncounts);
1501 /* Get max values for each field. */
1502 for (i = 0; i < ncounts; i++)
1507 if (cnt_max < ptr->counts[i])
1508 cnt_max = ptr->counts[i];
1510 if (addr_max < ptr->addresses[i])
1511 addr_max = ptr->addresses[i];
1513 if (line_p && line_max < ptr->line_nums[i])
1514 line_max = ptr->line_nums[i];
1518 p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>";
1526 p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>";
1533 addr_len = num_digits (addr_max, 16);
1534 cnt_len = num_digits (cnt_max, 10);
1535 line_len = num_digits (line_max, 10);
1537 /* Now print out the basic block information. */
1538 for (i = 0; i < ncounts; i++)
1541 " Block #%*d: executed %*ld time(s) address= 0x%.*lx",
1543 cnt_len, ptr->counts[i],
1544 addr_len, ptr->addresses[i]);
1547 fprintf (file, " function= %-*s", func_len,
1548 (ptr->functions[i]) ? ptr->functions[i] : "<none>");
1551 fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]);
1554 fprintf (file, " file= %s",
1555 (ptr->filenames[i]) ? ptr->filenames[i] : "<none>");
1557 fprintf (file, "\n");
1560 fprintf (file, "\n");
1564 fprintf (file, "\n\n");
1570 __bb_init_func (struct bb *blocks)
1572 /* User is supposed to check whether the first word is non-0,
1573 but just in case.... */
1575 if (blocks->zero_word)
1579 /* Initialize destructor. */
1581 ON_EXIT (__bb_exit_func, 0);
1584 /* Set up linked list. */
1585 blocks->zero_word = 1;
1586 blocks->next = bb_head;
1590 #endif /* not inhibit_libc */
1591 #endif /* not BLOCK_PROFILER_CODE */
1594 /* Default free-store management functions for C++, per sections 12.5 and
1595 17.3.3 of the Working Paper. */
1598 /* operator new (size_t), described in 17.3.3.5. This function is used by
1599 C++ programs to allocate a block of memory to hold a single object. */
1601 typedef void (*vfp)(void);
1602 extern vfp __new_handler;
1605 __builtin_new (size_t sz)
1609 /* malloc (0) is unpredictable; avoid it. */
1612 p = (void *) malloc (sz);
1615 (*__new_handler) ();
1616 p = (void *) malloc (sz);
1621 #endif /* L_op_new */
1624 /* void * operator new [] (size_t), described in 17.3.3.6. This function
1625 is used by C++ programs to allocate a block of memory for an array. */
1627 extern void * __builtin_new (size_t);
1630 __builtin_vec_new (size_t sz)
1632 return __builtin_new (sz);
1634 #endif /* L_op_vnew */
1636 #ifdef L_new_handler
1637 /* set_new_handler (fvoid_t *) and the default new handler, described in
1638 17.3.3.2 and 17.3.3.5. These functions define the result of a failure
1639 to allocate the amount of memory requested from operator new or new []. */
1641 #ifndef inhibit_libc
1642 /* This gets us __GNU_LIBRARY__. */
1643 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1646 #ifdef __GNU_LIBRARY__
1647 /* Avoid forcing the library's meaning of `write' on the user program
1648 by using the "internal" name (for use within the library) */
1649 #define write(fd, buf, n) __write((fd), (buf), (n))
1651 #endif /* inhibit_libc */
1653 typedef void (*vfp)(void);
1654 void __default_new_handler (void);
1656 vfp __new_handler = __default_new_handler;
1659 set_new_handler (vfp handler)
1663 prev_handler = __new_handler;
1664 if (handler == 0) handler = __default_new_handler;
1665 __new_handler = handler;
1666 return prev_handler;
1669 #define MESSAGE "Virtual memory exceeded in `new'\n"
1672 __default_new_handler ()
1674 #ifndef inhibit_libc
1675 /* don't use fprintf (stderr, ...) because it may need to call malloc. */
1676 /* This should really print the name of the program, but that is hard to
1677 do. We need a standard, clean way to get at the name. */
1678 write (2, MESSAGE, sizeof (MESSAGE));
1680 /* don't call exit () because that may call global destructors which
1681 may cause a loop. */
1687 /* operator delete (void *), described in 17.3.3.3. This function is used
1688 by C++ programs to return to the free store a block of memory allocated
1689 as a single object. */
1692 __builtin_delete (void *ptr)
1700 /* operator delete [] (void *), described in 17.3.3.4. This function is
1701 used by C++ programs to return to the free store a block of memory
1702 allocated as an array. */
1704 extern void __builtin_delete (void *);
1707 __builtin_vec_delete (void *ptr)
1709 __builtin_delete (ptr);
1713 /* End of C++ free-store management functions */
1716 unsigned int __shtab[] = {
1717 0x00000001, 0x00000002, 0x00000004, 0x00000008,
1718 0x00000010, 0x00000020, 0x00000040, 0x00000080,
1719 0x00000100, 0x00000200, 0x00000400, 0x00000800,
1720 0x00001000, 0x00002000, 0x00004000, 0x00008000,
1721 0x00010000, 0x00020000, 0x00040000, 0x00080000,
1722 0x00100000, 0x00200000, 0x00400000, 0x00800000,
1723 0x01000000, 0x02000000, 0x04000000, 0x08000000,
1724 0x10000000, 0x20000000, 0x40000000, 0x80000000
1728 #ifdef L_clear_cache
1729 /* Clear part of an instruction cache. */
1731 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1734 __clear_cache (beg, end)
1737 #ifdef CLEAR_INSN_CACHE
1738 CLEAR_INSN_CACHE (beg, end);
1740 #ifdef INSN_CACHE_SIZE
1741 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1742 static int initialized = 0;
1746 typedef (*function_ptr) ();
1748 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1749 /* It's cheaper to clear the whole cache.
1750 Put in a series of jump instructions so that calling the beginning
1751 of the cache will clear the whole thing. */
1755 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1756 & -INSN_CACHE_LINE_WIDTH);
1757 int end_ptr = ptr + INSN_CACHE_SIZE;
1759 while (ptr < end_ptr)
1761 *(INSTRUCTION_TYPE *)ptr
1762 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1763 ptr += INSN_CACHE_LINE_WIDTH;
1765 *(INSTRUCTION_TYPE *)(ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1770 /* Call the beginning of the sequence. */
1771 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1772 & -INSN_CACHE_LINE_WIDTH))
1775 #else /* Cache is large. */
1779 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1780 & -INSN_CACHE_LINE_WIDTH);
1782 while (ptr < (int) array + sizeof array)
1784 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1785 ptr += INSN_CACHE_LINE_WIDTH;
1791 /* Find the location in array that occupies the same cache line as BEG. */
1793 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1794 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1795 & -INSN_CACHE_PLANE_SIZE)
1798 /* Compute the cache alignment of the place to stop clearing. */
1799 #if 0 /* This is not needed for gcc's purposes. */
1800 /* If the block to clear is bigger than a cache plane,
1801 we clear the entire cache, and OFFSET is already correct. */
1802 if (end < beg + INSN_CACHE_PLANE_SIZE)
1804 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1805 & -INSN_CACHE_LINE_WIDTH)
1806 & (INSN_CACHE_PLANE_SIZE - 1));
1808 #if INSN_CACHE_DEPTH > 1
1809 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1810 if (end_addr <= start_addr)
1811 end_addr += INSN_CACHE_PLANE_SIZE;
1813 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1815 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1816 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1818 while (addr != stop)
1820 /* Call the return instruction at ADDR. */
1821 ((function_ptr) addr) ();
1823 addr += INSN_CACHE_LINE_WIDTH;
1826 #else /* just one plane */
1829 /* Call the return instruction at START_ADDR. */
1830 ((function_ptr) start_addr) ();
1832 start_addr += INSN_CACHE_LINE_WIDTH;
1834 while ((start_addr % INSN_CACHE_SIZE) != offset);
1835 #endif /* just one plane */
1836 #endif /* Cache is large */
1837 #endif /* Cache exists */
1838 #endif /* CLEAR_INSN_CACHE */
1841 #endif /* L_clear_cache */
1845 /* Jump to a trampoline, loading the static chain address. */
1847 #ifdef TRANSFER_FROM_TRAMPOLINE
1848 TRANSFER_FROM_TRAMPOLINE
1851 #if defined (NeXT) && defined (__MACH__)
1853 /* Make stack executable so we can call trampolines on stack.
1854 This is called from INITIALIZE_TRAMPOLINE in next.h. */
1858 #include <mach/mach.h>
1862 __enable_execute_stack (addr)
1866 char *eaddr = addr + TRAMPOLINE_SIZE;
1867 vm_address_t a = (vm_address_t) addr;
1869 /* turn on execute access on stack */
1870 r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
1871 if (r != KERN_SUCCESS)
1873 mach_error("vm_protect VM_PROT_ALL", r);
1877 /* We inline the i-cache invalidation for speed */
1879 #ifdef CLEAR_INSN_CACHE
1880 CLEAR_INSN_CACHE (addr, eaddr);
1882 __clear_cache ((int) addr, (int) eaddr);
1886 #endif /* defined (NeXT) && defined (__MACH__) */
1890 /* Make stack executable so we can call trampolines on stack.
1891 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
1893 #include <sys/mman.h>
1894 #include <sys/vmparam.h>
1895 #include <machine/machparam.h>
1898 __enable_execute_stack ()
1901 static unsigned lowest = USRSTACK;
1902 unsigned current = (unsigned) &fp & -NBPG;
1904 if (lowest > current)
1906 unsigned len = lowest - current;
1907 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
1911 /* Clear instruction cache in case an old trampoline is in it. */
1914 #endif /* __convex__ */
1918 /* Modified from the convex -code above. */
1920 #include <sys/param.h>
1922 #include <sys/m88kbcs.h>
1925 __enable_execute_stack ()
1928 static unsigned long lowest = USRSTACK;
1929 unsigned long current = (unsigned long) &save_errno & -NBPC;
1931 /* Ignore errno being set. memctl sets errno to EINVAL whenever the
1932 address is seen as 'negative'. That is the case with the stack. */
1935 if (lowest > current)
1937 unsigned len=lowest-current;
1938 memctl(current,len,MCT_TEXT);
1942 memctl(current,NBPC,MCT_TEXT);
1946 #endif /* __DOLPHIN__ */
1950 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1952 #include <sys/mman.h>
1953 #include <sys/types.h>
1954 #include <sys/param.h>
1955 #include <sys/vmmac.h>
1957 /* Modified from the convex -code above.
1958 mremap promises to clear the i-cache. */
1961 __enable_execute_stack ()
1964 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
1965 PROT_READ|PROT_WRITE|PROT_EXEC))
1967 perror ("mprotect in __enable_execute_stack");
1972 #endif /* __pyr__ */
1973 #endif /* L_trampoline */
1977 #include "gbl-ctors.h"
1978 /* Some systems use __main in a way incompatible with its use in gcc, in these
1979 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
1980 give the same symbol without quotes for an alternative entry point. You
1981 must define both, or niether. */
1983 #define NAME__MAIN "__main"
1984 #define SYMBOL__MAIN __main
1987 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
1988 /* Run all the global destructors on exit from the program. */
1991 __do_global_dtors ()
1993 #ifdef DO_GLOBAL_DTORS_BODY
1994 DO_GLOBAL_DTORS_BODY;
1997 for (p = __DTOR_LIST__ + 1; *p; )
2003 #ifndef INIT_SECTION_ASM_OP
2004 /* Run all the global constructors on entry to the program. */
2007 #define ON_EXIT(a, b)
2009 /* Make sure the exit routine is pulled in to define the globals as
2010 bss symbols, just in case the linker does not automatically pull
2011 bss definitions from the library. */
2013 extern int _exit_dummy_decl;
2014 int *_exit_dummy_ref = &_exit_dummy_decl;
2015 #endif /* ON_EXIT */
2018 __do_global_ctors ()
2020 DO_GLOBAL_CTORS_BODY;
2021 ON_EXIT (__do_global_dtors, 0);
2023 #endif /* no INIT_SECTION_ASM_OP */
2025 #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
2026 /* Subroutine called automatically by `main'.
2027 Compiling a global function named `main'
2028 produces an automatic call to this function at the beginning.
2030 For many systems, this routine calls __do_global_ctors.
2031 For systems which support a .init section we use the .init section
2032 to run __do_global_ctors, so we need not do anything here. */
2037 /* Support recursive calls to `main': run initializers just once. */
2038 static int initialized = 0;
2042 __do_global_ctors ();
2045 #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
2047 #endif /* L__main */
2051 #include "gbl-ctors.h"
2053 /* Provide default definitions for the lists of constructors and
2054 destructors, so that we don't get linker errors. These symbols are
2055 intentionally bss symbols, so that gld and/or collect will provide
2056 the right values. */
2058 /* We declare the lists here with two elements each,
2059 so that they are valid empty lists if no other definition is loaded. */
2060 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
2062 /* After 2.3, try this definition on all systems. */
2063 func_ptr __CTOR_LIST__[2] = {0, 0};
2064 func_ptr __DTOR_LIST__[2] = {0, 0};
2066 func_ptr __CTOR_LIST__[2];
2067 func_ptr __DTOR_LIST__[2];
2069 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
2070 #endif /* L_ctors */
2074 #include "gbl-ctors.h"
2078 /* If we have no known way of registering our own __do_global_dtors
2079 routine so that it will be invoked at program exit time, then we
2080 have to define our own exit routine which will get this to happen. */
2082 extern void __do_global_dtors ();
2083 extern void _cleanup ();
2084 extern void _exit () __attribute__ ((noreturn));
2090 __do_global_dtors ();
2100 int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */
2109 void *exception_handler;
2112 struct exception_table_node {
2113 exception_table *table;
2116 struct exception_table_node *next;
2119 static int except_table_pos = 0;
2120 static void *except_pc = (void *)0;
2121 static struct exception_table_node *exception_table_list = 0;
2123 static exception_table *
2124 find_exception_table (pc)
2127 register struct exception_table_node *table = exception_table_list;
2128 for ( ; table != 0; table = table->next)
2130 if (table->start <= pc && table->end > pc)
2131 return table->table;
2136 /* this routine takes a pc, and the address of the exception handler associated
2137 with the closest exception table handler entry associated with that PC,
2138 or 0 if there are no table entries the PC fits in. The algorithm works
2139 something like this:
2141 while(current_entry exists) {
2142 if(current_entry.start < pc )
2143 current_entry = next_entry;
2145 if(prev_entry.start <= pc && prev_entry.end > pc) {
2146 save pointer to prev_entry;
2147 return prev_entry.exception_handler;
2154 Assuming a correctly sorted table (ascending order) this routine should
2155 return the tighest match...
2157 In the advent of a tie, we have to give the last entry, as it represents
2163 __find_first_exception_table_match(pc)
2166 exception_table *table = find_exception_table (pc);
2172 printf("find_first_exception_table_match(): pc = %x!\n",pc);
2178 /* We can't do this yet, as we don't know that the table is sorted. */
2181 if (table[pos].start > except_pc)
2182 /* found the first table[pos].start > except_pc, so the previous
2183 entry better be the one we want! */
2185 } while(table[pos].exception_handler != (void*)-1);
2188 if (table[pos].start <= except_pc && table[pos].end > except_pc)
2190 except_table_pos = pos;
2192 printf("find_first_eh_table_match(): found match: %x\n",table[pos].exception_handler);
2194 return table[pos].exception_handler;
2197 while (table[++pos].exception_handler != (void*)-1) {
2198 if (table[pos].start <= except_pc && table[pos].end > except_pc)
2200 /* This can apply. Make sure it is better or as good as the previous
2202 /* The best one ends first. */
2203 if (best == 0 || (table[pos].end <= table[best].end
2204 /* The best one starts last. */
2205 && table[pos].start >= table[best].start))
2210 return table[best].exception_handler;
2214 printf("find_first_eh_table_match(): else: returning NULL!\n");
2220 __throw_type_match (const char *catch_type, const char *throw_type)
2223 printf("__throw_type_match (): catch_type = %s, throw_type = %s\n",
2224 catch_type, throw_type);
2226 return strcmp (catch_type, throw_type);
2230 __register_exceptions (exception_table *table)
2232 struct exception_table_node *node = (struct exception_table_node*)
2233 malloc (sizeof (struct exception_table_node));
2234 exception_table *range = table + 1;
2235 node->table = table;
2237 /* This look can be optimized away either if the table
2238 is sorted, or if we pass in extra parameters. */
2239 node->start = range->start;
2240 node->end = range->end;
2241 for (range++ ; range->start != (void*)(-1); range++)
2243 if (range->start < node->start)
2244 node->start = range->start;
2245 if (range->end > node->end)
2246 node->end = range->end;
2249 node->next = exception_table_list;
2250 exception_table_list = node;
2255 __unwind_function(void *ptr)
2257 asm("movl 8(%esp),%ecx");
2258 /* Undo current frame */
2259 asm("movl %ebp,%esp");
2261 asm("# like ret, but stay here");
2262 asm("addl $4,%esp");
2264 /* Now, undo previous frame. */
2265 /* This is a test routine, as we have to dynamically probe to find out
2266 what to pop for certain, this is just a guess. */
2267 asm("leal -16(%ebp),%esp");
2268 asm("pop %eax # really for popl %ebx");
2269 asm("pop %eax # really for popl %esi");
2270 asm("pop %eax # really for popl %edi");
2271 asm("movl %ebp,%esp");
2274 asm("movl %ecx,0(%esp)");
2281 #ifndef inhibit_libc
2282 /* This gets us __GNU_LIBRARY__. */
2283 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2286 #ifdef __GNU_LIBRARY__
2287 /* Avoid forcing the library's meaning of `write' on the user program
2288 by using the "internal" name (for use within the library) */
2289 #define write(fd, buf, n) __write((fd), (buf), (n))
2291 #endif /* inhibit_libc */
2293 #define MESSAGE "pure virtual method called\n"
2298 #ifndef inhibit_libc
2299 write (2, MESSAGE, sizeof (MESSAGE) - 1);