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)
1001 /* Define codes for all the float formats that we know of. Note
1002 that this is copied from real.h. */
1004 #define UNKNOWN_FLOAT_FORMAT 0
1005 #define IEEE_FLOAT_FORMAT 1
1006 #define VAX_FLOAT_FORMAT 2
1007 #define IBM_FLOAT_FORMAT 3
1009 /* Default to IEEE float if not specified. Nearly all machines use it. */
1010 #ifndef HOST_FLOAT_FORMAT
1011 #define HOST_FLOAT_FORMAT IEEE_FLOAT_FORMAT
1014 #if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1019 #if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
1024 #if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
1033 /* Do the calculation in DFmode
1034 so that we don't lose any of the precision of the high word
1035 while multiplying it. */
1042 /* Protect against double-rounding error.
1043 Represent any low-order bits, that might be truncated in DFmode,
1044 by a bit that won't be lost. The bit can go in anywhere below the
1045 rounding position of the SFmode. A fixed mask and bit position
1046 handles all usual configurations. It doesn't handle the case
1047 of 128-bit DImode, however. */
1048 if (DF_SIZE < DI_SIZE
1049 && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1051 #define REP_BIT ((USItype) 1 << (DI_SIZE - DF_SIZE))
1052 if (u >= ((UDItype) 1 << DF_SIZE))
1054 if ((USItype) u & (REP_BIT - 1))
1058 f = (USItype) (u >> WORD_SIZE);
1059 f *= HIGH_HALFWORD_COEFF;
1060 f *= HIGH_HALFWORD_COEFF;
1061 f += (USItype) (u & (HIGH_WORD_COEFF - 1));
1063 return (SFtype) (negate ? -f : f);
1067 #if defined(L_fixunsxfsi) && LONG_DOUBLE_TYPE_SIZE == 96
1068 /* Reenable the normal types, in case limits.h needs them. */
1082 if (a >= - (DFtype) LONG_MIN)
1083 return (SItype) (a + LONG_MIN) - LONG_MIN;
1089 /* Reenable the normal types, in case limits.h needs them. */
1103 if (a >= - (DFtype) LONG_MIN)
1104 return (SItype) (a + LONG_MIN) - LONG_MIN;
1110 /* Reenable the normal types, in case limits.h needs them. */
1121 __fixunssfsi (SFtype a)
1123 if (a >= - (SFtype) LONG_MIN)
1124 return (SItype) (a + LONG_MIN) - LONG_MIN;
1129 /* From here on down, the routines use normal data types. */
1131 #define SItype bogus_type
1132 #define USItype bogus_type
1133 #define DItype bogus_type
1134 #define UDItype bogus_type
1135 #define SFtype bogus_type
1136 #define DFtype bogus_type
1148 /* Like bcmp except the sign is meaningful.
1149 Result is negative if S1 is less than S2,
1150 positive if S1 is greater, 0 if S1 and S2 are equal. */
1153 __gcc_bcmp (s1, s2, size)
1154 unsigned char *s1, *s2;
1159 unsigned char c1 = *s1++, c2 = *s2++;
1171 #if defined(__svr4__) || defined(__alliant__)
1175 /* The Alliant needs the added underscore. */
1176 asm (".globl __builtin_saveregs");
1177 asm ("__builtin_saveregs:");
1178 asm (".globl ___builtin_saveregs");
1179 asm ("___builtin_saveregs:");
1181 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
1182 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
1183 area and also for a new va_list
1185 /* Save all argument registers in the arg reg save area. The
1186 arg reg save area must have the following layout (according
1198 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
1199 asm (" fst.q %f12,16(%sp)");
1201 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
1202 asm (" st.l %r17,36(%sp)");
1203 asm (" st.l %r18,40(%sp)");
1204 asm (" st.l %r19,44(%sp)");
1205 asm (" st.l %r20,48(%sp)");
1206 asm (" st.l %r21,52(%sp)");
1207 asm (" st.l %r22,56(%sp)");
1208 asm (" st.l %r23,60(%sp)");
1209 asm (" st.l %r24,64(%sp)");
1210 asm (" st.l %r25,68(%sp)");
1211 asm (" st.l %r26,72(%sp)");
1212 asm (" st.l %r27,76(%sp)");
1214 asm (" adds 80,%sp,%r16"); /* compute the address of the new
1215 va_list structure. Put in into
1216 r16 so that it will be returned
1219 /* Initialize all fields of the new va_list structure. This
1220 structure looks like:
1223 unsigned long ireg_used;
1224 unsigned long freg_used;
1230 asm (" st.l %r0, 0(%r16)"); /* nfixed */
1231 asm (" st.l %r0, 4(%r16)"); /* nfloating */
1232 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
1233 asm (" bri %r1"); /* delayed return */
1234 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
1236 #else /* not __svr4__ */
1237 #if defined(__PARAGON__)
1239 * we'll use SVR4-ish varargs but need SVR3.2 assembler syntax,
1240 * and we stand a better chance of hooking into libraries
1241 * compiled by PGI. [andyp@ssd.intel.com]
1245 asm (".globl __builtin_saveregs");
1246 asm ("__builtin_saveregs:");
1247 asm (".globl ___builtin_saveregs");
1248 asm ("___builtin_saveregs:");
1250 asm (" andnot 0x0f,sp,sp"); /* round down to 16-byte boundary */
1251 asm (" adds -96,sp,sp"); /* allocate stack space for reg save
1252 area and also for a new va_list
1254 /* Save all argument registers in the arg reg save area. The
1255 arg reg save area must have the following layout (according
1267 asm (" fst.q f8, 0(sp)");
1268 asm (" fst.q f12,16(sp)");
1269 asm (" st.l r16,32(sp)");
1270 asm (" st.l r17,36(sp)");
1271 asm (" st.l r18,40(sp)");
1272 asm (" st.l r19,44(sp)");
1273 asm (" st.l r20,48(sp)");
1274 asm (" st.l r21,52(sp)");
1275 asm (" st.l r22,56(sp)");
1276 asm (" st.l r23,60(sp)");
1277 asm (" st.l r24,64(sp)");
1278 asm (" st.l r25,68(sp)");
1279 asm (" st.l r26,72(sp)");
1280 asm (" st.l r27,76(sp)");
1282 asm (" adds 80,sp,r16"); /* compute the address of the new
1283 va_list structure. Put in into
1284 r16 so that it will be returned
1287 /* Initialize all fields of the new va_list structure. This
1288 structure looks like:
1291 unsigned long ireg_used;
1292 unsigned long freg_used;
1298 asm (" st.l r0, 0(r16)"); /* nfixed */
1299 asm (" st.l r0, 4(r16)"); /* nfloating */
1300 asm (" st.l sp, 8(r16)"); /* __va_ctl points to __va_struct. */
1301 asm (" bri r1"); /* delayed return */
1302 asm (" st.l r28,12(r16)"); /* pointer to overflow args */
1303 #else /* not __PARAGON__ */
1307 asm (".globl ___builtin_saveregs");
1308 asm ("___builtin_saveregs:");
1309 asm (" mov sp,r30");
1310 asm (" andnot 0x0f,sp,sp");
1311 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
1313 /* Fill in the __va_struct. */
1314 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
1315 asm (" st.l r17, 4(sp)"); /* int fixed[12] */
1316 asm (" st.l r18, 8(sp)");
1317 asm (" st.l r19,12(sp)");
1318 asm (" st.l r20,16(sp)");
1319 asm (" st.l r21,20(sp)");
1320 asm (" st.l r22,24(sp)");
1321 asm (" st.l r23,28(sp)");
1322 asm (" st.l r24,32(sp)");
1323 asm (" st.l r25,36(sp)");
1324 asm (" st.l r26,40(sp)");
1325 asm (" st.l r27,44(sp)");
1327 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
1328 asm (" fst.q f12,64(sp)"); /* int floating[8] */
1330 /* Fill in the __va_ctl. */
1331 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
1332 asm (" st.l r28,84(sp)"); /* pointer to more args */
1333 asm (" st.l r0, 88(sp)"); /* nfixed */
1334 asm (" st.l r0, 92(sp)"); /* nfloating */
1336 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
1338 asm (" mov r30,sp");
1339 /* recover stack and pass address to start
1341 #endif /* not __PARAGON__ */
1342 #endif /* not __svr4__ */
1343 #else /* not __i860__ */
1345 asm (".global __builtin_saveregs");
1346 asm ("__builtin_saveregs:");
1347 asm (".global ___builtin_saveregs");
1348 asm ("___builtin_saveregs:");
1349 #ifdef NEED_PROC_COMMAND
1352 asm ("st %i0,[%fp+68]");
1353 asm ("st %i1,[%fp+72]");
1354 asm ("st %i2,[%fp+76]");
1355 asm ("st %i3,[%fp+80]");
1356 asm ("st %i4,[%fp+84]");
1358 asm ("st %i5,[%fp+88]");
1359 #ifdef NEED_TYPE_COMMAND
1360 asm (".type __builtin_saveregs,#function");
1361 asm (".size __builtin_saveregs,.-__builtin_saveregs");
1363 #else /* not __sparc__ */
1364 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1367 asm (" .ent __builtin_saveregs");
1368 asm (" .globl __builtin_saveregs");
1369 asm ("__builtin_saveregs:");
1370 asm (" sw $4,0($30)");
1371 asm (" sw $5,4($30)");
1372 asm (" sw $6,8($30)");
1373 asm (" sw $7,12($30)");
1375 asm (" .end __builtin_saveregs");
1376 #else /* not __mips__, etc. */
1379 __builtin_saveregs ()
1384 #endif /* not __mips__ */
1385 #endif /* not __sparc__ */
1386 #endif /* not __i860__ */
1390 #ifndef inhibit_libc
1392 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1394 /* This is used by the `assert' macro. */
1396 __eprintf (string, expression, line, filename)
1398 const char *expression;
1400 const char *filename;
1402 fprintf (stderr, string, expression, line, filename);
1412 /* Structure emitted by -a */
1416 const char *filename;
1420 const unsigned long *addresses;
1422 /* Older GCC's did not emit these fields. */
1424 const char **functions;
1425 const long *line_nums;
1426 const char **filenames;
1429 #ifdef BLOCK_PROFILER_CODE
1432 #ifndef inhibit_libc
1434 /* Simple minded basic block profiling output dumper for
1435 systems that don't provide tcov support. At present,
1436 it requires atexit and stdio. */
1438 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1444 extern int atexit (void (*) (void));
1446 extern void atexit (void (*) (void));
1448 #define ON_EXIT(FUNC,ARG) atexit ((FUNC))
1451 extern void on_exit (void*, void*);
1452 #define ON_EXIT(FUNC,ARG) on_exit ((FUNC), (ARG))
1456 static struct bb *bb_head;
1458 /* Return the number of digits needed to print a value */
1459 /* __inline__ */ static int num_digits (long value, int base)
1461 int minus = (value < 0 && base != 16);
1462 unsigned long v = (minus) ? -value : value;
1476 __bb_exit_func (void)
1478 FILE *file = fopen ("bb.out", "a");
1488 /* This is somewhat type incorrect, but it avoids worrying about
1489 exactly where time.h is included from. It should be ok unless
1490 a void * differs from other pointer formats, or if sizeof(long)
1491 is < sizeof (time_t). It would be nice if we could assume the
1492 use of rationale standards here. */
1494 time((void *) &time_value);
1495 fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value));
1497 /* We check the length field explicitly in order to allow compatibility
1498 with older GCC's which did not provide it. */
1500 for (ptr = bb_head; ptr != (struct bb *)0; ptr = ptr->next)
1503 int func_p = (ptr->nwords >= sizeof (struct bb) && ptr->nwords <= 1000);
1504 int line_p = (func_p && ptr->line_nums);
1505 int file_p = (func_p && ptr->filenames);
1506 long ncounts = ptr->ncounts;
1512 int blk_len = num_digits (ncounts, 10);
1517 fprintf (file, "File %s, %ld basic blocks \n\n",
1518 ptr->filename, ncounts);
1520 /* Get max values for each field. */
1521 for (i = 0; i < ncounts; i++)
1526 if (cnt_max < ptr->counts[i])
1527 cnt_max = ptr->counts[i];
1529 if (addr_max < ptr->addresses[i])
1530 addr_max = ptr->addresses[i];
1532 if (line_p && line_max < ptr->line_nums[i])
1533 line_max = ptr->line_nums[i];
1537 p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>";
1545 p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>";
1552 addr_len = num_digits (addr_max, 16);
1553 cnt_len = num_digits (cnt_max, 10);
1554 line_len = num_digits (line_max, 10);
1556 /* Now print out the basic block information. */
1557 for (i = 0; i < ncounts; i++)
1560 " Block #%*d: executed %*ld time(s) address= 0x%.*lx",
1562 cnt_len, ptr->counts[i],
1563 addr_len, ptr->addresses[i]);
1566 fprintf (file, " function= %-*s", func_len,
1567 (ptr->functions[i]) ? ptr->functions[i] : "<none>");
1570 fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]);
1573 fprintf (file, " file= %s",
1574 (ptr->filenames[i]) ? ptr->filenames[i] : "<none>");
1576 fprintf (file, "\n");
1579 fprintf (file, "\n");
1583 fprintf (file, "\n\n");
1589 __bb_init_func (struct bb *blocks)
1591 /* User is supposed to check whether the first word is non-0,
1592 but just in case.... */
1594 if (blocks->zero_word)
1598 /* Initialize destructor. */
1600 ON_EXIT (__bb_exit_func, 0);
1603 /* Set up linked list. */
1604 blocks->zero_word = 1;
1605 blocks->next = bb_head;
1609 #endif /* not inhibit_libc */
1610 #endif /* not BLOCK_PROFILER_CODE */
1613 /* Default free-store management functions for C++, per sections 12.5 and
1614 17.3.3 of the Working Paper. */
1617 /* operator new (size_t), described in 17.3.3.5. This function is used by
1618 C++ programs to allocate a block of memory to hold a single object. */
1620 typedef void (*vfp)(void);
1621 extern vfp __new_handler;
1622 extern void __default_new_handler (void);
1625 void * __builtin_new (size_t sz)
1626 __attribute__ ((weak, alias ("___builtin_new")));
1628 ___builtin_new (size_t sz)
1631 __builtin_new (size_t sz)
1635 vfp handler = (__new_handler) ? __new_handler : __default_new_handler;
1637 /* malloc (0) is unpredictable; avoid it. */
1640 p = (void *) malloc (sz);
1644 p = (void *) malloc (sz);
1649 #endif /* L_op_new */
1652 /* void * operator new [] (size_t), described in 17.3.3.6. This function
1653 is used by C++ programs to allocate a block of memory for an array. */
1655 extern void * __builtin_new (size_t);
1658 void * __builtin_vec_new (size_t sz)
1659 __attribute__ ((weak, alias ("___builtin_vec_new")));
1661 ___builtin_vec_new (size_t sz)
1664 __builtin_vec_new (size_t sz)
1667 return __builtin_new (sz);
1669 #endif /* L_op_vnew */
1671 #ifdef L_new_handler
1672 /* set_new_handler (fvoid_t *) and the default new handler, described in
1673 17.3.3.2 and 17.3.3.5. These functions define the result of a failure
1674 to allocate the amount of memory requested from operator new or new []. */
1676 #ifndef inhibit_libc
1677 /* This gets us __GNU_LIBRARY__. */
1678 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1681 #ifdef __GNU_LIBRARY__
1682 /* Avoid forcing the library's meaning of `write' on the user program
1683 by using the "internal" name (for use within the library) */
1684 #define write(fd, buf, n) __write((fd), (buf), (n))
1686 #endif /* inhibit_libc */
1688 typedef void (*vfp)(void);
1689 void __default_new_handler (void);
1691 vfp __new_handler = (vfp)0;
1694 set_new_handler (vfp handler)
1698 prev_handler = __new_handler;
1699 if (handler == 0) handler = __default_new_handler;
1700 __new_handler = handler;
1701 return prev_handler;
1704 #define MESSAGE "Virtual memory exceeded in `new'\n"
1707 __default_new_handler ()
1709 #ifndef inhibit_libc
1710 /* don't use fprintf (stderr, ...) because it may need to call malloc. */
1711 /* This should really print the name of the program, but that is hard to
1712 do. We need a standard, clean way to get at the name. */
1713 write (2, MESSAGE, sizeof (MESSAGE));
1715 /* don't call exit () because that may call global destructors which
1716 may cause a loop. */
1722 /* operator delete (void *), described in 17.3.3.3. This function is used
1723 by C++ programs to return to the free store a block of memory allocated
1724 as a single object. */
1727 void __builtin_delete (void *ptr)
1728 __attribute__ ((weak, alias ("___builtin_delete")));
1730 ___builtin_delete (void *ptr)
1733 __builtin_delete (void *ptr)
1742 /* operator delete [] (void *), described in 17.3.3.4. This function is
1743 used by C++ programs to return to the free store a block of memory
1744 allocated as an array. */
1746 extern void __builtin_delete (void *);
1749 void __builtin_vec_delete (void *ptr)
1750 __attribute__ ((weak, alias ("___builtin_vec_delete")));
1752 ___builtin_vec_delete (void *ptr)
1755 __builtin_vec_delete (void *ptr)
1758 __builtin_delete (ptr);
1762 /* End of C++ free-store management functions */
1765 unsigned int __shtab[] = {
1766 0x00000001, 0x00000002, 0x00000004, 0x00000008,
1767 0x00000010, 0x00000020, 0x00000040, 0x00000080,
1768 0x00000100, 0x00000200, 0x00000400, 0x00000800,
1769 0x00001000, 0x00002000, 0x00004000, 0x00008000,
1770 0x00010000, 0x00020000, 0x00040000, 0x00080000,
1771 0x00100000, 0x00200000, 0x00400000, 0x00800000,
1772 0x01000000, 0x02000000, 0x04000000, 0x08000000,
1773 0x10000000, 0x20000000, 0x40000000, 0x80000000
1777 #ifdef L_clear_cache
1778 /* Clear part of an instruction cache. */
1780 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1783 __clear_cache (beg, end)
1786 #ifdef CLEAR_INSN_CACHE
1787 CLEAR_INSN_CACHE (beg, end);
1789 #ifdef INSN_CACHE_SIZE
1790 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1791 static int initialized;
1795 typedef (*function_ptr) ();
1797 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1798 /* It's cheaper to clear the whole cache.
1799 Put in a series of jump instructions so that calling the beginning
1800 of the cache will clear the whole thing. */
1804 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1805 & -INSN_CACHE_LINE_WIDTH);
1806 int end_ptr = ptr + INSN_CACHE_SIZE;
1808 while (ptr < end_ptr)
1810 *(INSTRUCTION_TYPE *)ptr
1811 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1812 ptr += INSN_CACHE_LINE_WIDTH;
1814 *(INSTRUCTION_TYPE *)(ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1819 /* Call the beginning of the sequence. */
1820 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1821 & -INSN_CACHE_LINE_WIDTH))
1824 #else /* Cache is large. */
1828 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1829 & -INSN_CACHE_LINE_WIDTH);
1831 while (ptr < (int) array + sizeof array)
1833 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1834 ptr += INSN_CACHE_LINE_WIDTH;
1840 /* Find the location in array that occupies the same cache line as BEG. */
1842 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1843 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1844 & -INSN_CACHE_PLANE_SIZE)
1847 /* Compute the cache alignment of the place to stop clearing. */
1848 #if 0 /* This is not needed for gcc's purposes. */
1849 /* If the block to clear is bigger than a cache plane,
1850 we clear the entire cache, and OFFSET is already correct. */
1851 if (end < beg + INSN_CACHE_PLANE_SIZE)
1853 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1854 & -INSN_CACHE_LINE_WIDTH)
1855 & (INSN_CACHE_PLANE_SIZE - 1));
1857 #if INSN_CACHE_DEPTH > 1
1858 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1859 if (end_addr <= start_addr)
1860 end_addr += INSN_CACHE_PLANE_SIZE;
1862 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1864 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1865 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1867 while (addr != stop)
1869 /* Call the return instruction at ADDR. */
1870 ((function_ptr) addr) ();
1872 addr += INSN_CACHE_LINE_WIDTH;
1875 #else /* just one plane */
1878 /* Call the return instruction at START_ADDR. */
1879 ((function_ptr) start_addr) ();
1881 start_addr += INSN_CACHE_LINE_WIDTH;
1883 while ((start_addr % INSN_CACHE_SIZE) != offset);
1884 #endif /* just one plane */
1885 #endif /* Cache is large */
1886 #endif /* Cache exists */
1887 #endif /* CLEAR_INSN_CACHE */
1890 #endif /* L_clear_cache */
1894 /* Jump to a trampoline, loading the static chain address. */
1896 #ifdef TRANSFER_FROM_TRAMPOLINE
1897 TRANSFER_FROM_TRAMPOLINE
1900 #if defined (NeXT) && defined (__MACH__)
1902 /* Make stack executable so we can call trampolines on stack.
1903 This is called from INITIALIZE_TRAMPOLINE in next.h. */
1907 #include <mach/mach.h>
1911 __enable_execute_stack (addr)
1915 char *eaddr = addr + TRAMPOLINE_SIZE;
1916 vm_address_t a = (vm_address_t) addr;
1918 /* turn on execute access on stack */
1919 r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
1920 if (r != KERN_SUCCESS)
1922 mach_error("vm_protect VM_PROT_ALL", r);
1926 /* We inline the i-cache invalidation for speed */
1928 #ifdef CLEAR_INSN_CACHE
1929 CLEAR_INSN_CACHE (addr, eaddr);
1931 __clear_cache ((int) addr, (int) eaddr);
1935 #endif /* defined (NeXT) && defined (__MACH__) */
1939 /* Make stack executable so we can call trampolines on stack.
1940 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
1942 #include <sys/mman.h>
1943 #include <sys/vmparam.h>
1944 #include <machine/machparam.h>
1947 __enable_execute_stack ()
1950 static unsigned lowest = USRSTACK;
1951 unsigned current = (unsigned) &fp & -NBPG;
1953 if (lowest > current)
1955 unsigned len = lowest - current;
1956 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
1960 /* Clear instruction cache in case an old trampoline is in it. */
1963 #endif /* __convex__ */
1967 /* Modified from the convex -code above. */
1969 #include <sys/param.h>
1971 #include <sys/m88kbcs.h>
1974 __enable_execute_stack ()
1977 static unsigned long lowest = USRSTACK;
1978 unsigned long current = (unsigned long) &save_errno & -NBPC;
1980 /* Ignore errno being set. memctl sets errno to EINVAL whenever the
1981 address is seen as 'negative'. That is the case with the stack. */
1984 if (lowest > current)
1986 unsigned len=lowest-current;
1987 memctl(current,len,MCT_TEXT);
1991 memctl(current,NBPC,MCT_TEXT);
1995 #endif /* __DOLPHIN__ */
1999 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2001 #include <sys/mman.h>
2002 #include <sys/types.h>
2003 #include <sys/param.h>
2004 #include <sys/vmmac.h>
2006 /* Modified from the convex -code above.
2007 mremap promises to clear the i-cache. */
2010 __enable_execute_stack ()
2013 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
2014 PROT_READ|PROT_WRITE|PROT_EXEC))
2016 perror ("mprotect in __enable_execute_stack");
2021 #endif /* __pyr__ */
2022 #endif /* L_trampoline */
2026 #include "gbl-ctors.h"
2027 /* Some systems use __main in a way incompatible with its use in gcc, in these
2028 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2029 give the same symbol without quotes for an alternative entry point. You
2030 must define both, or neither. */
2032 #define NAME__MAIN "__main"
2033 #define SYMBOL__MAIN __main
2036 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2037 /* Run all the global destructors on exit from the program. */
2040 __do_global_dtors ()
2042 #ifdef DO_GLOBAL_DTORS_BODY
2043 DO_GLOBAL_DTORS_BODY;
2046 for (p = __DTOR_LIST__ + 1; *p; )
2052 #ifndef INIT_SECTION_ASM_OP
2053 /* Run all the global constructors on entry to the program. */
2056 #define ON_EXIT(a, b)
2058 /* Make sure the exit routine is pulled in to define the globals as
2059 bss symbols, just in case the linker does not automatically pull
2060 bss definitions from the library. */
2062 extern int _exit_dummy_decl;
2063 int *_exit_dummy_ref = &_exit_dummy_decl;
2064 #endif /* ON_EXIT */
2067 __do_global_ctors ()
2069 DO_GLOBAL_CTORS_BODY;
2070 ON_EXIT (__do_global_dtors, 0);
2072 #endif /* no INIT_SECTION_ASM_OP */
2074 #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
2075 /* Subroutine called automatically by `main'.
2076 Compiling a global function named `main'
2077 produces an automatic call to this function at the beginning.
2079 For many systems, this routine calls __do_global_ctors.
2080 For systems which support a .init section we use the .init section
2081 to run __do_global_ctors, so we need not do anything here. */
2086 /* Support recursive calls to `main': run initializers just once. */
2087 static int initialized;
2091 __do_global_ctors ();
2094 #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
2096 #endif /* L__main */
2100 #include "gbl-ctors.h"
2102 /* Provide default definitions for the lists of constructors and
2103 destructors, so that we don't get linker errors. These symbols are
2104 intentionally bss symbols, so that gld and/or collect will provide
2105 the right values. */
2107 /* We declare the lists here with two elements each,
2108 so that they are valid empty lists if no other definition is loaded. */
2109 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
2111 /* After 2.3, try this definition on all systems. */
2112 func_ptr __CTOR_LIST__[2] = {0, 0};
2113 func_ptr __DTOR_LIST__[2] = {0, 0};
2115 func_ptr __CTOR_LIST__[2];
2116 func_ptr __DTOR_LIST__[2];
2118 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
2119 #endif /* L_ctors */
2123 #include "gbl-ctors.h"
2127 /* If we have no known way of registering our own __do_global_dtors
2128 routine so that it will be invoked at program exit time, then we
2129 have to define our own exit routine which will get this to happen. */
2131 extern void __do_global_dtors ();
2132 extern void _cleanup ();
2133 extern void _exit () __attribute__ ((noreturn));
2139 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2140 __do_global_dtors ();
2151 int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */
2160 void *exception_handler;
2163 struct exception_table_node {
2164 exception_table *table;
2167 struct exception_table_node *next;
2170 static int except_table_pos;
2171 static void *except_pc;
2172 static struct exception_table_node *exception_table_list;
2174 static exception_table *
2175 find_exception_table (pc)
2178 register struct exception_table_node *table = exception_table_list;
2179 for ( ; table != 0; table = table->next)
2181 if (table->start <= pc && table->end > pc)
2182 return table->table;
2187 /* this routine takes a pc, and the address of the exception handler associated
2188 with the closest exception table handler entry associated with that PC,
2189 or 0 if there are no table entries the PC fits in. The algorithm works
2190 something like this:
2192 while(current_entry exists) {
2193 if(current_entry.start < pc )
2194 current_entry = next_entry;
2196 if(prev_entry.start <= pc && prev_entry.end > pc) {
2197 save pointer to prev_entry;
2198 return prev_entry.exception_handler;
2205 Assuming a correctly sorted table (ascending order) this routine should
2206 return the tighest match...
2208 In the advent of a tie, we have to give the last entry, as it represents
2214 __find_first_exception_table_match(pc)
2217 exception_table *table = find_exception_table (pc);
2223 printf("find_first_exception_table_match(): pc = %x!\n",pc);
2229 /* We can't do this yet, as we don't know that the table is sorted. */
2232 if (table[pos].start > except_pc)
2233 /* found the first table[pos].start > except_pc, so the previous
2234 entry better be the one we want! */
2236 } while(table[pos].exception_handler != (void*)-1);
2239 if (table[pos].start <= except_pc && table[pos].end > except_pc)
2241 except_table_pos = pos;
2243 printf("find_first_eh_table_match(): found match: %x\n",table[pos].exception_handler);
2245 return table[pos].exception_handler;
2248 while (table[++pos].exception_handler != (void*)-1) {
2249 if (table[pos].start <= except_pc && table[pos].end > except_pc)
2251 /* This can apply. Make sure it is better or as good as the previous
2253 /* The best one ends first. */
2254 if (best == 0 || (table[pos].end <= table[best].end
2255 /* The best one starts last. */
2256 && table[pos].start >= table[best].start))
2261 return table[best].exception_handler;
2265 printf("find_first_eh_table_match(): else: returning NULL!\n");
2271 __throw_type_match (void *catch_type, void *throw_type, void* obj)
2274 printf("__throw_type_match (): catch_type = %s, throw_type = %s\n",
2275 catch_type, throw_type);
2277 if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)
2283 __register_exceptions (exception_table *table)
2285 struct exception_table_node *node;
2286 exception_table *range = table + 1;
2288 if (range->start == (void*)-1)
2291 node = (struct exception_table_node*)
2292 malloc (sizeof (struct exception_table_node));
2293 node->table = table;
2295 /* This look can be optimized away either if the table
2296 is sorted, or if we pass in extra parameters. */
2297 node->start = range->start;
2298 node->end = range->end;
2299 for (range++ ; range->start != (void*)(-1); range++)
2301 if (range->start < node->start)
2302 node->start = range->start;
2303 if (range->end > node->end)
2304 node->end = range->end;
2307 node->next = exception_table_list;
2308 exception_table_list = node;
2313 __unwind_function(void *ptr)
2315 asm("movl 8(%esp),%ecx");
2316 /* Undo current frame */
2317 asm("movl %ebp,%esp");
2319 /* like ret, but stay here */
2320 asm("addl $4,%esp");
2322 /* Now, undo previous frame. */
2323 /* This is a test routine, as we have to dynamically probe to find out
2324 what to pop for certain, this is just a guess. */
2325 asm("leal -16(%ebp),%esp");
2326 asm("pop %eax"); /* really for popl %ebx */
2327 asm("pop %eax"); /* really for popl %esi */
2328 asm("pop %eax"); /* really for popl %edi */
2329 asm("movl %ebp,%esp");
2332 asm("movl %ecx,0(%esp)");
2337 #if #machine(rs6000)
2338 __unwind_function(void *ptr)
2347 /* use 31 as a scratch register to restore the link register. */
2348 asm("l 31, 8(1);mtlr 31 # l lr,8(1)");
2351 asm("mtctr 3;bctr # b 3");
2355 #if #machine(powerpc)
2356 __unwind_function(void *ptr)
2360 asm("lwz 31,-4(1)");
2365 /* use 31 as a scratch register to restore the link register. */
2366 asm("lwz 31, 8(1);mtlr 31 # l lr,8(1)");
2367 asm("lwz 31,-4(1)");
2369 asm("mtctr 3;bctr # b 3");
2371 #endif /* powerpc */
2375 #ifndef inhibit_libc
2376 /* This gets us __GNU_LIBRARY__. */
2377 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2380 #ifdef __GNU_LIBRARY__
2381 /* Avoid forcing the library's meaning of `write' on the user program
2382 by using the "internal" name (for use within the library) */
2383 #define write(fd, buf, n) __write((fd), (buf), (n))
2385 #endif /* inhibit_libc */
2387 #define MESSAGE "pure virtual method called\n"
2392 #ifndef inhibit_libc
2393 write (2, MESSAGE, sizeof (MESSAGE) - 1);