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
39 /* Don't use `fancy_abort' here even if config.h says to use it. */
44 #if (SUPPORTS_WEAK == 1) && defined (ASM_OUTPUT_DEF)
48 /* Permit the tm.h file to select the endianness to use just for this
49 file. This is used when the endianness is determined when the
52 #ifndef LIBGCC2_WORDS_BIG_ENDIAN
53 #define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
56 /* In the first part of this file, we are interfacing to calls generated
57 by the compiler itself. These calls pass values into these routines
58 which have very specific modes (rather than very specific types), and
59 these compiler-generated calls also expect any return values to have
60 very specific modes (rather than very specific types). Thus, we need
61 to avoid using regular C language type names in this part of the file
62 because the sizes for those types can be configured to be anything.
63 Instead we use the following special type names. */
65 typedef unsigned int UQItype __attribute__ ((mode (QI)));
66 typedef int SItype __attribute__ ((mode (SI)));
67 typedef unsigned int USItype __attribute__ ((mode (SI)));
68 typedef int DItype __attribute__ ((mode (DI)));
69 typedef unsigned int UDItype __attribute__ ((mode (DI)));
71 typedef float SFtype __attribute__ ((mode (SF)));
72 typedef float DFtype __attribute__ ((mode (DF)));
74 #if LONG_DOUBLE_TYPE_SIZE == 96
75 typedef float XFtype __attribute__ ((mode (XF)));
77 #if LONG_DOUBLE_TYPE_SIZE == 128
78 typedef float TFtype __attribute__ ((mode (TF)));
81 typedef int word_type __attribute__ ((mode (__word__)));
83 /* Make sure that we don't accidentally use any normal C language built-in
84 type names in the first part of this file. Instead we want to use *only*
85 the type names defined above. The following macro definitions insure
86 that if we *do* accidentally use some normal C language built-in type name,
87 we will get a syntax error. */
89 #define char bogus_type
90 #define short bogus_type
91 #define int bogus_type
92 #define long bogus_type
93 #define unsigned bogus_type
94 #define float bogus_type
95 #define double bogus_type
97 #define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
99 /* DIstructs are pairs of SItype values in the order determined by
100 LIBGCC2_WORDS_BIG_ENDIAN. */
102 #if LIBGCC2_WORDS_BIG_ENDIAN
103 struct DIstruct {SItype high, low;};
105 struct DIstruct {SItype low, high;};
108 /* We need this union to unpack/pack DImode values, since we don't have
109 any arithmetic yet. Incoming DImode parameters are stored into the
110 `ll' field, and the unpacked result is read from the struct `s'. */
118 #if defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_w_sdiv)
120 #include "longlong.h"
122 #endif /* udiv or mul */
124 extern DItype __fixunssfdi (SFtype a);
125 extern DItype __fixunsdfdi (DFtype a);
126 #if LONG_DOUBLE_TYPE_SIZE == 96
127 extern DItype __fixunsxfdi (XFtype a);
129 #if LONG_DOUBLE_TYPE_SIZE == 128
130 extern DItype __fixunstfdi (TFtype a);
133 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
134 #if defined (L_divdi3) || defined (L_moddi3)
147 w.s.high = -uu.s.high - ((USItype) w.s.low > 0);
168 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
172 w.s.low = (USItype)uu.s.high >> -bm;
176 USItype carries = (USItype)uu.s.high << bm;
177 w.s.high = (USItype)uu.s.high >> b;
178 w.s.low = ((USItype)uu.s.low >> b) | carries;
200 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
204 w.s.high = (USItype)uu.s.low << -bm;
208 USItype carries = (USItype)uu.s.low >> bm;
209 w.s.low = (USItype)uu.s.low << b;
210 w.s.high = ((USItype)uu.s.high << b) | carries;
232 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
235 /* w.s.high = 1..1 or 0..0 */
236 w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
237 w.s.low = uu.s.high >> -bm;
241 USItype carries = (USItype)uu.s.high << bm;
242 w.s.high = uu.s.high >> b;
243 w.s.low = ((USItype)uu.s.low >> b) | carries;
258 w.s.low = ffs (uu.s.low);
261 w.s.low = ffs (uu.s.high);
264 w.s.low += BITS_PER_UNIT * sizeof (SItype);
282 w.ll = __umulsidi3 (uu.s.low, vv.s.low);
283 w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
284 + (USItype) uu.s.high * (USItype) vv.s.low);
292 __udiv_w_sdiv (rp, a1, a0, d)
293 USItype *rp, a1, a0, d;
300 if (a1 < d - a1 - (a0 >> (SI_TYPE_SIZE - 1)))
302 /* dividend, divisor, and quotient are nonnegative */
303 sdiv_qrnnd (q, r, a1, a0, d);
307 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
308 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (SI_TYPE_SIZE - 1));
309 /* Divide (c1*2^32 + c0) by d */
310 sdiv_qrnnd (q, r, c1, c0, d);
311 /* Add 2^31 to quotient */
312 q += (USItype) 1 << (SI_TYPE_SIZE - 1);
317 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
318 c1 = a1 >> 1; /* A/2 */
319 c0 = (a1 << (SI_TYPE_SIZE - 1)) + (a0 >> 1);
321 if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
323 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
325 r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
342 else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
345 c0 = ~c0; /* logical NOT */
347 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
349 q = ~q; /* (A/2)/b1 */
352 r = 2*r + (a0 & 1); /* A/(2*b1) */
370 else /* Implies c1 = b1 */
371 { /* Hence a1 = d - 1 = 2*b1 - 1 */
391 static const UQItype __clz_tab[] =
393 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,
394 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,
395 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,
396 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,
397 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,
398 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 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,
400 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,
404 __udivmoddi4 (n, d, rp)
411 USItype d0, d1, n0, n1, n2;
423 #if !UDIV_NEEDS_NORMALIZATION
430 udiv_qrnnd (q0, n0, n1, n0, d0);
433 /* Remainder in n0. */
440 d0 = 1 / d0; /* Divide intentionally by zero. */
442 udiv_qrnnd (q1, n1, 0, n1, d0);
443 udiv_qrnnd (q0, n0, n1, n0, d0);
445 /* Remainder in n0. */
456 #else /* UDIV_NEEDS_NORMALIZATION */
464 count_leading_zeros (bm, d0);
468 /* Normalize, i.e. make the most significant bit of the
472 n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
476 udiv_qrnnd (q0, n0, n1, n0, d0);
479 /* Remainder in n0 >> bm. */
486 d0 = 1 / d0; /* Divide intentionally by zero. */
488 count_leading_zeros (bm, d0);
492 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
493 conclude (the most significant bit of n1 is set) /\ (the
494 leading quotient digit q1 = 1).
496 This special case is necessary, not an optimization.
497 (Shifts counts of SI_TYPE_SIZE are undefined.) */
506 b = SI_TYPE_SIZE - bm;
510 n1 = (n1 << bm) | (n0 >> b);
513 udiv_qrnnd (q1, n1, n2, n1, d0);
518 udiv_qrnnd (q0, n0, n1, n0, d0);
520 /* Remainder in n0 >> bm. */
530 #endif /* UDIV_NEEDS_NORMALIZATION */
541 /* Remainder in n1n0. */
553 count_leading_zeros (bm, d1);
556 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
557 conclude (the most significant bit of n1 is set) /\ (the
558 quotient digit q0 = 0 or 1).
560 This special case is necessary, not an optimization. */
562 /* The condition on the next line takes advantage of that
563 n1 >= d1 (true due to program flow). */
564 if (n1 > d1 || n0 >= d0)
567 sub_ddmmss (n1, n0, n1, n0, d1, d0);
586 b = SI_TYPE_SIZE - bm;
588 d1 = (d1 << bm) | (d0 >> b);
591 n1 = (n1 << bm) | (n0 >> b);
594 udiv_qrnnd (q0, n1, n2, n1, d1);
595 umul_ppmm (m1, m0, q0, d0);
597 if (m1 > n1 || (m1 == n1 && m0 > n0))
600 sub_ddmmss (m1, m0, m1, m0, d1, d0);
605 /* Remainder in (n1n0 - m1m0) >> bm. */
608 sub_ddmmss (n1, n0, n1, n0, m1, m0);
609 rr.s.low = (n1 << b) | (n0 >> bm);
610 rr.s.high = n1 >> bm;
624 UDItype __udivmoddi4 ();
639 uu.ll = __negdi2 (uu.ll);
642 vv.ll = __negdi2 (vv.ll);
644 w = __udivmoddi4 (uu.ll, vv.ll, (UDItype *) 0);
653 UDItype __udivmoddi4 ();
667 uu.ll = __negdi2 (uu.ll);
669 vv.ll = __negdi2 (vv.ll);
671 (void) __udivmoddi4 (uu.ll, vv.ll, &w);
680 UDItype __udivmoddi4 ();
687 (void) __udivmoddi4 (u, v, &w);
694 UDItype __udivmoddi4 ();
699 return __udivmoddi4 (n, d, (UDItype *) 0);
710 au.ll = a, bu.ll = b;
712 if (au.s.high < bu.s.high)
714 else if (au.s.high > bu.s.high)
716 if ((USItype) au.s.low < (USItype) bu.s.low)
718 else if ((USItype) au.s.low > (USItype) bu.s.low)
731 au.ll = a, bu.ll = b;
733 if ((USItype) au.s.high < (USItype) bu.s.high)
735 else if ((USItype) au.s.high > (USItype) bu.s.high)
737 if ((USItype) au.s.low < (USItype) bu.s.low)
739 else if ((USItype) au.s.low > (USItype) bu.s.low)
745 #if defined(L_fixunstfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
746 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
747 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
759 /* Compute high word of result, as a flonum. */
760 b = (a / HIGH_WORD_COEFF);
761 /* Convert that to fixed (but not to DItype!),
762 and shift it into the high word. */
765 /* Remove high part from the TFtype, leaving the low part as flonum. */
767 /* Convert that to fixed (but not to DItype!) and add it in.
768 Sometimes A comes out negative. This is significant, since
769 A has more bits than a long int does. */
771 v -= (USItype) (- a);
778 #if defined(L_fixtfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
784 return - __fixunstfdi (-a);
785 return __fixunstfdi (a);
789 #if defined(L_fixunsxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
790 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
791 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
803 /* Compute high word of result, as a flonum. */
804 b = (a / HIGH_WORD_COEFF);
805 /* Convert that to fixed (but not to DItype!),
806 and shift it into the high word. */
809 /* Remove high part from the XFtype, leaving the low part as flonum. */
811 /* Convert that to fixed (but not to DItype!) and add it in.
812 Sometimes A comes out negative. This is significant, since
813 A has more bits than a long int does. */
815 v -= (USItype) (- a);
822 #if defined(L_fixxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
828 return - __fixunsxfdi (-a);
829 return __fixunsxfdi (a);
834 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
835 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
847 /* Compute high word of result, as a flonum. */
848 b = (a / HIGH_WORD_COEFF);
849 /* Convert that to fixed (but not to DItype!),
850 and shift it into the high word. */
853 /* Remove high part from the DFtype, leaving the low part as flonum. */
855 /* Convert that to fixed (but not to DItype!) and add it in.
856 Sometimes A comes out negative. This is significant, since
857 A has more bits than a long int does. */
859 v -= (USItype) (- a);
872 return - __fixunsdfdi (-a);
873 return __fixunsdfdi (a);
878 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
879 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
882 __fixunssfdi (SFtype original_a)
884 /* Convert the SFtype to a DFtype, because that is surely not going
885 to lose any bits. Some day someone else can write a faster version
886 that avoids converting to DFtype, and verify it really works right. */
887 DFtype a = original_a;
894 /* Compute high word of result, as a flonum. */
895 b = (a / HIGH_WORD_COEFF);
896 /* Convert that to fixed (but not to DItype!),
897 and shift it into the high word. */
900 /* Remove high part from the DFtype, leaving the low part as flonum. */
902 /* Convert that to fixed (but not to DItype!) and add it in.
903 Sometimes A comes out negative. This is significant, since
904 A has more bits than a long int does. */
906 v -= (USItype) (- a);
918 return - __fixunssfdi (-a);
919 return __fixunssfdi (a);
923 #if defined(L_floatdixf) && (LONG_DOUBLE_TYPE_SIZE == 96)
924 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
925 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
926 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
938 d = (USItype) (u >> WORD_SIZE);
939 d *= HIGH_HALFWORD_COEFF;
940 d *= HIGH_HALFWORD_COEFF;
941 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
943 return (negate ? -d : d);
947 #if defined(L_floatditf) && (LONG_DOUBLE_TYPE_SIZE == 128)
948 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
949 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
950 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
962 d = (USItype) (u >> WORD_SIZE);
963 d *= HIGH_HALFWORD_COEFF;
964 d *= HIGH_HALFWORD_COEFF;
965 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
967 return (negate ? -d : d);
972 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
973 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
974 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
986 d = (USItype) (u >> WORD_SIZE);
987 d *= HIGH_HALFWORD_COEFF;
988 d *= HIGH_HALFWORD_COEFF;
989 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
991 return (negate ? -d : d);
996 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
997 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
998 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
999 #define DI_SIZE (sizeof (DItype) * BITS_PER_UNIT)
1000 #if TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1004 #if TARGET_FLOAT_FORMAT == IBM_FLOAT_FORMAT
1008 #if TARGET_FLOAT_FORMAT == VAX_FLOAT_FORMAT
1023 /* Do the calculation in DFmode
1024 so that we don't lose any of the precision of the high word
1025 while multiplying it. */
1032 /* Protect against double-rounding error.
1033 Represent any low-order bits, that might be truncated in DFmode,
1034 by a bit that won't be lost. The bit can go in anywhere below the
1035 rounding position of the SFmode. A fixed mask and bit position
1036 handles all usual configurations. It doesn't handle the case
1037 of 128-bit DImode, however. */
1038 if (DF_SIZE < DI_SIZE
1039 && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1041 #define REP_BIT ((USItype) 1 << (DI_SIZE - DF_SIZE))
1042 if (u >= ((UDItype) 1 << DF_SIZE))
1044 if ((USItype) u & (REP_BIT - 1))
1048 f = (USItype) (u >> WORD_SIZE);
1049 f *= HIGH_HALFWORD_COEFF;
1050 f *= HIGH_HALFWORD_COEFF;
1051 f += (USItype) (u & (HIGH_WORD_COEFF - 1));
1053 return (SFtype) (negate ? -f : f);
1057 #if defined(L_fixunsxfsi) && LONG_DOUBLE_TYPE_SIZE == 96
1058 /* Reenable the normal types, in case limits.h needs them. */
1072 if (a >= - (DFtype) LONG_MIN)
1073 return (SItype) (a + LONG_MIN) - LONG_MIN;
1079 /* Reenable the normal types, in case limits.h needs them. */
1093 if (a >= - (DFtype) LONG_MIN)
1094 return (SItype) (a + LONG_MIN) - LONG_MIN;
1100 /* Reenable the normal types, in case limits.h needs them. */
1111 __fixunssfsi (SFtype a)
1113 if (a >= - (SFtype) LONG_MIN)
1114 return (SItype) (a + LONG_MIN) - LONG_MIN;
1119 /* From here on down, the routines use normal data types. */
1121 #define SItype bogus_type
1122 #define USItype bogus_type
1123 #define DItype bogus_type
1124 #define UDItype bogus_type
1125 #define SFtype bogus_type
1126 #define DFtype bogus_type
1138 /* Like bcmp except the sign is meaningful.
1139 Result is negative if S1 is less than S2,
1140 positive if S1 is greater, 0 if S1 and S2 are equal. */
1143 __gcc_bcmp (s1, s2, size)
1144 unsigned char *s1, *s2;
1149 unsigned char c1 = *s1++, c2 = *s2++;
1161 #if defined(__svr4__) || defined(__alliant__)
1165 /* The Alliant needs the added underscore. */
1166 asm (".globl __builtin_saveregs");
1167 asm ("__builtin_saveregs:");
1168 asm (".globl ___builtin_saveregs");
1169 asm ("___builtin_saveregs:");
1171 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
1172 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
1173 area and also for a new va_list
1175 /* Save all argument registers in the arg reg save area. The
1176 arg reg save area must have the following layout (according
1188 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
1189 asm (" fst.q %f12,16(%sp)");
1191 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
1192 asm (" st.l %r17,36(%sp)");
1193 asm (" st.l %r18,40(%sp)");
1194 asm (" st.l %r19,44(%sp)");
1195 asm (" st.l %r20,48(%sp)");
1196 asm (" st.l %r21,52(%sp)");
1197 asm (" st.l %r22,56(%sp)");
1198 asm (" st.l %r23,60(%sp)");
1199 asm (" st.l %r24,64(%sp)");
1200 asm (" st.l %r25,68(%sp)");
1201 asm (" st.l %r26,72(%sp)");
1202 asm (" st.l %r27,76(%sp)");
1204 asm (" adds 80,%sp,%r16"); /* compute the address of the new
1205 va_list structure. Put in into
1206 r16 so that it will be returned
1209 /* Initialize all fields of the new va_list structure. This
1210 structure looks like:
1213 unsigned long ireg_used;
1214 unsigned long freg_used;
1220 asm (" st.l %r0, 0(%r16)"); /* nfixed */
1221 asm (" st.l %r0, 4(%r16)"); /* nfloating */
1222 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
1223 asm (" bri %r1"); /* delayed return */
1224 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
1226 #else /* not __svr4__ */
1227 #if defined(__PARAGON__)
1229 * we'll use SVR4-ish varargs but need SVR3.2 assembler syntax,
1230 * and we stand a better chance of hooking into libraries
1231 * compiled by PGI. [andyp@ssd.intel.com]
1235 asm (".globl __builtin_saveregs");
1236 asm ("__builtin_saveregs:");
1237 asm (".globl ___builtin_saveregs");
1238 asm ("___builtin_saveregs:");
1240 asm (" andnot 0x0f,sp,sp"); /* round down to 16-byte boundary */
1241 asm (" adds -96,sp,sp"); /* allocate stack space for reg save
1242 area and also for a new va_list
1244 /* Save all argument registers in the arg reg save area. The
1245 arg reg save area must have the following layout (according
1257 asm (" fst.q f8, 0(sp)");
1258 asm (" fst.q f12,16(sp)");
1259 asm (" st.l r16,32(sp)");
1260 asm (" st.l r17,36(sp)");
1261 asm (" st.l r18,40(sp)");
1262 asm (" st.l r19,44(sp)");
1263 asm (" st.l r20,48(sp)");
1264 asm (" st.l r21,52(sp)");
1265 asm (" st.l r22,56(sp)");
1266 asm (" st.l r23,60(sp)");
1267 asm (" st.l r24,64(sp)");
1268 asm (" st.l r25,68(sp)");
1269 asm (" st.l r26,72(sp)");
1270 asm (" st.l r27,76(sp)");
1272 asm (" adds 80,sp,r16"); /* compute the address of the new
1273 va_list structure. Put in into
1274 r16 so that it will be returned
1277 /* Initialize all fields of the new va_list structure. This
1278 structure looks like:
1281 unsigned long ireg_used;
1282 unsigned long freg_used;
1288 asm (" st.l r0, 0(r16)"); /* nfixed */
1289 asm (" st.l r0, 4(r16)"); /* nfloating */
1290 asm (" st.l sp, 8(r16)"); /* __va_ctl points to __va_struct. */
1291 asm (" bri r1"); /* delayed return */
1292 asm (" st.l r28,12(r16)"); /* pointer to overflow args */
1293 #else /* not __PARAGON__ */
1297 asm (".globl ___builtin_saveregs");
1298 asm ("___builtin_saveregs:");
1299 asm (" mov sp,r30");
1300 asm (" andnot 0x0f,sp,sp");
1301 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
1303 /* Fill in the __va_struct. */
1304 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
1305 asm (" st.l r17, 4(sp)"); /* int fixed[12] */
1306 asm (" st.l r18, 8(sp)");
1307 asm (" st.l r19,12(sp)");
1308 asm (" st.l r20,16(sp)");
1309 asm (" st.l r21,20(sp)");
1310 asm (" st.l r22,24(sp)");
1311 asm (" st.l r23,28(sp)");
1312 asm (" st.l r24,32(sp)");
1313 asm (" st.l r25,36(sp)");
1314 asm (" st.l r26,40(sp)");
1315 asm (" st.l r27,44(sp)");
1317 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
1318 asm (" fst.q f12,64(sp)"); /* int floating[8] */
1320 /* Fill in the __va_ctl. */
1321 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
1322 asm (" st.l r28,84(sp)"); /* pointer to more args */
1323 asm (" st.l r0, 88(sp)"); /* nfixed */
1324 asm (" st.l r0, 92(sp)"); /* nfloating */
1326 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
1328 asm (" mov r30,sp");
1329 /* recover stack and pass address to start
1331 #endif /* not __PARAGON__ */
1332 #endif /* not __svr4__ */
1333 #else /* not __i860__ */
1335 asm (".global __builtin_saveregs");
1336 asm ("__builtin_saveregs:");
1337 asm (".global ___builtin_saveregs");
1338 asm ("___builtin_saveregs:");
1339 #ifdef NEED_PROC_COMMAND
1342 asm ("st %i0,[%fp+68]");
1343 asm ("st %i1,[%fp+72]");
1344 asm ("st %i2,[%fp+76]");
1345 asm ("st %i3,[%fp+80]");
1346 asm ("st %i4,[%fp+84]");
1348 asm ("st %i5,[%fp+88]");
1349 #ifdef NEED_TYPE_COMMAND
1350 asm (".type __builtin_saveregs,#function");
1351 asm (".size __builtin_saveregs,.-__builtin_saveregs");
1353 #else /* not __sparc__ */
1354 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1357 asm (" .ent __builtin_saveregs");
1358 asm (" .globl __builtin_saveregs");
1359 asm ("__builtin_saveregs:");
1360 asm (" sw $4,0($30)");
1361 asm (" sw $5,4($30)");
1362 asm (" sw $6,8($30)");
1363 asm (" sw $7,12($30)");
1365 asm (" .end __builtin_saveregs");
1366 #else /* not __mips__, etc. */
1369 __builtin_saveregs ()
1374 #endif /* not __mips__ */
1375 #endif /* not __sparc__ */
1376 #endif /* not __i860__ */
1380 #ifndef inhibit_libc
1382 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1384 /* This is used by the `assert' macro. */
1386 __eprintf (string, expression, line, filename)
1388 const char *expression;
1390 const char *filename;
1392 fprintf (stderr, string, expression, line, filename);
1402 /* Structure emitted by -a */
1406 const char *filename;
1410 const unsigned long *addresses;
1412 /* Older GCC's did not emit these fields. */
1414 const char **functions;
1415 const long *line_nums;
1416 const char **filenames;
1419 #ifdef BLOCK_PROFILER_CODE
1422 #ifndef inhibit_libc
1424 /* Simple minded basic block profiling output dumper for
1425 systems that don't provide tcov support. At present,
1426 it requires atexit and stdio. */
1428 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1434 extern int atexit (void (*) (void));
1436 extern void atexit (void (*) (void));
1438 #define ON_EXIT(FUNC,ARG) atexit ((FUNC))
1441 extern void on_exit (void*, void*);
1442 #define ON_EXIT(FUNC,ARG) on_exit ((FUNC), (ARG))
1446 static struct bb *bb_head;
1448 /* Return the number of digits needed to print a value */
1449 /* __inline__ */ static int num_digits (long value, int base)
1451 int minus = (value < 0 && base != 16);
1452 unsigned long v = (minus) ? -value : value;
1466 __bb_exit_func (void)
1468 FILE *file = fopen ("bb.out", "a");
1478 /* This is somewhat type incorrect, but it avoids worrying about
1479 exactly where time.h is included from. It should be ok unless
1480 a void * differs from other pointer formats, or if sizeof(long)
1481 is < sizeof (time_t). It would be nice if we could assume the
1482 use of rationale standards here. */
1484 time((void *) &time_value);
1485 fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value));
1487 /* We check the length field explicitly in order to allow compatibility
1488 with older GCC's which did not provide it. */
1490 for (ptr = bb_head; ptr != (struct bb *)0; ptr = ptr->next)
1493 int func_p = (ptr->nwords >= sizeof (struct bb) && ptr->nwords <= 1000);
1494 int line_p = (func_p && ptr->line_nums);
1495 int file_p = (func_p && ptr->filenames);
1496 long ncounts = ptr->ncounts;
1502 int blk_len = num_digits (ncounts, 10);
1507 fprintf (file, "File %s, %ld basic blocks \n\n",
1508 ptr->filename, ncounts);
1510 /* Get max values for each field. */
1511 for (i = 0; i < ncounts; i++)
1516 if (cnt_max < ptr->counts[i])
1517 cnt_max = ptr->counts[i];
1519 if (addr_max < ptr->addresses[i])
1520 addr_max = ptr->addresses[i];
1522 if (line_p && line_max < ptr->line_nums[i])
1523 line_max = ptr->line_nums[i];
1527 p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>";
1535 p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>";
1542 addr_len = num_digits (addr_max, 16);
1543 cnt_len = num_digits (cnt_max, 10);
1544 line_len = num_digits (line_max, 10);
1546 /* Now print out the basic block information. */
1547 for (i = 0; i < ncounts; i++)
1550 " Block #%*d: executed %*ld time(s) address= 0x%.*lx",
1552 cnt_len, ptr->counts[i],
1553 addr_len, ptr->addresses[i]);
1556 fprintf (file, " function= %-*s", func_len,
1557 (ptr->functions[i]) ? ptr->functions[i] : "<none>");
1560 fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]);
1563 fprintf (file, " file= %s",
1564 (ptr->filenames[i]) ? ptr->filenames[i] : "<none>");
1566 fprintf (file, "\n");
1569 fprintf (file, "\n");
1573 fprintf (file, "\n\n");
1579 __bb_init_func (struct bb *blocks)
1581 /* User is supposed to check whether the first word is non-0,
1582 but just in case.... */
1584 if (blocks->zero_word)
1588 /* Initialize destructor. */
1590 ON_EXIT (__bb_exit_func, 0);
1593 /* Set up linked list. */
1594 blocks->zero_word = 1;
1595 blocks->next = bb_head;
1599 #endif /* not inhibit_libc */
1600 #endif /* not BLOCK_PROFILER_CODE */
1603 /* Default free-store management functions for C++, per sections 12.5 and
1604 17.3.3 of the Working Paper. */
1607 /* operator new (size_t), described in 17.3.3.5. This function is used by
1608 C++ programs to allocate a block of memory to hold a single object. */
1610 typedef void (*vfp)(void);
1611 extern vfp __new_handler;
1612 extern void __default_new_handler (void);
1615 void * __builtin_new (size_t sz)
1616 __attribute__ ((weak, alias ("___builtin_new")));
1618 ___builtin_new (size_t sz)
1621 __builtin_new (size_t sz)
1625 vfp handler = (__new_handler) ? __new_handler : __default_new_handler;
1627 /* malloc (0) is unpredictable; avoid it. */
1630 p = (void *) malloc (sz);
1634 p = (void *) malloc (sz);
1639 #endif /* L_op_new */
1642 /* void * operator new [] (size_t), described in 17.3.3.6. This function
1643 is used by C++ programs to allocate a block of memory for an array. */
1645 extern void * __builtin_new (size_t);
1648 void * __builtin_vec_new (size_t sz)
1649 __attribute__ ((weak, alias ("___builtin_vec_new")));
1651 ___builtin_vec_new (size_t sz)
1654 __builtin_vec_new (size_t sz)
1657 return __builtin_new (sz);
1659 #endif /* L_op_vnew */
1661 #ifdef L_new_handler
1662 /* set_new_handler (fvoid_t *) and the default new handler, described in
1663 17.3.3.2 and 17.3.3.5. These functions define the result of a failure
1664 to allocate the amount of memory requested from operator new or new []. */
1666 #ifndef inhibit_libc
1667 /* This gets us __GNU_LIBRARY__. */
1668 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1671 #ifdef __GNU_LIBRARY__
1672 /* Avoid forcing the library's meaning of `write' on the user program
1673 by using the "internal" name (for use within the library) */
1674 #define write(fd, buf, n) __write((fd), (buf), (n))
1676 #endif /* inhibit_libc */
1678 typedef void (*vfp)(void);
1679 void __default_new_handler (void);
1681 vfp __new_handler = (vfp)0;
1684 set_new_handler (vfp handler)
1688 prev_handler = __new_handler;
1689 if (handler == 0) handler = __default_new_handler;
1690 __new_handler = handler;
1691 return prev_handler;
1694 #define MESSAGE "Virtual memory exceeded in `new'\n"
1697 __default_new_handler ()
1699 #ifndef inhibit_libc
1700 /* don't use fprintf (stderr, ...) because it may need to call malloc. */
1701 /* This should really print the name of the program, but that is hard to
1702 do. We need a standard, clean way to get at the name. */
1703 write (2, MESSAGE, sizeof (MESSAGE));
1705 /* don't call exit () because that may call global destructors which
1706 may cause a loop. */
1712 /* operator delete (void *), described in 17.3.3.3. This function is used
1713 by C++ programs to return to the free store a block of memory allocated
1714 as a single object. */
1717 void __builtin_delete (void *ptr)
1718 __attribute__ ((weak, alias ("___builtin_delete")));
1720 ___builtin_delete (void *ptr)
1723 __builtin_delete (void *ptr)
1732 /* operator delete [] (void *), described in 17.3.3.4. This function is
1733 used by C++ programs to return to the free store a block of memory
1734 allocated as an array. */
1736 extern void __builtin_delete (void *);
1739 void __builtin_vec_delete (void *ptr)
1740 __attribute__ ((weak, alias ("___builtin_vec_delete")));
1742 ___builtin_vec_delete (void *ptr)
1745 __builtin_vec_delete (void *ptr)
1748 __builtin_delete (ptr);
1752 /* End of C++ free-store management functions */
1755 unsigned int __shtab[] = {
1756 0x00000001, 0x00000002, 0x00000004, 0x00000008,
1757 0x00000010, 0x00000020, 0x00000040, 0x00000080,
1758 0x00000100, 0x00000200, 0x00000400, 0x00000800,
1759 0x00001000, 0x00002000, 0x00004000, 0x00008000,
1760 0x00010000, 0x00020000, 0x00040000, 0x00080000,
1761 0x00100000, 0x00200000, 0x00400000, 0x00800000,
1762 0x01000000, 0x02000000, 0x04000000, 0x08000000,
1763 0x10000000, 0x20000000, 0x40000000, 0x80000000
1767 #ifdef L_clear_cache
1768 /* Clear part of an instruction cache. */
1770 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1773 __clear_cache (beg, end)
1776 #ifdef CLEAR_INSN_CACHE
1777 CLEAR_INSN_CACHE (beg, end);
1779 #ifdef INSN_CACHE_SIZE
1780 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1781 static int initialized;
1785 typedef (*function_ptr) ();
1787 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1788 /* It's cheaper to clear the whole cache.
1789 Put in a series of jump instructions so that calling the beginning
1790 of the cache will clear the whole thing. */
1794 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1795 & -INSN_CACHE_LINE_WIDTH);
1796 int end_ptr = ptr + INSN_CACHE_SIZE;
1798 while (ptr < end_ptr)
1800 *(INSTRUCTION_TYPE *)ptr
1801 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1802 ptr += INSN_CACHE_LINE_WIDTH;
1804 *(INSTRUCTION_TYPE *)(ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1809 /* Call the beginning of the sequence. */
1810 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1811 & -INSN_CACHE_LINE_WIDTH))
1814 #else /* Cache is large. */
1818 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1819 & -INSN_CACHE_LINE_WIDTH);
1821 while (ptr < (int) array + sizeof array)
1823 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1824 ptr += INSN_CACHE_LINE_WIDTH;
1830 /* Find the location in array that occupies the same cache line as BEG. */
1832 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1833 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1834 & -INSN_CACHE_PLANE_SIZE)
1837 /* Compute the cache alignment of the place to stop clearing. */
1838 #if 0 /* This is not needed for gcc's purposes. */
1839 /* If the block to clear is bigger than a cache plane,
1840 we clear the entire cache, and OFFSET is already correct. */
1841 if (end < beg + INSN_CACHE_PLANE_SIZE)
1843 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1844 & -INSN_CACHE_LINE_WIDTH)
1845 & (INSN_CACHE_PLANE_SIZE - 1));
1847 #if INSN_CACHE_DEPTH > 1
1848 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1849 if (end_addr <= start_addr)
1850 end_addr += INSN_CACHE_PLANE_SIZE;
1852 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1854 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1855 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1857 while (addr != stop)
1859 /* Call the return instruction at ADDR. */
1860 ((function_ptr) addr) ();
1862 addr += INSN_CACHE_LINE_WIDTH;
1865 #else /* just one plane */
1868 /* Call the return instruction at START_ADDR. */
1869 ((function_ptr) start_addr) ();
1871 start_addr += INSN_CACHE_LINE_WIDTH;
1873 while ((start_addr % INSN_CACHE_SIZE) != offset);
1874 #endif /* just one plane */
1875 #endif /* Cache is large */
1876 #endif /* Cache exists */
1877 #endif /* CLEAR_INSN_CACHE */
1880 #endif /* L_clear_cache */
1884 /* Jump to a trampoline, loading the static chain address. */
1886 #ifdef TRANSFER_FROM_TRAMPOLINE
1887 TRANSFER_FROM_TRAMPOLINE
1890 #if defined (NeXT) && defined (__MACH__)
1892 /* Make stack executable so we can call trampolines on stack.
1893 This is called from INITIALIZE_TRAMPOLINE in next.h. */
1897 #include <mach/mach.h>
1901 __enable_execute_stack (addr)
1905 char *eaddr = addr + TRAMPOLINE_SIZE;
1906 vm_address_t a = (vm_address_t) addr;
1908 /* turn on execute access on stack */
1909 r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
1910 if (r != KERN_SUCCESS)
1912 mach_error("vm_protect VM_PROT_ALL", r);
1916 /* We inline the i-cache invalidation for speed */
1918 #ifdef CLEAR_INSN_CACHE
1919 CLEAR_INSN_CACHE (addr, eaddr);
1921 __clear_cache ((int) addr, (int) eaddr);
1925 #endif /* defined (NeXT) && defined (__MACH__) */
1929 /* Make stack executable so we can call trampolines on stack.
1930 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
1932 #include <sys/mman.h>
1933 #include <sys/vmparam.h>
1934 #include <machine/machparam.h>
1937 __enable_execute_stack ()
1940 static unsigned lowest = USRSTACK;
1941 unsigned current = (unsigned) &fp & -NBPG;
1943 if (lowest > current)
1945 unsigned len = lowest - current;
1946 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
1950 /* Clear instruction cache in case an old trampoline is in it. */
1953 #endif /* __convex__ */
1957 /* Modified from the convex -code above. */
1959 #include <sys/param.h>
1961 #include <sys/m88kbcs.h>
1964 __enable_execute_stack ()
1967 static unsigned long lowest = USRSTACK;
1968 unsigned long current = (unsigned long) &save_errno & -NBPC;
1970 /* Ignore errno being set. memctl sets errno to EINVAL whenever the
1971 address is seen as 'negative'. That is the case with the stack. */
1974 if (lowest > current)
1976 unsigned len=lowest-current;
1977 memctl(current,len,MCT_TEXT);
1981 memctl(current,NBPC,MCT_TEXT);
1985 #endif /* __DOLPHIN__ */
1989 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1991 #include <sys/mman.h>
1992 #include <sys/types.h>
1993 #include <sys/param.h>
1994 #include <sys/vmmac.h>
1996 /* Modified from the convex -code above.
1997 mremap promises to clear the i-cache. */
2000 __enable_execute_stack ()
2003 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
2004 PROT_READ|PROT_WRITE|PROT_EXEC))
2006 perror ("mprotect in __enable_execute_stack");
2011 #endif /* __pyr__ */
2012 #endif /* L_trampoline */
2016 #include "gbl-ctors.h"
2017 /* Some systems use __main in a way incompatible with its use in gcc, in these
2018 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2019 give the same symbol without quotes for an alternative entry point. You
2020 must define both, or neither. */
2022 #define NAME__MAIN "__main"
2023 #define SYMBOL__MAIN __main
2026 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2027 /* Run all the global destructors on exit from the program. */
2030 __do_global_dtors ()
2032 #ifdef DO_GLOBAL_DTORS_BODY
2033 DO_GLOBAL_DTORS_BODY;
2036 for (p = __DTOR_LIST__ + 1; *p; )
2042 #ifndef INIT_SECTION_ASM_OP
2043 /* Run all the global constructors on entry to the program. */
2046 #define ON_EXIT(a, b)
2048 /* Make sure the exit routine is pulled in to define the globals as
2049 bss symbols, just in case the linker does not automatically pull
2050 bss definitions from the library. */
2052 extern int _exit_dummy_decl;
2053 int *_exit_dummy_ref = &_exit_dummy_decl;
2054 #endif /* ON_EXIT */
2057 __do_global_ctors ()
2059 DO_GLOBAL_CTORS_BODY;
2060 ON_EXIT (__do_global_dtors, 0);
2062 #endif /* no INIT_SECTION_ASM_OP */
2064 #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
2065 /* Subroutine called automatically by `main'.
2066 Compiling a global function named `main'
2067 produces an automatic call to this function at the beginning.
2069 For many systems, this routine calls __do_global_ctors.
2070 For systems which support a .init section we use the .init section
2071 to run __do_global_ctors, so we need not do anything here. */
2076 /* Support recursive calls to `main': run initializers just once. */
2077 static int initialized;
2081 __do_global_ctors ();
2084 #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
2086 #endif /* L__main */
2090 #include "gbl-ctors.h"
2092 /* Provide default definitions for the lists of constructors and
2093 destructors, so that we don't get linker errors. These symbols are
2094 intentionally bss symbols, so that gld and/or collect will provide
2095 the right values. */
2097 /* We declare the lists here with two elements each,
2098 so that they are valid empty lists if no other definition is loaded. */
2099 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
2101 /* After 2.3, try this definition on all systems. */
2102 func_ptr __CTOR_LIST__[2] = {0, 0};
2103 func_ptr __DTOR_LIST__[2] = {0, 0};
2105 func_ptr __CTOR_LIST__[2];
2106 func_ptr __DTOR_LIST__[2];
2108 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
2109 #endif /* L_ctors */
2113 #include "gbl-ctors.h"
2117 /* If we have no known way of registering our own __do_global_dtors
2118 routine so that it will be invoked at program exit time, then we
2119 have to define our own exit routine which will get this to happen. */
2121 extern void __do_global_dtors ();
2122 extern void _cleanup ();
2123 extern void _exit () __attribute__ ((noreturn));
2129 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2130 __do_global_dtors ();
2141 int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */
2150 void *exception_handler;
2153 struct exception_table_node {
2154 exception_table *table;
2157 struct exception_table_node *next;
2160 static int except_table_pos;
2161 static void *except_pc;
2162 static struct exception_table_node *exception_table_list;
2164 static exception_table *
2165 find_exception_table (pc)
2168 register struct exception_table_node *table = exception_table_list;
2169 for ( ; table != 0; table = table->next)
2171 if (table->start <= pc && table->end > pc)
2172 return table->table;
2177 /* this routine takes a pc, and the address of the exception handler associated
2178 with the closest exception table handler entry associated with that PC,
2179 or 0 if there are no table entries the PC fits in. The algorithm works
2180 something like this:
2182 while(current_entry exists) {
2183 if(current_entry.start < pc )
2184 current_entry = next_entry;
2186 if(prev_entry.start <= pc && prev_entry.end > pc) {
2187 save pointer to prev_entry;
2188 return prev_entry.exception_handler;
2195 Assuming a correctly sorted table (ascending order) this routine should
2196 return the tighest match...
2198 In the advent of a tie, we have to give the last entry, as it represents
2204 __find_first_exception_table_match(pc)
2207 exception_table *table = find_exception_table (pc);
2213 printf("find_first_exception_table_match(): pc = %x!\n",pc);
2219 /* We can't do this yet, as we don't know that the table is sorted. */
2222 if (table[pos].start > except_pc)
2223 /* found the first table[pos].start > except_pc, so the previous
2224 entry better be the one we want! */
2226 } while(table[pos].exception_handler != (void*)-1);
2229 if (table[pos].start <= except_pc && table[pos].end > except_pc)
2231 except_table_pos = pos;
2233 printf("find_first_eh_table_match(): found match: %x\n",table[pos].exception_handler);
2235 return table[pos].exception_handler;
2238 while (table[++pos].exception_handler != (void*)-1) {
2239 if (table[pos].start <= except_pc && table[pos].end > except_pc)
2241 /* This can apply. Make sure it is better or as good as the previous
2243 /* The best one ends first. */
2244 if (best == 0 || (table[pos].end <= table[best].end
2245 /* The best one starts last. */
2246 && table[pos].start >= table[best].start))
2251 return table[best].exception_handler;
2255 printf("find_first_eh_table_match(): else: returning NULL!\n");
2261 __throw_type_match (void *catch_type, void *throw_type, void* obj)
2264 printf("__throw_type_match (): catch_type = %s, throw_type = %s\n",
2265 catch_type, throw_type);
2267 if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)
2273 __register_exceptions (exception_table *table)
2275 struct exception_table_node *node;
2276 exception_table *range = table + 1;
2278 if (range->start == (void*)-1)
2281 node = (struct exception_table_node*)
2282 malloc (sizeof (struct exception_table_node));
2283 node->table = table;
2285 /* This look can be optimized away either if the table
2286 is sorted, or if we pass in extra parameters. */
2287 node->start = range->start;
2288 node->end = range->end;
2289 for (range++ ; range->start != (void*)(-1); range++)
2291 if (range->start < node->start)
2292 node->start = range->start;
2293 if (range->end > node->end)
2294 node->end = range->end;
2297 node->next = exception_table_list;
2298 exception_table_list = node;
2303 __unwind_function(void *ptr)
2305 asm("movl 8(%esp),%ecx");
2306 /* Undo current frame */
2307 asm("movl %ebp,%esp");
2309 asm("# like ret, but stay here");
2310 asm("addl $4,%esp");
2312 /* Now, undo previous frame. */
2313 /* This is a test routine, as we have to dynamically probe to find out
2314 what to pop for certain, this is just a guess. */
2315 asm("leal -16(%ebp),%esp");
2316 asm("pop %eax # really for popl %ebx");
2317 asm("pop %eax # really for popl %esi");
2318 asm("pop %eax # really for popl %edi");
2319 asm("movl %ebp,%esp");
2322 asm("movl %ecx,0(%esp)");
2327 #if #machine(rs6000)
2328 __unwind_function(void *ptr)
2337 /* use 31 as a scratch register to restore the link register. */
2338 asm("l 31, 8(1);mtlr 31 # l lr,8(1)");
2341 asm("mtctr 3;bctr # b 3");
2345 #if #machine(powerpc)
2346 __unwind_function(void *ptr)
2350 asm("lwz 31,-4(1)");
2355 /* use 31 as a scratch register to restore the link register. */
2356 asm("lwz 31, 8(1);mtlr 31 # l lr,8(1)");
2357 asm("lwz 31,-4(1)");
2359 asm("mtctr 3;bctr # b 3");
2361 #endif /* powerpc */
2365 #ifndef inhibit_libc
2366 /* This gets us __GNU_LIBRARY__. */
2367 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2370 #ifdef __GNU_LIBRARY__
2371 /* Avoid forcing the library's meaning of `write' on the user program
2372 by using the "internal" name (for use within the library) */
2373 #define write(fd, buf, n) __write((fd), (buf), (n))
2375 #endif /* inhibit_libc */
2377 #define MESSAGE "pure virtual method called\n"
2382 #ifndef inhibit_libc
2383 write (2, MESSAGE, sizeof (MESSAGE) - 1);