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
.high
= (USItype
)uu
.s
.low
<< -bm
;
171 USItype carries
= (USItype
)uu
.s
.low
>> bm
;
172 w
.s
.low
= (USItype
)uu
.s
.low
<< b
;
173 w
.s
.high
= ((USItype
)uu
.s
.high
<< b
) | carries
;
195 bm
= (sizeof (SItype
) * BITS_PER_UNIT
) - b
;
199 w
.s
.low
= (USItype
)uu
.s
.high
>> -bm
;
203 USItype carries
= (USItype
)uu
.s
.high
<< bm
;
204 w
.s
.high
= (USItype
)uu
.s
.high
>> b
;
205 w
.s
.low
= ((USItype
)uu
.s
.low
>> b
) | carries
;
227 bm
= (sizeof (SItype
) * BITS_PER_UNIT
) - b
;
231 w
.s
.high
= (USItype
)uu
.s
.low
<< -bm
;
235 USItype carries
= (USItype
)uu
.s
.low
>> bm
;
236 w
.s
.low
= (USItype
)uu
.s
.low
<< b
;
237 w
.s
.high
= ((USItype
)uu
.s
.high
<< b
) | carries
;
259 bm
= (sizeof (SItype
) * BITS_PER_UNIT
) - b
;
262 /* w.s.high = 1..1 or 0..0 */
263 w
.s
.high
= uu
.s
.high
>> (sizeof (SItype
) * BITS_PER_UNIT
- 1);
264 w
.s
.low
= uu
.s
.high
>> -bm
;
268 USItype carries
= (USItype
)uu
.s
.high
<< bm
;
269 w
.s
.high
= uu
.s
.high
>> b
;
270 w
.s
.low
= ((USItype
)uu
.s
.low
>> b
) | carries
;
285 w
.s
.low
= ffs (uu
.s
.low
);
288 w
.s
.low
= ffs (uu
.s
.high
);
291 w
.s
.low
+= BITS_PER_UNIT
* sizeof (SItype
);
309 w
.ll
= __umulsidi3 (uu
.s
.low
, vv
.s
.low
);
310 w
.s
.high
+= ((USItype
) uu
.s
.low
* (USItype
) vv
.s
.high
311 + (USItype
) uu
.s
.high
* (USItype
) vv
.s
.low
);
319 __udiv_w_sdiv (rp
, a1
, a0
, d
)
320 USItype
*rp
, a1
, a0
, d
;
327 if (a1
< d
- a1
- (a0
>> (SI_TYPE_SIZE
- 1)))
329 /* dividend, divisor, and quotient are nonnegative */
330 sdiv_qrnnd (q
, r
, a1
, a0
, d
);
334 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
335 sub_ddmmss (c1
, c0
, a1
, a0
, d
>> 1, d
<< (SI_TYPE_SIZE
- 1));
336 /* Divide (c1*2^32 + c0) by d */
337 sdiv_qrnnd (q
, r
, c1
, c0
, d
);
338 /* Add 2^31 to quotient */
339 q
+= (USItype
) 1 << (SI_TYPE_SIZE
- 1);
344 b1
= d
>> 1; /* d/2, between 2^30 and 2^31 - 1 */
345 c1
= a1
>> 1; /* A/2 */
346 c0
= (a1
<< (SI_TYPE_SIZE
- 1)) + (a0
>> 1);
348 if (a1
< b1
) /* A < 2^32*b1, so A/2 < 2^31*b1 */
350 sdiv_qrnnd (q
, r
, c1
, c0
, b1
); /* (A/2) / (d/2) */
352 r
= 2*r
+ (a0
& 1); /* Remainder from A/(2*b1) */
369 else if (c1
< b1
) /* So 2^31 <= (A/2)/b1 < 2^32 */
372 c0
= ~c0
; /* logical NOT */
374 sdiv_qrnnd (q
, r
, c1
, c0
, b1
); /* (A/2) / (d/2) */
376 q
= ~q
; /* (A/2)/b1 */
379 r
= 2*r
+ (a0
& 1); /* A/(2*b1) */
397 else /* Implies c1 = b1 */
398 { /* Hence a1 = d - 1 = 2*b1 - 1 */
418 static const UQItype __clz_tab
[] =
420 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,
421 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,
422 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,
423 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,
424 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,
425 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,
426 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,
427 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,
431 __udivmoddi4 (n
, d
, rp
)
438 USItype d0
, d1
, n0
, n1
, n2
;
450 #if !UDIV_NEEDS_NORMALIZATION
457 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
460 /* Remainder in n0. */
467 d0
= 1 / d0
; /* Divide intentionally by zero. */
469 udiv_qrnnd (q1
, n1
, 0, n1
, d0
);
470 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
472 /* Remainder in n0. */
483 #else /* UDIV_NEEDS_NORMALIZATION */
491 count_leading_zeros (bm
, d0
);
495 /* Normalize, i.e. make the most significant bit of the
499 n1
= (n1
<< bm
) | (n0
>> (SI_TYPE_SIZE
- bm
));
503 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
506 /* Remainder in n0 >> bm. */
513 d0
= 1 / d0
; /* Divide intentionally by zero. */
515 count_leading_zeros (bm
, d0
);
519 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
520 conclude (the most significant bit of n1 is set) /\ (the
521 leading quotient digit q1 = 1).
523 This special case is necessary, not an optimization.
524 (Shifts counts of SI_TYPE_SIZE are undefined.) */
533 b
= SI_TYPE_SIZE
- bm
;
537 n1
= (n1
<< bm
) | (n0
>> b
);
540 udiv_qrnnd (q1
, n1
, n2
, n1
, d0
);
545 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
547 /* Remainder in n0 >> bm. */
557 #endif /* UDIV_NEEDS_NORMALIZATION */
568 /* Remainder in n1n0. */
580 count_leading_zeros (bm
, d1
);
583 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
584 conclude (the most significant bit of n1 is set) /\ (the
585 quotient digit q0 = 0 or 1).
587 This special case is necessary, not an optimization. */
589 /* The condition on the next line takes advantage of that
590 n1 >= d1 (true due to program flow). */
591 if (n1
> d1
|| n0
>= d0
)
594 sub_ddmmss (n1
, n0
, n1
, n0
, d1
, d0
);
613 b
= SI_TYPE_SIZE
- bm
;
615 d1
= (d1
<< bm
) | (d0
>> b
);
618 n1
= (n1
<< bm
) | (n0
>> b
);
621 udiv_qrnnd (q0
, n1
, n2
, n1
, d1
);
622 umul_ppmm (m1
, m0
, q0
, d0
);
624 if (m1
> n1
|| (m1
== n1
&& m0
> n0
))
627 sub_ddmmss (m1
, m0
, m1
, m0
, d1
, d0
);
632 /* Remainder in (n1n0 - m1m0) >> bm. */
635 sub_ddmmss (n1
, n0
, n1
, n0
, m1
, m0
);
636 rr
.s
.low
= (n1
<< b
) | (n0
>> bm
);
637 rr
.s
.high
= n1
>> bm
;
651 UDItype
__udivmoddi4 ();
666 uu
.ll
= __negdi2 (uu
.ll
);
669 vv
.ll
= __negdi2 (vv
.ll
);
671 w
= __udivmoddi4 (uu
.ll
, vv
.ll
, (UDItype
*) 0);
680 UDItype
__udivmoddi4 ();
694 uu
.ll
= __negdi2 (uu
.ll
);
696 vv
.ll
= __negdi2 (vv
.ll
);
698 (void) __udivmoddi4 (uu
.ll
, vv
.ll
, &w
);
707 UDItype
__udivmoddi4 ();
714 (void) __udivmoddi4 (u
, v
, &w
);
721 UDItype
__udivmoddi4 ();
726 return __udivmoddi4 (n
, d
, (UDItype
*) 0);
737 au
.ll
= a
, bu
.ll
= b
;
739 if (au
.s
.high
< bu
.s
.high
)
741 else if (au
.s
.high
> bu
.s
.high
)
743 if ((USItype
) au
.s
.low
< (USItype
) bu
.s
.low
)
745 else if ((USItype
) au
.s
.low
> (USItype
) bu
.s
.low
)
758 au
.ll
= a
, bu
.ll
= b
;
760 if ((USItype
) au
.s
.high
< (USItype
) bu
.s
.high
)
762 else if ((USItype
) au
.s
.high
> (USItype
) bu
.s
.high
)
764 if ((USItype
) au
.s
.low
< (USItype
) bu
.s
.low
)
766 else if ((USItype
) au
.s
.low
> (USItype
) bu
.s
.low
)
772 #if defined(L_fixunstfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
773 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
774 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
786 /* Compute high word of result, as a flonum. */
787 b
= (a
/ HIGH_WORD_COEFF
);
788 /* Convert that to fixed (but not to DItype!),
789 and shift it into the high word. */
792 /* Remove high part from the TFtype, leaving the low part as flonum. */
794 /* Convert that to fixed (but not to DItype!) and add it in.
795 Sometimes A comes out negative. This is significant, since
796 A has more bits than a long int does. */
798 v
-= (USItype
) (- a
);
805 #if defined(L_fixtfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
811 return - __fixunstfdi (-a
);
812 return __fixunstfdi (a
);
816 #if defined(L_fixunsxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
817 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
818 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
830 /* Compute high word of result, as a flonum. */
831 b
= (a
/ HIGH_WORD_COEFF
);
832 /* Convert that to fixed (but not to DItype!),
833 and shift it into the high word. */
836 /* Remove high part from the XFtype, leaving the low part as flonum. */
838 /* Convert that to fixed (but not to DItype!) and add it in.
839 Sometimes A comes out negative. This is significant, since
840 A has more bits than a long int does. */
842 v
-= (USItype
) (- a
);
849 #if defined(L_fixxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
855 return - __fixunsxfdi (-a
);
856 return __fixunsxfdi (a
);
861 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
862 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
874 /* Compute high word of result, as a flonum. */
875 b
= (a
/ HIGH_WORD_COEFF
);
876 /* Convert that to fixed (but not to DItype!),
877 and shift it into the high word. */
880 /* Remove high part from the DFtype, leaving the low part as flonum. */
882 /* Convert that to fixed (but not to DItype!) and add it in.
883 Sometimes A comes out negative. This is significant, since
884 A has more bits than a long int does. */
886 v
-= (USItype
) (- a
);
899 return - __fixunsdfdi (-a
);
900 return __fixunsdfdi (a
);
905 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
906 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
909 __fixunssfdi (SFtype original_a
)
911 /* Convert the SFtype to a DFtype, because that is surely not going
912 to lose any bits. Some day someone else can write a faster version
913 that avoids converting to DFtype, and verify it really works right. */
914 DFtype a
= original_a
;
921 /* Compute high word of result, as a flonum. */
922 b
= (a
/ HIGH_WORD_COEFF
);
923 /* Convert that to fixed (but not to DItype!),
924 and shift it into the high word. */
927 /* Remove high part from the DFtype, leaving the low part as flonum. */
929 /* Convert that to fixed (but not to DItype!) and add it in.
930 Sometimes A comes out negative. This is significant, since
931 A has more bits than a long int does. */
933 v
-= (USItype
) (- a
);
945 return - __fixunssfdi (-a
);
946 return __fixunssfdi (a
);
950 #if defined(L_floatdixf) && (LONG_DOUBLE_TYPE_SIZE == 96)
951 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
952 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
953 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
965 d
= (USItype
) (u
>> WORD_SIZE
);
966 d
*= HIGH_HALFWORD_COEFF
;
967 d
*= HIGH_HALFWORD_COEFF
;
968 d
+= (USItype
) (u
& (HIGH_WORD_COEFF
- 1));
970 return (negate
? -d
: d
);
974 #if defined(L_floatditf) && (LONG_DOUBLE_TYPE_SIZE == 128)
975 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
976 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
977 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
989 d
= (USItype
) (u
>> WORD_SIZE
);
990 d
*= HIGH_HALFWORD_COEFF
;
991 d
*= HIGH_HALFWORD_COEFF
;
992 d
+= (USItype
) (u
& (HIGH_WORD_COEFF
- 1));
994 return (negate
? -d
: d
);
999 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
1000 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
1001 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
1013 d
= (USItype
) (u
>> WORD_SIZE
);
1014 d
*= HIGH_HALFWORD_COEFF
;
1015 d
*= HIGH_HALFWORD_COEFF
;
1016 d
+= (USItype
) (u
& (HIGH_WORD_COEFF
- 1));
1018 return (negate
? -d
: d
);
1023 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
1024 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
1025 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
1026 #define DI_SIZE (sizeof (DItype) * BITS_PER_UNIT)
1027 #if TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1031 #if TARGET_FLOAT_FORMAT == IBM_FLOAT_FORMAT
1035 #if TARGET_FLOAT_FORMAT == VAX_FLOAT_FORMAT
1050 /* Do the calculation in DFmode
1051 so that we don't lose any of the precision of the high word
1052 while multiplying it. */
1059 /* Protect against double-rounding error.
1060 Represent any low-order bits, that might be truncated in DFmode,
1061 by a bit that won't be lost. The bit can go in anywhere below the
1062 rounding position of the SFmode. A fixed mask and bit position
1063 handles all usual configurations. It doesn't handle the case
1064 of 128-bit DImode, however. */
1065 if (DF_SIZE
< DI_SIZE
1066 && DF_SIZE
> (DI_SIZE
- DF_SIZE
+ SF_SIZE
))
1068 #define REP_BIT ((USItype) 1 << (DI_SIZE - DF_SIZE))
1069 if (u
>= ((UDItype
) 1 << DF_SIZE
))
1071 if ((USItype
) u
& (REP_BIT
- 1))
1075 f
= (USItype
) (u
>> WORD_SIZE
);
1076 f
*= HIGH_HALFWORD_COEFF
;
1077 f
*= HIGH_HALFWORD_COEFF
;
1078 f
+= (USItype
) (u
& (HIGH_WORD_COEFF
- 1));
1080 return (SFtype
) (negate
? -f
: f
);
1084 #if defined(L_fixunsxfsi) && LONG_DOUBLE_TYPE_SIZE == 96
1085 #include "glimits.h"
1091 if (a
>= - (DFtype
) LONG_MIN
)
1092 return (SItype
) (a
+ LONG_MIN
) - LONG_MIN
;
1098 #include "glimits.h"
1104 if (a
>= - (DFtype
) LONG_MIN
)
1105 return (SItype
) (a
+ LONG_MIN
) - LONG_MIN
;
1111 #include "glimits.h"
1114 __fixunssfsi (SFtype a
)
1116 if (a
>= - (SFtype
) LONG_MIN
)
1117 return (SItype
) (a
+ LONG_MIN
) - LONG_MIN
;
1122 /* From here on down, the routines use normal data types. */
1124 #define SItype bogus_type
1125 #define USItype bogus_type
1126 #define DItype bogus_type
1127 #define UDItype bogus_type
1128 #define SFtype bogus_type
1129 #define DFtype bogus_type
1141 /* Like bcmp except the sign is meaningful.
1142 Reult is negative if S1 is less than S2,
1143 positive if S1 is greater, 0 if S1 and S2 are equal. */
1146 __gcc_bcmp (s1
, s2
, size
)
1147 unsigned char *s1
, *s2
;
1152 unsigned char c1
= *s1
++, c2
= *s2
++;
1164 #if defined(__svr4__) || defined(__alliant__)
1168 /* The Alliant needs the added underscore. */
1169 asm (".globl __builtin_saveregs");
1170 asm ("__builtin_saveregs:");
1171 asm (".globl ___builtin_saveregs");
1172 asm ("___builtin_saveregs:");
1174 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
1175 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
1176 area and also for a new va_list
1178 /* Save all argument registers in the arg reg save area. The
1179 arg reg save area must have the following layout (according
1191 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
1192 asm (" fst.q %f12,16(%sp)");
1194 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
1195 asm (" st.l %r17,36(%sp)");
1196 asm (" st.l %r18,40(%sp)");
1197 asm (" st.l %r19,44(%sp)");
1198 asm (" st.l %r20,48(%sp)");
1199 asm (" st.l %r21,52(%sp)");
1200 asm (" st.l %r22,56(%sp)");
1201 asm (" st.l %r23,60(%sp)");
1202 asm (" st.l %r24,64(%sp)");
1203 asm (" st.l %r25,68(%sp)");
1204 asm (" st.l %r26,72(%sp)");
1205 asm (" st.l %r27,76(%sp)");
1207 asm (" adds 80,%sp,%r16"); /* compute the address of the new
1208 va_list structure. Put in into
1209 r16 so that it will be returned
1212 /* Initialize all fields of the new va_list structure. This
1213 structure looks like:
1216 unsigned long ireg_used;
1217 unsigned long freg_used;
1223 asm (" st.l %r0, 0(%r16)"); /* nfixed */
1224 asm (" st.l %r0, 4(%r16)"); /* nfloating */
1225 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
1226 asm (" bri %r1"); /* delayed return */
1227 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
1229 #else /* not __svr4__ */
1230 #if defined(__PARAGON__)
1232 * we'll use SVR4-ish varargs but need SVR3.2 assembler syntax,
1233 * and we stand a better chance of hooking into libraries
1234 * compiled by PGI. [andyp@ssd.intel.com]
1238 asm (".globl __builtin_saveregs");
1239 asm ("__builtin_saveregs:");
1240 asm (".globl ___builtin_saveregs");
1241 asm ("___builtin_saveregs:");
1243 asm (" andnot 0x0f,sp,sp"); /* round down to 16-byte boundary */
1244 asm (" adds -96,sp,sp"); /* allocate stack space for reg save
1245 area and also for a new va_list
1247 /* Save all argument registers in the arg reg save area. The
1248 arg reg save area must have the following layout (according
1260 asm (" fst.q f8, 0(sp)");
1261 asm (" fst.q f12,16(sp)");
1262 asm (" st.l r16,32(sp)");
1263 asm (" st.l r17,36(sp)");
1264 asm (" st.l r18,40(sp)");
1265 asm (" st.l r19,44(sp)");
1266 asm (" st.l r20,48(sp)");
1267 asm (" st.l r21,52(sp)");
1268 asm (" st.l r22,56(sp)");
1269 asm (" st.l r23,60(sp)");
1270 asm (" st.l r24,64(sp)");
1271 asm (" st.l r25,68(sp)");
1272 asm (" st.l r26,72(sp)");
1273 asm (" st.l r27,76(sp)");
1275 asm (" adds 80,sp,r16"); /* compute the address of the new
1276 va_list structure. Put in into
1277 r16 so that it will be returned
1280 /* Initialize all fields of the new va_list structure. This
1281 structure looks like:
1284 unsigned long ireg_used;
1285 unsigned long freg_used;
1291 asm (" st.l r0, 0(r16)"); /* nfixed */
1292 asm (" st.l r0, 4(r16)"); /* nfloating */
1293 asm (" st.l sp, 8(r16)"); /* __va_ctl points to __va_struct. */
1294 asm (" bri r1"); /* delayed return */
1295 asm (" st.l r28,12(r16)"); /* pointer to overflow args */
1296 #else /* not __PARAGON__ */
1300 asm (".globl ___builtin_saveregs");
1301 asm ("___builtin_saveregs:");
1302 asm (" mov sp,r30");
1303 asm (" andnot 0x0f,sp,sp");
1304 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
1306 /* Fill in the __va_struct. */
1307 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
1308 asm (" st.l r17, 4(sp)"); /* int fixed[12] */
1309 asm (" st.l r18, 8(sp)");
1310 asm (" st.l r19,12(sp)");
1311 asm (" st.l r20,16(sp)");
1312 asm (" st.l r21,20(sp)");
1313 asm (" st.l r22,24(sp)");
1314 asm (" st.l r23,28(sp)");
1315 asm (" st.l r24,32(sp)");
1316 asm (" st.l r25,36(sp)");
1317 asm (" st.l r26,40(sp)");
1318 asm (" st.l r27,44(sp)");
1320 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
1321 asm (" fst.q f12,64(sp)"); /* int floating[8] */
1323 /* Fill in the __va_ctl. */
1324 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
1325 asm (" st.l r28,84(sp)"); /* pointer to more args */
1326 asm (" st.l r0, 88(sp)"); /* nfixed */
1327 asm (" st.l r0, 92(sp)"); /* nfloating */
1329 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
1331 asm (" mov r30,sp");
1332 /* recover stack and pass address to start
1334 #endif /* not __PARAGON__ */
1335 #endif /* not __svr4__ */
1336 #else /* not __i860__ */
1338 asm (".global __builtin_saveregs");
1339 asm ("__builtin_saveregs:");
1340 asm (".global ___builtin_saveregs");
1341 asm ("___builtin_saveregs:");
1342 #ifdef NEED_PROC_COMMAND
1345 asm ("st %i0,[%fp+68]");
1346 asm ("st %i1,[%fp+72]");
1347 asm ("st %i2,[%fp+76]");
1348 asm ("st %i3,[%fp+80]");
1349 asm ("st %i4,[%fp+84]");
1351 asm ("st %i5,[%fp+88]");
1352 #ifdef NEED_TYPE_COMMAND
1353 asm (".type __builtin_saveregs,#function");
1354 asm (".size __builtin_saveregs,.-__builtin_saveregs");
1356 #else /* not __sparc__ */
1357 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1360 asm (" .ent __builtin_saveregs");
1361 asm (" .globl __builtin_saveregs");
1362 asm ("__builtin_saveregs:");
1363 asm (" sw $4,0($30)");
1364 asm (" sw $5,4($30)");
1365 asm (" sw $6,8($30)");
1366 asm (" sw $7,12($30)");
1368 asm (" .end __builtin_saveregs");
1369 #else /* not __mips__, etc. */
1372 __builtin_saveregs ()
1377 #endif /* not __mips__ */
1378 #endif /* not __sparc__ */
1379 #endif /* not __i860__ */
1383 #ifndef inhibit_libc
1385 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1387 /* This is used by the `assert' macro. */
1389 __eprintf (string
, expression
, line
, filename
)
1391 const char *expression
;
1393 const char *filename
;
1395 fprintf (stderr
, string
, expression
, line
, filename
);
1405 /* Structure emitted by -a */
1409 const char *filename
;
1413 const unsigned long *addresses
;
1415 /* Older GCC's did not emit these fields. */
1417 const char **functions
;
1418 const long *line_nums
;
1419 const char **filenames
;
1422 #ifdef BLOCK_PROFILER_CODE
1425 #ifndef inhibit_libc
1427 /* Simple minded basic block profiling output dumper for
1428 systems that don't provde tcov support. At present,
1429 it requires atexit and stdio. */
1431 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1436 extern void atexit (void (*) (void));
1437 #define ON_EXIT(FUNC,ARG) atexit ((FUNC))
1440 extern void on_exit (void*, void*);
1441 #define ON_EXIT(FUNC,ARG) on_exit ((FUNC), (ARG))
1445 static struct bb
*bb_head
= (struct bb
*)0;
1447 /* Return the number of digits needed to print a value */
1448 /* __inline__ */ static int num_digits (long value
, int base
)
1450 int minus
= (value
< 0 && base
!= 16);
1451 unsigned long v
= (minus
) ? -value
: value
;
1465 __bb_exit_func (void)
1467 FILE *file
= fopen ("bb.out", "a");
1477 /* This is somewhat type incorrect, but it avoids worrying about
1478 exactly where time.h is included from. It should be ok unless
1479 a void * differs from other pointer formats, or if sizeof(long)
1480 is < sizeof (time_t). It would be nice if we could assume the
1481 use of rationale standards here. */
1483 time((void *) &time_value
);
1484 fprintf (file
, "Basic block profiling finished on %s\n", ctime ((void *) &time_value
));
1486 /* We check the length field explicitly in order to allow compatibility
1487 with older GCC's which did not provide it. */
1489 for (ptr
= bb_head
; ptr
!= (struct bb
*)0; ptr
= ptr
->next
)
1492 int func_p
= (ptr
->nwords
>= sizeof (struct bb
) && ptr
->nwords
<= 1000);
1493 int line_p
= (func_p
&& ptr
->line_nums
);
1494 int file_p
= (func_p
&& ptr
->filenames
);
1495 long ncounts
= ptr
->ncounts
;
1501 int blk_len
= num_digits (ncounts
, 10);
1506 fprintf (file
, "File %s, %ld basic blocks \n\n",
1507 ptr
->filename
, ncounts
);
1509 /* Get max values for each field. */
1510 for (i
= 0; i
< ncounts
; i
++)
1515 if (cnt_max
< ptr
->counts
[i
])
1516 cnt_max
= ptr
->counts
[i
];
1518 if (addr_max
< ptr
->addresses
[i
])
1519 addr_max
= ptr
->addresses
[i
];
1521 if (line_p
&& line_max
< ptr
->line_nums
[i
])
1522 line_max
= ptr
->line_nums
[i
];
1526 p
= (ptr
->functions
[i
]) ? (ptr
->functions
[i
]) : "<none>";
1534 p
= (ptr
->filenames
[i
]) ? (ptr
->filenames
[i
]) : "<none>";
1541 addr_len
= num_digits (addr_max
, 16);
1542 cnt_len
= num_digits (cnt_max
, 10);
1543 line_len
= num_digits (line_max
, 10);
1545 /* Now print out the basic block information. */
1546 for (i
= 0; i
< ncounts
; i
++)
1549 " Block #%*d: executed %*ld time(s) address= 0x%.*lx",
1551 cnt_len
, ptr
->counts
[i
],
1552 addr_len
, ptr
->addresses
[i
]);
1555 fprintf (file
, " function= %-*s", func_len
,
1556 (ptr
->functions
[i
]) ? ptr
->functions
[i
] : "<none>");
1559 fprintf (file
, " line= %*ld", line_len
, ptr
->line_nums
[i
]);
1562 fprintf (file
, " file= %s",
1563 (ptr
->filenames
[i
]) ? ptr
->filenames
[i
] : "<none>");
1565 fprintf (file
, "\n");
1568 fprintf (file
, "\n");
1572 fprintf (file
, "\n\n");
1578 __bb_init_func (struct bb
*blocks
)
1580 /* User is supposed to check whether the first word is non-0,
1581 but just in case.... */
1583 if (blocks
->zero_word
)
1587 /* Initialize destructor. */
1589 ON_EXIT (__bb_exit_func
, 0);
1592 /* Set up linked list. */
1593 blocks
->zero_word
= 1;
1594 blocks
->next
= bb_head
;
1598 #endif /* not inhibit_libc */
1599 #endif /* not BLOCK_PROFILER_CODE */
1602 /* Default free-store management functions for C++, per sections 12.5 and
1603 17.3.3 of the Working Paper. */
1606 /* operator new (size_t), described in 17.3.3.5. This function is used by
1607 C++ programs to allocate a block of memory to hold a single object. */
1609 typedef void (*vfp
)(void);
1610 extern vfp __new_handler
;
1613 __builtin_new (size_t sz
)
1617 /* malloc (0) is unpredictable; avoid it. */
1620 p
= (void *) malloc (sz
);
1623 (*__new_handler
) ();
1624 p
= (void *) malloc (sz
);
1629 #endif /* L_op_new */
1632 /* void * operator new [] (size_t), described in 17.3.3.6. This function
1633 is used by C++ programs to allocate a block of memory for an array. */
1635 extern void * __builtin_new (size_t);
1638 __builtin_vec_new (size_t sz
)
1640 return __builtin_new (sz
);
1642 #endif /* L_op_vnew */
1644 #ifdef L_new_handler
1645 /* set_new_handler (fvoid_t *) and the default new handler, described in
1646 17.3.3.2 and 17.3.3.5. These functions define the result of a failure
1647 to allocate the amount of memory requested from operator new or new []. */
1649 #ifndef inhibit_libc
1650 /* This gets us __GNU_LIBRARY__. */
1651 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1654 #ifdef __GNU_LIBRARY__
1655 /* Avoid forcing the library's meaning of `write' on the user program
1656 by using the "internal" name (for use within the library) */
1657 #define write(fd, buf, n) __write((fd), (buf), (n))
1659 #endif /* inhibit_libc */
1661 typedef void (*vfp
)(void);
1662 void __default_new_handler (void);
1664 vfp __new_handler
= __default_new_handler
;
1667 set_new_handler (vfp handler
)
1671 prev_handler
= __new_handler
;
1672 if (handler
== 0) handler
= __default_new_handler
;
1673 __new_handler
= handler
;
1674 return prev_handler
;
1677 #define MESSAGE "Virtual memory exceeded in `new'\n"
1680 __default_new_handler ()
1682 /* don't use fprintf (stderr, ...) because it may need to call malloc. */
1683 /* This should really print the name of the program, but that is hard to
1684 do. We need a standard, clean way to get at the name. */
1685 write (2, MESSAGE
, sizeof (MESSAGE
));
1686 /* don't call exit () because that may call global destructors which
1687 may cause a loop. */
1693 /* operator delete (void *), described in 17.3.3.3. This function is used
1694 by C++ programs to return to the free store a block of memory allocated
1695 as a single object. */
1698 __builtin_delete (void *ptr
)
1706 /* operator delete [] (void *), described in 17.3.3.4. This function is
1707 used by C++ programs to return to the free store a block of memory
1708 allocated as an array. */
1710 extern void __builtin_delete (void *);
1713 __builtin_vec_delete (void *ptr
)
1715 __builtin_delete (ptr
);
1719 /* End of C++ free-store management functions */
1722 unsigned int __shtab
[] = {
1723 0x00000001, 0x00000002, 0x00000004, 0x00000008,
1724 0x00000010, 0x00000020, 0x00000040, 0x00000080,
1725 0x00000100, 0x00000200, 0x00000400, 0x00000800,
1726 0x00001000, 0x00002000, 0x00004000, 0x00008000,
1727 0x00010000, 0x00020000, 0x00040000, 0x00080000,
1728 0x00100000, 0x00200000, 0x00400000, 0x00800000,
1729 0x01000000, 0x02000000, 0x04000000, 0x08000000,
1730 0x10000000, 0x20000000, 0x40000000, 0x80000000
1734 #ifdef L_clear_cache
1735 /* Clear part of an instruction cache. */
1737 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1740 __clear_cache (beg
, end
)
1743 #ifdef CLEAR_INSN_CACHE
1744 CLEAR_INSN_CACHE (beg
, end
);
1746 #ifdef INSN_CACHE_SIZE
1747 static char array
[INSN_CACHE_SIZE
+ INSN_CACHE_PLANE_SIZE
+ INSN_CACHE_LINE_WIDTH
];
1748 static int initialized
= 0;
1752 typedef (*function_ptr
) ();
1754 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1755 /* It's cheaper to clear the whole cache.
1756 Put in a series of jump instructions so that calling the beginning
1757 of the cache will clear the whole thing. */
1761 int ptr
= (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
1762 & -INSN_CACHE_LINE_WIDTH
);
1763 int end_ptr
= ptr
+ INSN_CACHE_SIZE
;
1765 while (ptr
< end_ptr
)
1767 *(INSTRUCTION_TYPE
*)ptr
1768 = JUMP_AHEAD_INSTRUCTION
+ INSN_CACHE_LINE_WIDTH
;
1769 ptr
+= INSN_CACHE_LINE_WIDTH
;
1771 *(INSTRUCTION_TYPE
*)(ptr
- INSN_CACHE_LINE_WIDTH
) = RETURN_INSTRUCTION
;
1776 /* Call the beginning of the sequence. */
1777 (((function_ptr
) (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
1778 & -INSN_CACHE_LINE_WIDTH
))
1781 #else /* Cache is large. */
1785 int ptr
= (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
1786 & -INSN_CACHE_LINE_WIDTH
);
1788 while (ptr
< (int) array
+ sizeof array
)
1790 *(INSTRUCTION_TYPE
*)ptr
= RETURN_INSTRUCTION
;
1791 ptr
+= INSN_CACHE_LINE_WIDTH
;
1797 /* Find the location in array that occupies the same cache line as BEG. */
1799 offset
= ((int) beg
& -INSN_CACHE_LINE_WIDTH
) & (INSN_CACHE_PLANE_SIZE
- 1);
1800 start_addr
= (((int) (array
+ INSN_CACHE_PLANE_SIZE
- 1)
1801 & -INSN_CACHE_PLANE_SIZE
)
1804 /* Compute the cache alignment of the place to stop clearing. */
1805 #if 0 /* This is not needed for gcc's purposes. */
1806 /* If the block to clear is bigger than a cache plane,
1807 we clear the entire cache, and OFFSET is already correct. */
1808 if (end
< beg
+ INSN_CACHE_PLANE_SIZE
)
1810 offset
= (((int) (end
+ INSN_CACHE_LINE_WIDTH
- 1)
1811 & -INSN_CACHE_LINE_WIDTH
)
1812 & (INSN_CACHE_PLANE_SIZE
- 1));
1814 #if INSN_CACHE_DEPTH > 1
1815 end_addr
= (start_addr
& -INSN_CACHE_PLANE_SIZE
) + offset
;
1816 if (end_addr
<= start_addr
)
1817 end_addr
+= INSN_CACHE_PLANE_SIZE
;
1819 for (plane
= 0; plane
< INSN_CACHE_DEPTH
; plane
++)
1821 int addr
= start_addr
+ plane
* INSN_CACHE_PLANE_SIZE
;
1822 int stop
= end_addr
+ plane
* INSN_CACHE_PLANE_SIZE
;
1824 while (addr
!= stop
)
1826 /* Call the return instruction at ADDR. */
1827 ((function_ptr
) addr
) ();
1829 addr
+= INSN_CACHE_LINE_WIDTH
;
1832 #else /* just one plane */
1835 /* Call the return instruction at START_ADDR. */
1836 ((function_ptr
) start_addr
) ();
1838 start_addr
+= INSN_CACHE_LINE_WIDTH
;
1840 while ((start_addr
% INSN_CACHE_SIZE
) != offset
);
1841 #endif /* just one plane */
1842 #endif /* Cache is large */
1843 #endif /* Cache exists */
1844 #endif /* CLEAR_INSN_CACHE */
1847 #endif /* L_clear_cache */
1851 /* Jump to a trampoline, loading the static chain address. */
1853 #ifdef TRANSFER_FROM_TRAMPOLINE
1854 TRANSFER_FROM_TRAMPOLINE
1857 #if defined (NeXT) && defined (__MACH__)
1859 /* Make stack executable so we can call trampolines on stack.
1860 This is called from INITIALIZE_TRAMPOLINE in next.h. */
1864 #include <mach/mach.h>
1868 __enable_execute_stack (addr
)
1872 char *eaddr
= addr
+ TRAMPOLINE_SIZE
;
1873 vm_address_t a
= (vm_address_t
) addr
;
1875 /* turn on execute access on stack */
1876 r
= vm_protect (task_self (), a
, TRAMPOLINE_SIZE
, FALSE
, VM_PROT_ALL
);
1877 if (r
!= KERN_SUCCESS
)
1879 mach_error("vm_protect VM_PROT_ALL", r
);
1883 /* We inline the i-cache invalidation for speed */
1885 #ifdef CLEAR_INSN_CACHE
1886 CLEAR_INSN_CACHE (addr
, eaddr
);
1888 __clear_cache ((int) addr
, (int) eaddr
);
1892 #endif /* defined (NeXT) && defined (__MACH__) */
1896 /* Make stack executable so we can call trampolines on stack.
1897 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
1899 #include <sys/mman.h>
1900 #include <sys/vmparam.h>
1901 #include <machine/machparam.h>
1904 __enable_execute_stack ()
1907 static unsigned lowest
= USRSTACK
;
1908 unsigned current
= (unsigned) &fp
& -NBPG
;
1910 if (lowest
> current
)
1912 unsigned len
= lowest
- current
;
1913 mremap (current
, &len
, PROT_READ
| PROT_WRITE
| PROT_EXEC
, MAP_PRIVATE
);
1917 /* Clear instruction cache in case an old trampoline is in it. */
1920 #endif /* __convex__ */
1924 /* Modified from the convex -code above. */
1926 #include <sys/param.h>
1928 #include <sys/m88kbcs.h>
1931 __enable_execute_stack ()
1934 static unsigned long lowest
= USRSTACK
;
1935 unsigned long current
= (unsigned long) &save_errno
& -NBPC
;
1937 /* Ignore errno being set. memctl sets errno to EINVAL whenever the
1938 address is seen as 'negative'. That is the case with the stack. */
1941 if (lowest
> current
)
1943 unsigned len
=lowest
-current
;
1944 memctl(current
,len
,MCT_TEXT
);
1948 memctl(current
,NBPC
,MCT_TEXT
);
1952 #endif /* __DOLPHIN__ */
1956 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1958 #include <sys/mman.h>
1959 #include <sys/types.h>
1960 #include <sys/param.h>
1961 #include <sys/vmmac.h>
1963 /* Modified from the convex -code above.
1964 mremap promises to clear the i-cache. */
1967 __enable_execute_stack ()
1970 if (mprotect (((unsigned int)&fp
/PAGSIZ
)*PAGSIZ
, PAGSIZ
,
1971 PROT_READ
|PROT_WRITE
|PROT_EXEC
))
1973 perror ("mprotect in __enable_execute_stack");
1978 #endif /* __pyr__ */
1979 #endif /* L_trampoline */
1983 #include "gbl-ctors.h"
1984 /* Some systems use __main in a way incompatible with its use in gcc, in these
1985 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
1986 give the same symbol without quotes for an alternative entry point. You
1987 must define both, or niether. */
1989 #define NAME__MAIN "__main"
1990 #define SYMBOL__MAIN __main
1993 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
1994 /* Run all the global destructors on exit from the program. */
1997 __do_global_dtors ()
1999 #ifdef DO_GLOBAL_DTORS_BODY
2000 DO_GLOBAL_DTORS_BODY
;
2003 for (p
= __DTOR_LIST__
+ 1; *p
; )
2009 #ifndef INIT_SECTION_ASM_OP
2010 /* Run all the global constructors on entry to the program. */
2013 #define ON_EXIT(a, b)
2015 /* Make sure the exit routine is pulled in to define the globals as
2016 bss symbols, just in case the linker does not automatically pull
2017 bss definitions from the library. */
2019 extern int _exit_dummy_decl
;
2020 int *_exit_dummy_ref
= &_exit_dummy_decl
;
2021 #endif /* ON_EXIT */
2024 __do_global_ctors ()
2026 DO_GLOBAL_CTORS_BODY
;
2027 ON_EXIT (__do_global_dtors
, 0);
2029 #endif /* no INIT_SECTION_ASM_OP */
2031 #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
2032 /* Subroutine called automatically by `main'.
2033 Compiling a global function named `main'
2034 produces an automatic call to this function at the beginning.
2036 For many systems, this routine calls __do_global_ctors.
2037 For systems which support a .init section we use the .init section
2038 to run __do_global_ctors, so we need not do anything here. */
2043 /* Support recursive calls to `main': run initializers just once. */
2044 static int initialized
= 0;
2048 __do_global_ctors ();
2051 #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
2053 #endif /* L__main */
2057 #include "gbl-ctors.h"
2059 /* Provide default definitions for the lists of constructors and
2060 destructors, so that we don't get linker errors. These symbols are
2061 intentionally bss symbols, so that gld and/or collect will provide
2062 the right values. */
2064 /* We declare the lists here with two elements each,
2065 so that they are valid empty lists if no other definition is loaded. */
2066 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
2068 /* After 2.3, try this definition on all systems. */
2069 func_ptr __CTOR_LIST__
[2] = {0, 0};
2070 func_ptr __DTOR_LIST__
[2] = {0, 0};
2072 func_ptr __CTOR_LIST__
[2];
2073 func_ptr __DTOR_LIST__
[2];
2075 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
2076 #endif /* L_ctors */
2080 #include "gbl-ctors.h"
2084 /* If we have no known way of registering our own __do_global_dtors
2085 routine so that it will be invoked at program exit time, then we
2086 have to define our own exit routine which will get this to happen. */
2088 extern void __do_global_dtors ();
2089 extern void _cleanup ();
2090 extern void _exit () __attribute__ ((noreturn
));
2096 __do_global_dtors ();
2106 int _exit_dummy_decl
= 0; /* prevent compiler & linker warnings */
2115 void *exception_handler
;
2118 struct exception_table_node
{
2119 exception_table
*table
;
2122 struct exception_table_node
*next
;
2125 static int except_table_pos
= 0;
2126 static void *except_pc
= (void *)0;
2127 static struct exception_table_node
*exception_table_list
= 0;
2129 static exception_table
*
2130 find_exception_table (pc
)
2133 register struct exception_table_node
*table
= exception_table_list
;
2134 for ( ; table
!= 0; table
= table
->next
)
2136 if (table
->start
<= pc
&& table
->end
> pc
)
2137 return table
->table
;
2142 /* this routine takes a pc, and the address of the exception handler associated
2143 with the closest exception table handler entry associated with that PC,
2144 or 0 if there are no table entries the PC fits in. The algorithm works
2145 something like this:
2147 while(current_entry exists) {
2148 if(current_entry.start < pc )
2149 current_entry = next_entry;
2151 if(prev_entry.start <= pc && prev_entry.end > pc) {
2152 save pointer to prev_entry;
2153 return prev_entry.exception_handler;
2160 Assuming a correctly sorted table (ascending order) this routine should
2161 return the tighest match...
2163 In the advent of a tie, we have to give the last entry, as it represents
2169 __find_first_exception_table_match(pc
)
2172 exception_table
*table
= find_exception_table (pc
);
2178 printf("find_first_exception_table_match(): pc = %x!\n",pc
);
2184 /* We can't do this yet, as we don't know that the table is sorted. */
2187 if (table
[pos
].start
> except_pc
)
2188 /* found the first table[pos].start > except_pc, so the previous
2189 entry better be the one we want! */
2191 } while(table
[pos
].exception_handler
!= (void*)-1);
2194 if (table
[pos
].start
<= except_pc
&& table
[pos
].end
> except_pc
)
2196 except_table_pos
= pos
;
2198 printf("find_first_eh_table_match(): found match: %x\n",table
[pos
].exception_handler
);
2200 return table
[pos
].exception_handler
;
2203 while (table
[++pos
].exception_handler
!= (void*)-1) {
2204 if (table
[pos
].start
<= except_pc
&& table
[pos
].end
> except_pc
)
2206 /* This can apply. Make sure it is better or as good as the previous
2208 /* The best one ends first. */
2209 if (best
== 0 || (table
[pos
].end
<= table
[best
].end
2210 /* The best one starts last. */
2211 && table
[pos
].start
>= table
[best
].start
))
2216 return table
[best
].exception_handler
;
2220 printf("find_first_eh_table_match(): else: returning NULL!\n");
2226 __throw_type_match (const char *catch_type
, const char *throw_type
)
2229 printf("__throw_type_match (): catch_type = %s, throw_type = %s\n",
2230 catch_type
, throw_type
);
2232 return strcmp (catch_type
, throw_type
);
2236 __register_exceptions (exception_table
*table
)
2238 struct exception_table_node
*node
= (struct exception_table_node
*)
2239 malloc (sizeof (struct exception_table_node
));
2240 exception_table
*range
= table
+ 1;
2241 node
->table
= table
;
2243 /* This look can be optimized away either if the table
2244 is sorted, or if we pass in extra parameters. */
2245 node
->start
= range
->start
;
2246 node
->end
= range
->end
;
2247 for (range
++ ; range
->start
!= (void*)(-1); range
++)
2249 if (range
->start
< node
->start
)
2250 node
->start
= range
->start
;
2251 if (range
->end
> node
->end
)
2252 node
->end
= range
->end
;
2255 node
->next
= exception_table_list
;
2256 exception_table_list
= node
;
2261 __unwind_function(void *ptr
)
2263 asm("movl 8(%esp),%ecx");
2264 /* Undo current frame */
2265 asm("movl %ebp,%esp");
2267 asm("# like ret, but stay here");
2268 asm("addl $4,%esp");
2270 /* Now, undo previous frame. */
2271 /* This is a test routine, as we have to dynamically probe to find out
2272 what to pop for certain, this is just a guess. */
2273 asm("leal -16(%ebp),%esp");
2274 asm("pop %eax # really for popl %ebx");
2275 asm("pop %eax # really for popl %esi");
2276 asm("pop %eax # really for popl %edi");
2277 asm("movl %ebp,%esp");
2280 asm("movl %ecx,0(%esp)");
2287 #define MESSAGE "pure virtual method called\n"
2291 write (2, MESSAGE
, sizeof (MESSAGE
) - 1);