1 /* More subroutines needed by GCC output code on some machines. */
2 /* Compile this one with gcc. */
3 /* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* As a special exception, if you link this library with other files,
23 some of which are compiled with GCC, to produce an executable,
24 this library does not by itself cause the resulting executable
25 to be covered by the GNU General Public License.
26 This exception does not however invalidate any other reasons why
27 the executable file might be covered by the GNU General Public License. */
29 /* It is incorrect to include config.h here, because this file is being
30 compiled for the target, and hence definitions concerning only the host
35 /* We disable this when inhibit_libc, so that gcc can still be built without
36 needing header files first. */
37 /* ??? This is not a good solution, since prototypes may be required in
38 some cases for correct code. See also frame.c/crtstuff.c. */
40 /* fixproto guarantees these system headers exist. */
48 extern void *malloc (size_t);
51 extern void free (void *);
54 extern int atexit(void (*)(void));
65 /* Don't use `fancy_abort' here even if config.h says to use it. */
70 /* In a cross-compilation situation, default to inhibiting compilation
71 of routines that use libc. */
73 #if defined(CROSS_COMPILE) && !defined(inhibit_libc)
77 /* Permit the tm.h file to select the endianness to use just for this
78 file. This is used when the endianness is determined when the
81 #ifndef LIBGCC2_WORDS_BIG_ENDIAN
82 #define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
85 #ifndef LIBGCC2_LONG_DOUBLE_TYPE_SIZE
86 #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE LONG_DOUBLE_TYPE_SIZE
89 /* In the first part of this file, we are interfacing to calls generated
90 by the compiler itself. These calls pass values into these routines
91 which have very specific modes (rather than very specific types), and
92 these compiler-generated calls also expect any return values to have
93 very specific modes (rather than very specific types). Thus, we need
94 to avoid using regular C language type names in this part of the file
95 because the sizes for those types can be configured to be anything.
96 Instead we use the following special type names. */
98 typedef int QItype
__attribute__ ((mode (QI
)));
99 typedef unsigned int UQItype
__attribute__ ((mode (QI
)));
100 typedef int HItype
__attribute__ ((mode (HI
)));
101 typedef unsigned int UHItype
__attribute__ ((mode (HI
)));
102 #if UNITS_PER_WORD > 1
103 /* These typedefs are usually forbidden on dsp's with UNITS_PER_WORD 1 */
104 typedef int SItype
__attribute__ ((mode (SI
)));
105 typedef unsigned int USItype
__attribute__ ((mode (SI
)));
106 #if UNITS_PER_WORD > 2
107 /* These typedefs are usually forbidden on archs with UNITS_PER_WORD 2 */
108 typedef int DItype
__attribute__ ((mode (DI
)));
109 typedef unsigned int UDItype
__attribute__ ((mode (DI
)));
113 #if BITS_PER_UNIT == 8
115 typedef float SFtype
__attribute__ ((mode (SF
)));
116 typedef float DFtype
__attribute__ ((mode (DF
)));
118 #if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
119 typedef float XFtype
__attribute__ ((mode (XF
)));
121 #if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128
122 typedef float TFtype
__attribute__ ((mode (TF
)));
125 #else /* BITS_PER_UNIT != 8 */
127 /* On dsp's there are usually qf/hf/tqf modes used instead of the above.
128 For now we don't support them in libgcc2.c. */
146 #endif /* BITS_PER_UNIT != 8 */
148 typedef int word_type
__attribute__ ((mode (__word__
)));
150 /* Make sure that we don't accidentally use any normal C language built-in
151 type names in the first part of this file. Instead we want to use *only*
152 the type names defined above. The following macro definitions insure
153 that if we *do* accidentally use some normal C language built-in type name,
154 we will get a syntax error. */
156 #define char bogus_type
157 #define short bogus_type
158 #define int bogus_type
159 #define long bogus_type
160 #define unsigned bogus_type
161 #define float bogus_type
162 #define double bogus_type
164 #if UNITS_PER_WORD > 2
165 #define W_TYPE_SIZE (4 * BITS_PER_UNIT)
167 #define UWtype USItype
168 #define HWtype SItype
169 #define UHWtype USItype
170 #define DWtype DItype
171 #define UDWtype UDItype
172 #define __NW(a,b) __ ## a ## si ## b
173 #define __NDW(a,b) __ ## a ## di ## b
174 #elif UNITS_PER_WORD > 1
175 #define W_TYPE_SIZE (2 * BITS_PER_UNIT)
177 #define UWtype UHItype
178 #define HWtype HItype
179 #define UHWtype UHItype
180 #define DWtype SItype
181 #define UDWtype USItype
182 #define __NW(a,b) __ ## a ## hi ## b
183 #define __NDW(a,b) __ ## a ## si ## b
185 #define W_TYPE_SIZE BITS_PER_UNIT
187 #define UWtype UQItype
188 #define HWtype QItype
189 #define UHWtype UQItype
190 #define DWtype HItype
191 #define UDWtype UHItype
192 #define __NW(a,b) __ ## a ## qi ## b
193 #define __NDW(a,b) __ ## a ## hi ## b
196 #define __muldi3 __NDW(mul,3)
197 #define __divdi3 __NDW(div,3)
198 #define __udivdi3 __NDW(udiv,3)
199 #define __moddi3 __NDW(mod,3)
200 #define __umoddi3 __NDW(umod,3)
201 #define __negdi2 __NDW(neg,2)
202 #define __lshrdi3 __NDW(lshr,3)
203 #define __ashldi3 __NDW(ashl,3)
204 #define __ashrdi3 __NDW(ashr,3)
205 #define __ffsdi2 __NDW(ffs,2)
206 #define __cmpdi2 __NDW(cmp,2)
207 #define __ucmpdi2 __NDW(ucmp,2)
208 #define __udivmoddi4 __NDW(udivmod,4)
209 #define __fixunstfdi __NDW(fixunstf,)
210 #define __fixtfdi __NDW(fixtf,)
211 #define __fixunsxfdi __NDW(fixunsxf,)
212 #define __fixxfdi __NDW(fixxf,)
213 #define __fixunsdfdi __NDW(fixunsdf,)
214 #define __fixdfdi __NDW(fixdf,)
215 #define __fixunssfdi __NDW(fixunssf,)
216 #define __fixsfdi __NDW(fixsf,)
217 #define __floatdixf __NDW(float,xf)
218 #define __floatditf __NDW(float,tf)
219 #define __floatdidf __NDW(float,df)
220 #define __floatdisf __NDW(float,sf)
221 #define __fixunsxfsi __NW(fixunsxf,)
222 #define __fixunstfsi __NW(fixunstf,)
223 #define __fixunsdfsi __NW(fixunsdf,)
224 #define __fixunssfsi __NW(fixunssf,)
226 /* DWstructs are pairs of Wtype values in the order determined by
227 LIBGCC2_WORDS_BIG_ENDIAN. */
229 #if LIBGCC2_WORDS_BIG_ENDIAN
230 struct DWstruct
{Wtype high
, low
;};
232 struct DWstruct
{Wtype low
, high
;};
235 /* We need this union to unpack/pack DImode values, since we don't have
236 any arithmetic yet. Incoming DImode parameters are stored into the
237 `ll' field, and the unpacked result is read from the struct `s'. */
245 #if (defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_w_sdiv)\
246 || defined (L_divdi3) || defined (L_udivdi3) \
247 || defined (L_moddi3) || defined (L_umoddi3))
249 #include "longlong.h"
251 #endif /* udiv or mul */
254 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
255 #if defined (L_divdi3) || defined (L_moddi3)
267 w
.s
.high
= -uu
.s
.high
- ((UWtype
) w
.s
.low
> 0);
273 /* Unless shift functions are defined whith full ANSI prototypes,
274 parameter b will be promoted to int if word_type is smaller than an int. */
277 __lshrdi3 (DWtype u
, word_type b
)
288 bm
= (sizeof (Wtype
) * BITS_PER_UNIT
) - b
;
292 w
.s
.low
= (UWtype
)uu
.s
.high
>> -bm
;
296 UWtype carries
= (UWtype
)uu
.s
.high
<< bm
;
297 w
.s
.high
= (UWtype
)uu
.s
.high
>> b
;
298 w
.s
.low
= ((UWtype
)uu
.s
.low
>> b
) | carries
;
307 __ashldi3 (DWtype u
, word_type b
)
318 bm
= (sizeof (Wtype
) * BITS_PER_UNIT
) - b
;
322 w
.s
.high
= (UWtype
)uu
.s
.low
<< -bm
;
326 UWtype carries
= (UWtype
)uu
.s
.low
>> bm
;
327 w
.s
.low
= (UWtype
)uu
.s
.low
<< b
;
328 w
.s
.high
= ((UWtype
)uu
.s
.high
<< b
) | carries
;
337 __ashrdi3 (DWtype u
, word_type b
)
348 bm
= (sizeof (Wtype
) * BITS_PER_UNIT
) - b
;
351 /* w.s.high = 1..1 or 0..0 */
352 w
.s
.high
= uu
.s
.high
>> (sizeof (Wtype
) * BITS_PER_UNIT
- 1);
353 w
.s
.low
= uu
.s
.high
>> -bm
;
357 UWtype carries
= (UWtype
)uu
.s
.high
<< bm
;
358 w
.s
.high
= uu
.s
.high
>> b
;
359 w
.s
.low
= ((UWtype
)uu
.s
.low
>> b
) | carries
;
373 w
.s
.low
= ffs (uu
.s
.low
);
376 w
.s
.low
= ffs (uu
.s
.high
);
379 w
.s
.low
+= BITS_PER_UNIT
* sizeof (Wtype
);
388 __muldi3 (DWtype u
, DWtype v
)
396 w
.ll
= __umulsidi3 (uu
.s
.low
, vv
.s
.low
);
397 w
.s
.high
+= ((UWtype
) uu
.s
.low
* (UWtype
) vv
.s
.high
398 + (UWtype
) uu
.s
.high
* (UWtype
) vv
.s
.low
);
405 #if defined (sdiv_qrnnd)
407 __udiv_w_sdiv (UWtype
*rp
, UWtype a1
, UWtype a0
, UWtype d
)
414 if (a1
< d
- a1
- (a0
>> (W_TYPE_SIZE
- 1)))
416 /* dividend, divisor, and quotient are nonnegative */
417 sdiv_qrnnd (q
, r
, a1
, a0
, d
);
421 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
422 sub_ddmmss (c1
, c0
, a1
, a0
, d
>> 1, d
<< (W_TYPE_SIZE
- 1));
423 /* Divide (c1*2^32 + c0) by d */
424 sdiv_qrnnd (q
, r
, c1
, c0
, d
);
425 /* Add 2^31 to quotient */
426 q
+= (UWtype
) 1 << (W_TYPE_SIZE
- 1);
431 b1
= d
>> 1; /* d/2, between 2^30 and 2^31 - 1 */
432 c1
= a1
>> 1; /* A/2 */
433 c0
= (a1
<< (W_TYPE_SIZE
- 1)) + (a0
>> 1);
435 if (a1
< b1
) /* A < 2^32*b1, so A/2 < 2^31*b1 */
437 sdiv_qrnnd (q
, r
, c1
, c0
, b1
); /* (A/2) / (d/2) */
439 r
= 2*r
+ (a0
& 1); /* Remainder from A/(2*b1) */
456 else if (c1
< b1
) /* So 2^31 <= (A/2)/b1 < 2^32 */
459 c0
= ~c0
; /* logical NOT */
461 sdiv_qrnnd (q
, r
, c1
, c0
, b1
); /* (A/2) / (d/2) */
463 q
= ~q
; /* (A/2)/b1 */
466 r
= 2*r
+ (a0
& 1); /* A/(2*b1) */
484 else /* Implies c1 = b1 */
485 { /* Hence a1 = d - 1 = 2*b1 - 1 */
503 /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */
505 __udiv_w_sdiv (UWtype
*rp
__attribute__ ((__unused__
)),
506 UWtype a1
__attribute__ ((__unused__
)),
507 UWtype a0
__attribute__ ((__unused__
)),
508 UWtype d
__attribute__ ((__unused__
)))
515 #if (defined (L_udivdi3) || defined (L_divdi3) || \
516 defined (L_umoddi3) || defined (L_moddi3))
521 static const UQItype __clz_tab
[] =
523 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,
524 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,
525 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,
526 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,
527 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,
528 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,
529 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,
530 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,
533 #if (defined (L_udivdi3) || defined (L_divdi3) || \
534 defined (L_umoddi3) || defined (L_moddi3))
538 __udivmoddi4 (UDWtype n
, UDWtype d
, UDWtype
*rp
)
543 UWtype d0
, d1
, n0
, n1
, n2
;
555 #if !UDIV_NEEDS_NORMALIZATION
562 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
565 /* Remainder in n0. */
572 d0
= 1 / d0
; /* Divide intentionally by zero. */
574 udiv_qrnnd (q1
, n1
, 0, n1
, d0
);
575 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
577 /* Remainder in n0. */
588 #else /* UDIV_NEEDS_NORMALIZATION */
596 count_leading_zeros (bm
, d0
);
600 /* Normalize, i.e. make the most significant bit of the
604 n1
= (n1
<< bm
) | (n0
>> (W_TYPE_SIZE
- bm
));
608 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
611 /* Remainder in n0 >> bm. */
618 d0
= 1 / d0
; /* Divide intentionally by zero. */
620 count_leading_zeros (bm
, d0
);
624 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
625 conclude (the most significant bit of n1 is set) /\ (the
626 leading quotient digit q1 = 1).
628 This special case is necessary, not an optimization.
629 (Shifts counts of W_TYPE_SIZE are undefined.) */
638 b
= W_TYPE_SIZE
- bm
;
642 n1
= (n1
<< bm
) | (n0
>> b
);
645 udiv_qrnnd (q1
, n1
, n2
, n1
, d0
);
650 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
652 /* Remainder in n0 >> bm. */
662 #endif /* UDIV_NEEDS_NORMALIZATION */
673 /* Remainder in n1n0. */
685 count_leading_zeros (bm
, d1
);
688 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
689 conclude (the most significant bit of n1 is set) /\ (the
690 quotient digit q0 = 0 or 1).
692 This special case is necessary, not an optimization. */
694 /* The condition on the next line takes advantage of that
695 n1 >= d1 (true due to program flow). */
696 if (n1
> d1
|| n0
>= d0
)
699 sub_ddmmss (n1
, n0
, n1
, n0
, d1
, d0
);
718 b
= W_TYPE_SIZE
- bm
;
720 d1
= (d1
<< bm
) | (d0
>> b
);
723 n1
= (n1
<< bm
) | (n0
>> b
);
726 udiv_qrnnd (q0
, n1
, n2
, n1
, d1
);
727 umul_ppmm (m1
, m0
, q0
, d0
);
729 if (m1
> n1
|| (m1
== n1
&& m0
> n0
))
732 sub_ddmmss (m1
, m0
, m1
, m0
, d1
, d0
);
737 /* Remainder in (n1n0 - m1m0) >> bm. */
740 sub_ddmmss (n1
, n0
, n1
, n0
, m1
, m0
);
741 rr
.s
.low
= (n1
<< b
) | (n0
>> bm
);
742 rr
.s
.high
= n1
>> bm
;
757 __divdi3 (DWtype u
, DWtype v
)
768 uu
.ll
= __negdi2 (uu
.ll
);
771 vv
.ll
= __negdi2 (vv
.ll
);
773 w
= __udivmoddi4 (uu
.ll
, vv
.ll
, (UDWtype
*) 0);
783 __moddi3 (DWtype u
, DWtype v
)
794 uu
.ll
= __negdi2 (uu
.ll
);
796 vv
.ll
= __negdi2 (vv
.ll
);
798 (void) __udivmoddi4 (uu
.ll
, vv
.ll
, &w
);
808 __umoddi3 (UDWtype u
, UDWtype v
)
812 (void) __udivmoddi4 (u
, v
, &w
);
820 __udivdi3 (UDWtype n
, UDWtype d
)
822 return __udivmoddi4 (n
, d
, (UDWtype
*) 0);
828 __cmpdi2 (DWtype a
, DWtype b
)
832 au
.ll
= a
, bu
.ll
= b
;
834 if (au
.s
.high
< bu
.s
.high
)
836 else if (au
.s
.high
> bu
.s
.high
)
838 if ((UWtype
) au
.s
.low
< (UWtype
) bu
.s
.low
)
840 else if ((UWtype
) au
.s
.low
> (UWtype
) bu
.s
.low
)
848 __ucmpdi2 (DWtype a
, DWtype b
)
852 au
.ll
= a
, bu
.ll
= b
;
854 if ((UWtype
) au
.s
.high
< (UWtype
) bu
.s
.high
)
856 else if ((UWtype
) au
.s
.high
> (UWtype
) bu
.s
.high
)
858 if ((UWtype
) au
.s
.low
< (UWtype
) bu
.s
.low
)
860 else if ((UWtype
) au
.s
.low
> (UWtype
) bu
.s
.low
)
866 #if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
867 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
868 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
871 __fixunstfdi (TFtype a
)
879 /* Compute high word of result, as a flonum. */
880 b
= (a
/ HIGH_WORD_COEFF
);
881 /* Convert that to fixed (but not to DWtype!),
882 and shift it into the high word. */
885 /* Remove high part from the TFtype, leaving the low part as flonum. */
887 /* Convert that to fixed (but not to DWtype!) and add it in.
888 Sometimes A comes out negative. This is significant, since
889 A has more bits than a long int does. */
898 #if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
899 extern DWtype
__fixunstfdi (TFtype a
);
905 return - __fixunstfdi (-a
);
906 return __fixunstfdi (a
);
910 #if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
911 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
912 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
915 __fixunsxfdi (XFtype a
)
923 /* Compute high word of result, as a flonum. */
924 b
= (a
/ HIGH_WORD_COEFF
);
925 /* Convert that to fixed (but not to DWtype!),
926 and shift it into the high word. */
929 /* Remove high part from the XFtype, leaving the low part as flonum. */
931 /* Convert that to fixed (but not to DWtype!) and add it in.
932 Sometimes A comes out negative. This is significant, since
933 A has more bits than a long int does. */
942 #if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
943 extern DWtype
__fixunsxfdi (XFtype a
);
949 return - __fixunsxfdi (-a
);
950 return __fixunsxfdi (a
);
955 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
956 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
959 __fixunsdfdi (DFtype a
)
967 /* Compute high word of result, as a flonum. */
968 b
= (a
/ HIGH_WORD_COEFF
);
969 /* Convert that to fixed (but not to DWtype!),
970 and shift it into the high word. */
973 /* Remove high part from the DFtype, leaving the low part as flonum. */
975 /* Convert that to fixed (but not to DWtype!) and add it in.
976 Sometimes A comes out negative. This is significant, since
977 A has more bits than a long int does. */
987 extern DWtype
__fixunsdfdi (DFtype a
);
993 return - __fixunsdfdi (-a
);
994 return __fixunsdfdi (a
);
999 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1000 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1003 __fixunssfdi (SFtype original_a
)
1005 /* Convert the SFtype to a DFtype, because that is surely not going
1006 to lose any bits. Some day someone else can write a faster version
1007 that avoids converting to DFtype, and verify it really works right. */
1008 DFtype a
= original_a
;
1015 /* Compute high word of result, as a flonum. */
1016 b
= (a
/ HIGH_WORD_COEFF
);
1017 /* Convert that to fixed (but not to DWtype!),
1018 and shift it into the high word. */
1021 /* Remove high part from the DFtype, leaving the low part as flonum. */
1023 /* Convert that to fixed (but not to DWtype!) and add it in.
1024 Sometimes A comes out negative. This is significant, since
1025 A has more bits than a long int does. */
1027 v
-= (UWtype
) (- a
);
1035 extern DWtype
__fixunssfdi (SFtype a
);
1038 __fixsfdi (SFtype a
)
1041 return - __fixunssfdi (-a
);
1042 return __fixunssfdi (a
);
1046 #if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
1047 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1048 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1049 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1052 __floatdixf (DWtype u
)
1056 d
= (Wtype
) (u
>> WORD_SIZE
);
1057 d
*= HIGH_HALFWORD_COEFF
;
1058 d
*= HIGH_HALFWORD_COEFF
;
1059 d
+= (UWtype
) (u
& (HIGH_WORD_COEFF
- 1));
1065 #if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
1066 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1067 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1068 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1071 __floatditf (DWtype u
)
1075 d
= (Wtype
) (u
>> WORD_SIZE
);
1076 d
*= HIGH_HALFWORD_COEFF
;
1077 d
*= HIGH_HALFWORD_COEFF
;
1078 d
+= (UWtype
) (u
& (HIGH_WORD_COEFF
- 1));
1085 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1086 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1087 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1090 __floatdidf (DWtype u
)
1094 d
= (Wtype
) (u
>> WORD_SIZE
);
1095 d
*= HIGH_HALFWORD_COEFF
;
1096 d
*= HIGH_HALFWORD_COEFF
;
1097 d
+= (UWtype
) (u
& (HIGH_WORD_COEFF
- 1));
1104 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1105 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1106 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1107 #define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT)
1109 /* Define codes for all the float formats that we know of. Note
1110 that this is copied from real.h. */
1112 #define UNKNOWN_FLOAT_FORMAT 0
1113 #define IEEE_FLOAT_FORMAT 1
1114 #define VAX_FLOAT_FORMAT 2
1115 #define IBM_FLOAT_FORMAT 3
1117 /* Default to IEEE float if not specified. Nearly all machines use it. */
1118 #ifndef HOST_FLOAT_FORMAT
1119 #define HOST_FLOAT_FORMAT IEEE_FLOAT_FORMAT
1122 #if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1127 #if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
1132 #if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
1138 __floatdisf (DWtype u
)
1140 /* Do the calculation in DFmode
1141 so that we don't lose any of the precision of the high word
1142 while multiplying it. */
1145 /* Protect against double-rounding error.
1146 Represent any low-order bits, that might be truncated in DFmode,
1147 by a bit that won't be lost. The bit can go in anywhere below the
1148 rounding position of the SFmode. A fixed mask and bit position
1149 handles all usual configurations. It doesn't handle the case
1150 of 128-bit DImode, however. */
1151 if (DF_SIZE
< DI_SIZE
1152 && DF_SIZE
> (DI_SIZE
- DF_SIZE
+ SF_SIZE
))
1154 #define REP_BIT ((UWtype) 1 << (DI_SIZE - DF_SIZE))
1155 if (! (- ((DWtype
) 1 << DF_SIZE
) < u
1156 && u
< ((DWtype
) 1 << DF_SIZE
)))
1158 if ((UWtype
) u
& (REP_BIT
- 1))
1162 f
= (Wtype
) (u
>> WORD_SIZE
);
1163 f
*= HIGH_HALFWORD_COEFF
;
1164 f
*= HIGH_HALFWORD_COEFF
;
1165 f
+= (UWtype
) (u
& (HIGH_WORD_COEFF
- 1));
1171 #if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
1172 /* Reenable the normal types, in case limits.h needs them. */
1185 __fixunsxfsi (XFtype a
)
1187 if (a
>= - (DFtype
) LONG_MIN
)
1188 return (Wtype
) (a
+ LONG_MIN
) - LONG_MIN
;
1194 /* Reenable the normal types, in case limits.h needs them. */
1207 __fixunsdfsi (DFtype a
)
1209 if (a
>= - (DFtype
) LONG_MIN
)
1210 return (Wtype
) (a
+ LONG_MIN
) - LONG_MIN
;
1216 /* Reenable the normal types, in case limits.h needs them. */
1229 __fixunssfsi (SFtype a
)
1231 if (a
>= - (SFtype
) LONG_MIN
)
1232 return (Wtype
) (a
+ LONG_MIN
) - LONG_MIN
;
1237 /* From here on down, the routines use normal data types. */
1239 #define SItype bogus_type
1240 #define USItype bogus_type
1241 #define DItype bogus_type
1242 #define UDItype bogus_type
1243 #define SFtype bogus_type
1244 #define DFtype bogus_type
1262 /* Like bcmp except the sign is meaningful.
1263 Result is negative if S1 is less than S2,
1264 positive if S1 is greater, 0 if S1 and S2 are equal. */
1267 __gcc_bcmp (unsigned char *s1
, unsigned char *s2
, size_t size
)
1271 unsigned char c1
= *s1
++, c2
= *s2
++;
1288 #if defined(__svr4__) || defined(__alliant__)
1292 /* The Alliant needs the added underscore. */
1293 asm (".globl __builtin_saveregs");
1294 asm ("__builtin_saveregs:");
1295 asm (".globl ___builtin_saveregs");
1296 asm ("___builtin_saveregs:");
1298 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
1299 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
1300 area and also for a new va_list
1302 /* Save all argument registers in the arg reg save area. The
1303 arg reg save area must have the following layout (according
1315 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
1316 asm (" fst.q %f12,16(%sp)");
1318 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
1319 asm (" st.l %r17,36(%sp)");
1320 asm (" st.l %r18,40(%sp)");
1321 asm (" st.l %r19,44(%sp)");
1322 asm (" st.l %r20,48(%sp)");
1323 asm (" st.l %r21,52(%sp)");
1324 asm (" st.l %r22,56(%sp)");
1325 asm (" st.l %r23,60(%sp)");
1326 asm (" st.l %r24,64(%sp)");
1327 asm (" st.l %r25,68(%sp)");
1328 asm (" st.l %r26,72(%sp)");
1329 asm (" st.l %r27,76(%sp)");
1331 asm (" adds 80,%sp,%r16"); /* compute the address of the new
1332 va_list structure. Put in into
1333 r16 so that it will be returned
1336 /* Initialize all fields of the new va_list structure. This
1337 structure looks like:
1340 unsigned long ireg_used;
1341 unsigned long freg_used;
1347 asm (" st.l %r0, 0(%r16)"); /* nfixed */
1348 asm (" st.l %r0, 4(%r16)"); /* nfloating */
1349 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
1350 asm (" bri %r1"); /* delayed return */
1351 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
1353 #else /* not __svr4__ */
1354 #if defined(__PARAGON__)
1356 * we'll use SVR4-ish varargs but need SVR3.2 assembler syntax,
1357 * and we stand a better chance of hooking into libraries
1358 * compiled by PGI. [andyp@ssd.intel.com]
1362 asm (".globl __builtin_saveregs");
1363 asm ("__builtin_saveregs:");
1364 asm (".globl ___builtin_saveregs");
1365 asm ("___builtin_saveregs:");
1367 asm (" andnot 0x0f,sp,sp"); /* round down to 16-byte boundary */
1368 asm (" adds -96,sp,sp"); /* allocate stack space for reg save
1369 area and also for a new va_list
1371 /* Save all argument registers in the arg reg save area. The
1372 arg reg save area must have the following layout (according
1384 asm (" fst.q f8, 0(sp)");
1385 asm (" fst.q f12,16(sp)");
1386 asm (" st.l r16,32(sp)");
1387 asm (" st.l r17,36(sp)");
1388 asm (" st.l r18,40(sp)");
1389 asm (" st.l r19,44(sp)");
1390 asm (" st.l r20,48(sp)");
1391 asm (" st.l r21,52(sp)");
1392 asm (" st.l r22,56(sp)");
1393 asm (" st.l r23,60(sp)");
1394 asm (" st.l r24,64(sp)");
1395 asm (" st.l r25,68(sp)");
1396 asm (" st.l r26,72(sp)");
1397 asm (" st.l r27,76(sp)");
1399 asm (" adds 80,sp,r16"); /* compute the address of the new
1400 va_list structure. Put in into
1401 r16 so that it will be returned
1404 /* Initialize all fields of the new va_list structure. This
1405 structure looks like:
1408 unsigned long ireg_used;
1409 unsigned long freg_used;
1415 asm (" st.l r0, 0(r16)"); /* nfixed */
1416 asm (" st.l r0, 4(r16)"); /* nfloating */
1417 asm (" st.l sp, 8(r16)"); /* __va_ctl points to __va_struct. */
1418 asm (" bri r1"); /* delayed return */
1419 asm (" st.l r28,12(r16)"); /* pointer to overflow args */
1420 #else /* not __PARAGON__ */
1424 asm (".globl ___builtin_saveregs");
1425 asm ("___builtin_saveregs:");
1426 asm (" mov sp,r30");
1427 asm (" andnot 0x0f,sp,sp");
1428 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
1430 /* Fill in the __va_struct. */
1431 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
1432 asm (" st.l r17, 4(sp)"); /* int fixed[12] */
1433 asm (" st.l r18, 8(sp)");
1434 asm (" st.l r19,12(sp)");
1435 asm (" st.l r20,16(sp)");
1436 asm (" st.l r21,20(sp)");
1437 asm (" st.l r22,24(sp)");
1438 asm (" st.l r23,28(sp)");
1439 asm (" st.l r24,32(sp)");
1440 asm (" st.l r25,36(sp)");
1441 asm (" st.l r26,40(sp)");
1442 asm (" st.l r27,44(sp)");
1444 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
1445 asm (" fst.q f12,64(sp)"); /* int floating[8] */
1447 /* Fill in the __va_ctl. */
1448 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
1449 asm (" st.l r28,84(sp)"); /* pointer to more args */
1450 asm (" st.l r0, 88(sp)"); /* nfixed */
1451 asm (" st.l r0, 92(sp)"); /* nfloating */
1453 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
1455 asm (" mov r30,sp");
1456 /* recover stack and pass address to start
1458 #endif /* not __PARAGON__ */
1459 #endif /* not __svr4__ */
1460 #else /* not __i860__ */
1462 asm (".global __builtin_saveregs");
1463 asm ("__builtin_saveregs:");
1464 asm (".global ___builtin_saveregs");
1465 asm ("___builtin_saveregs:");
1466 #ifdef NEED_PROC_COMMAND
1469 asm ("st %i0,[%fp+68]");
1470 asm ("st %i1,[%fp+72]");
1471 asm ("st %i2,[%fp+76]");
1472 asm ("st %i3,[%fp+80]");
1473 asm ("st %i4,[%fp+84]");
1475 asm ("st %i5,[%fp+88]");
1476 #ifdef NEED_TYPE_COMMAND
1477 asm (".type __builtin_saveregs,#function");
1478 asm (".size __builtin_saveregs,.-__builtin_saveregs");
1480 #else /* not __sparc__ */
1481 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1485 asm (" .set nomips16");
1487 asm (" .ent __builtin_saveregs");
1488 asm (" .globl __builtin_saveregs");
1489 asm ("__builtin_saveregs:");
1490 asm (" sw $4,0($30)");
1491 asm (" sw $5,4($30)");
1492 asm (" sw $6,8($30)");
1493 asm (" sw $7,12($30)");
1495 asm (" .end __builtin_saveregs");
1496 #else /* not __mips__, etc. */
1499 __builtin_saveregs (void)
1504 #endif /* not __mips__ */
1505 #endif /* not __sparc__ */
1506 #endif /* not __i860__ */
1510 #ifndef inhibit_libc
1512 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1514 /* This is used by the `assert' macro. */
1515 extern void __eprintf (const char *, const char *, unsigned int, const char *)
1516 __attribute__ ((__noreturn__
));
1519 __eprintf (const char *string
, const char *expression
,
1520 unsigned int line
, const char *filename
)
1522 fprintf (stderr
, string
, expression
, line
, filename
);
1532 /* Structure emitted by -a */
1536 const char *filename
;
1540 const unsigned long *addresses
;
1542 /* Older GCC's did not emit these fields. */
1544 const char **functions
;
1545 const long *line_nums
;
1546 const char **filenames
;
1550 #ifdef BLOCK_PROFILER_CODE
1553 #ifndef inhibit_libc
1555 /* Simple minded basic block profiling output dumper for
1556 systems that don't provide tcov support. At present,
1557 it requires atexit and stdio. */
1559 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1563 #include "gbl-ctors.h"
1564 #include "gcov-io.h"
1567 static struct bb
*bb_head
;
1569 static int num_digits (long value
, int base
) __attribute__ ((const));
1571 /* Return the number of digits needed to print a value */
1572 /* __inline__ */ static int num_digits (long value
, int base
)
1574 int minus
= (value
< 0 && base
!= 16);
1575 unsigned long v
= (minus
) ? -value
: value
;
1589 __bb_exit_func (void)
1591 FILE *da_file
, *file
;
1598 i
= strlen (bb_head
->filename
) - 3;
1600 if (!strcmp (bb_head
->filename
+i
, ".da"))
1602 /* Must be -fprofile-arcs not -a.
1603 Dump data in a form that gcov expects. */
1607 for (ptr
= bb_head
; ptr
!= (struct bb
*) 0; ptr
= ptr
->next
)
1609 /* If the file exists, and the number of counts in it is the same,
1610 then merge them in. */
1612 if ((da_file
= fopen (ptr
->filename
, "rb")) != 0)
1616 if (__read_long (&n_counts
, da_file
, 8) != 0)
1618 fprintf (stderr
, "arc profiling: Can't read output file %s.\n",
1623 if (n_counts
== ptr
->ncounts
)
1627 for (i
= 0; i
< n_counts
; i
++)
1631 if (__read_long (&v
, da_file
, 8) != 0)
1633 fprintf (stderr
, "arc profiling: Can't read output file %s.\n",
1637 ptr
->counts
[i
] += v
;
1641 if (fclose (da_file
) == EOF
)
1642 fprintf (stderr
, "arc profiling: Error closing output file %s.\n",
1645 if ((da_file
= fopen (ptr
->filename
, "wb")) == 0)
1647 fprintf (stderr
, "arc profiling: Can't open output file %s.\n",
1652 /* ??? Should first write a header to the file. Preferably, a 4 byte
1653 magic number, 4 bytes containing the time the program was
1654 compiled, 4 bytes containing the last modification time of the
1655 source file, and 4 bytes indicating the compiler options used.
1657 That way we can easily verify that the proper source/executable/
1658 data file combination is being used from gcov. */
1660 if (__write_long (ptr
->ncounts
, da_file
, 8) != 0)
1663 fprintf (stderr
, "arc profiling: Error writing output file %s.\n",
1669 long *count_ptr
= ptr
->counts
;
1671 for (j
= ptr
->ncounts
; j
> 0; j
--)
1673 if (__write_long (*count_ptr
, da_file
, 8) != 0)
1681 fprintf (stderr
, "arc profiling: Error writing output file %s.\n",
1685 if (fclose (da_file
) == EOF
)
1686 fprintf (stderr
, "arc profiling: Error closing output file %s.\n",
1693 /* Must be basic block profiling. Emit a human readable output file. */
1695 file
= fopen ("bb.out", "a");
1704 /* This is somewhat type incorrect, but it avoids worrying about
1705 exactly where time.h is included from. It should be ok unless
1706 a void * differs from other pointer formats, or if sizeof (long)
1707 is < sizeof (time_t). It would be nice if we could assume the
1708 use of rationale standards here. */
1710 time ((void *) &time_value
);
1711 fprintf (file
, "Basic block profiling finished on %s\n", ctime ((void *) &time_value
));
1713 /* We check the length field explicitly in order to allow compatibility
1714 with older GCC's which did not provide it. */
1716 for (ptr
= bb_head
; ptr
!= (struct bb
*) 0; ptr
= ptr
->next
)
1719 int func_p
= (ptr
->nwords
>= (long) sizeof (struct bb
)
1720 && ptr
->nwords
<= 1000
1722 int line_p
= (func_p
&& ptr
->line_nums
);
1723 int file_p
= (func_p
&& ptr
->filenames
);
1724 int addr_p
= (ptr
->addresses
!= 0);
1725 long ncounts
= ptr
->ncounts
;
1731 int blk_len
= num_digits (ncounts
, 10);
1736 fprintf (file
, "File %s, %ld basic blocks \n\n",
1737 ptr
->filename
, ncounts
);
1739 /* Get max values for each field. */
1740 for (i
= 0; i
< ncounts
; i
++)
1745 if (cnt_max
< ptr
->counts
[i
])
1746 cnt_max
= ptr
->counts
[i
];
1748 if (addr_p
&& (unsigned long) addr_max
< ptr
->addresses
[i
])
1749 addr_max
= ptr
->addresses
[i
];
1751 if (line_p
&& line_max
< ptr
->line_nums
[i
])
1752 line_max
= ptr
->line_nums
[i
];
1756 p
= (ptr
->functions
[i
]) ? (ptr
->functions
[i
]) : "<none>";
1764 p
= (ptr
->filenames
[i
]) ? (ptr
->filenames
[i
]) : "<none>";
1771 addr_len
= num_digits (addr_max
, 16);
1772 cnt_len
= num_digits (cnt_max
, 10);
1773 line_len
= num_digits (line_max
, 10);
1775 /* Now print out the basic block information. */
1776 for (i
= 0; i
< ncounts
; i
++)
1779 " Block #%*d: executed %*ld time(s)",
1781 cnt_len
, ptr
->counts
[i
]);
1784 fprintf (file
, " address= 0x%.*lx", addr_len
,
1788 fprintf (file
, " function= %-*s", func_len
,
1789 (ptr
->functions
[i
]) ? ptr
->functions
[i
] : "<none>");
1792 fprintf (file
, " line= %*ld", line_len
, ptr
->line_nums
[i
]);
1795 fprintf (file
, " file= %s",
1796 (ptr
->filenames
[i
]) ? ptr
->filenames
[i
] : "<none>");
1798 fprintf (file
, "\n");
1801 fprintf (file
, "\n");
1805 fprintf (file
, "\n\n");
1811 __bb_init_func (struct bb
*blocks
)
1813 /* User is supposed to check whether the first word is non-0,
1814 but just in case.... */
1816 if (blocks
->zero_word
)
1819 /* Initialize destructor. */
1821 atexit (__bb_exit_func
);
1823 /* Set up linked list. */
1824 blocks
->zero_word
= 1;
1825 blocks
->next
= bb_head
;
1829 #ifndef MACHINE_STATE_SAVE
1830 #define MACHINE_STATE_SAVE(ID)
1832 #ifndef MACHINE_STATE_RESTORE
1833 #define MACHINE_STATE_RESTORE(ID)
1836 /* Number of buckets in hashtable of basic block addresses. */
1838 #define BB_BUCKETS 311
1840 /* Maximum length of string in file bb.in. */
1842 #define BBINBUFSIZE 500
1844 /* BBINBUFSIZE-1 with double quotes. We could use #BBINBUFSIZE or
1845 "BBINBUFSIZE" but want to avoid trouble with preprocessors. */
1847 #define BBINBUFSIZESTR "499"
1851 struct bb_edge
*next
;
1852 unsigned long src_addr
;
1853 unsigned long dst_addr
;
1854 unsigned long count
;
1859 TRACE_KEEP
= 0, TRACE_ON
= 1, TRACE_OFF
= 2
1864 struct bb_func
*next
;
1867 enum bb_func_mode mode
;
1870 /* This is the connection to the outside world.
1871 The BLOCK_PROFILER macro must set __bb.blocks
1872 and __bb.blockno. */
1875 unsigned long blockno
;
1879 /* Vars to store addrs of source and destination basic blocks
1882 static unsigned long bb_src
= 0;
1883 static unsigned long bb_dst
= 0;
1885 static FILE *bb_tracefile
= (FILE *) 0;
1886 static struct bb_edge
**bb_hashbuckets
= (struct bb_edge
**) 0;
1887 static struct bb_func
*bb_func_head
= (struct bb_func
*) 0;
1888 static unsigned long bb_callcount
= 0;
1889 static int bb_mode
= 0;
1891 static unsigned long *bb_stack
= (unsigned long *) 0;
1892 static size_t bb_stacksize
= 0;
1894 static int reported
= 0;
1897 Always : Print execution frequencies of basic blocks
1899 bb_mode & 1 != 0 : Dump trace of basic blocks to file bbtrace[.gz]
1900 bb_mode & 2 != 0 : Print jump frequencies to file bb.out.
1901 bb_mode & 4 != 0 : Cut call instructions from basic block flow.
1902 bb_mode & 8 != 0 : Insert return instructions in basic block flow.
1907 /*#include <sys/types.h>*/
1908 #include <sys/stat.h>
1909 /*#include <malloc.h>*/
1911 /* Commands executed by gopen. */
1913 #define GOPENDECOMPRESS "gzip -cd "
1914 #define GOPENCOMPRESS "gzip -c >"
1916 /* Like fopen but pipes through gzip. mode may only be "r" or "w".
1917 If it does not compile, simply replace gopen by fopen and delete
1918 '.gz' from any first parameter to gopen. */
1921 gopen (char *fn
, char *mode
)
1929 if (mode
[0] != 'r' && mode
[0] != 'w')
1932 p
= fn
+ strlen (fn
)-1;
1933 use_gzip
= ((p
[-1] == '.' && (p
[0] == 'Z' || p
[0] == 'z'))
1934 || (p
[-2] == '.' && p
[-1] == 'g' && p
[0] == 'z'));
1941 char *s
= (char *) malloc (sizeof (char) * strlen (fn
)
1942 + sizeof (GOPENDECOMPRESS
));
1943 strcpy (s
, GOPENDECOMPRESS
);
1944 strcpy (s
+ (sizeof (GOPENDECOMPRESS
)-1), fn
);
1945 f
= popen (s
, mode
);
1953 char *s
= (char *) malloc (sizeof (char) * strlen (fn
)
1954 + sizeof (GOPENCOMPRESS
));
1955 strcpy (s
, GOPENCOMPRESS
);
1956 strcpy (s
+ (sizeof (GOPENCOMPRESS
)-1), fn
);
1957 if (!(f
= popen (s
, mode
)))
1958 f
= fopen (s
, mode
);
1965 return fopen (fn
, mode
);
1975 if (!fstat (fileno (f
), &buf
) && S_ISFIFO (buf
.st_mode
))
1983 #endif /* HAVE_POPEN */
1985 /* Called once per program. */
1988 __bb_exit_trace_func (void)
1990 FILE *file
= fopen ("bb.out", "a");
2003 gclose (bb_tracefile
);
2005 fclose (bb_tracefile
);
2006 #endif /* HAVE_POPEN */
2009 /* Check functions in `bb.in'. */
2014 const struct bb_func
*p
;
2015 int printed_something
= 0;
2019 /* This is somewhat type incorrect. */
2020 time ((void *) &time_value
);
2022 for (p
= bb_func_head
; p
!= (struct bb_func
*) 0; p
= p
->next
)
2024 for (ptr
= bb_head
; ptr
!= (struct bb
*) 0; ptr
= ptr
->next
)
2026 if (!ptr
->filename
|| (p
->filename
!= (char *) 0 && strcmp (p
->filename
, ptr
->filename
)))
2028 for (blk
= 0; blk
< ptr
->ncounts
; blk
++)
2030 if (!strcmp (p
->funcname
, ptr
->functions
[blk
]))
2035 if (!printed_something
)
2037 fprintf (file
, "Functions in `bb.in' not executed during basic block profiling on %s\n", ctime ((void *) &time_value
));
2038 printed_something
= 1;
2041 fprintf (file
, "\tFunction %s", p
->funcname
);
2043 fprintf (file
, " of file %s", p
->filename
);
2044 fprintf (file
, "\n" );
2049 if (printed_something
)
2050 fprintf (file
, "\n");
2056 if (!bb_hashbuckets
)
2060 fprintf (stderr
, "Profiler: out of memory\n");
2070 unsigned long addr_max
= 0;
2071 unsigned long cnt_max
= 0;
2075 /* This is somewhat type incorrect, but it avoids worrying about
2076 exactly where time.h is included from. It should be ok unless
2077 a void * differs from other pointer formats, or if sizeof (long)
2078 is < sizeof (time_t). It would be nice if we could assume the
2079 use of rationale standards here. */
2081 time ((void *) &time_value
);
2082 fprintf (file
, "Basic block jump tracing");
2084 switch (bb_mode
& 12)
2087 fprintf (file
, " (with call)");
2091 /* Print nothing. */
2095 fprintf (file
, " (with call & ret)");
2099 fprintf (file
, " (with ret)");
2103 fprintf (file
, " finished on %s\n", ctime ((void *) &time_value
));
2105 for (i
= 0; i
< BB_BUCKETS
; i
++)
2107 struct bb_edge
*bucket
= bb_hashbuckets
[i
];
2108 for ( ; bucket
; bucket
= bucket
->next
)
2110 if (addr_max
< bucket
->src_addr
)
2111 addr_max
= bucket
->src_addr
;
2112 if (addr_max
< bucket
->dst_addr
)
2113 addr_max
= bucket
->dst_addr
;
2114 if (cnt_max
< bucket
->count
)
2115 cnt_max
= bucket
->count
;
2118 addr_len
= num_digits (addr_max
, 16);
2119 cnt_len
= num_digits (cnt_max
, 10);
2121 for ( i
= 0; i
< BB_BUCKETS
; i
++)
2123 struct bb_edge
*bucket
= bb_hashbuckets
[i
];
2124 for ( ; bucket
; bucket
= bucket
->next
)
2126 fprintf (file
, "Jump from block 0x%.*lx to "
2127 "block 0x%.*lx executed %*lu time(s)\n",
2128 addr_len
, bucket
->src_addr
,
2129 addr_len
, bucket
->dst_addr
,
2130 cnt_len
, bucket
->count
);
2134 fprintf (file
, "\n");
2142 /* Free allocated memory. */
2147 struct bb_func
*old
= f
;
2150 if (old
->funcname
) free (old
->funcname
);
2151 if (old
->filename
) free (old
->filename
);
2162 for (i
= 0; i
< BB_BUCKETS
; i
++)
2164 struct bb_edge
*old
, *bucket
= bb_hashbuckets
[i
];
2169 bucket
= bucket
->next
;
2173 free (bb_hashbuckets
);
2176 for (b
= bb_head
; b
; b
= b
->next
)
2177 if (b
->flags
) free (b
->flags
);
2180 /* Called once per program. */
2183 __bb_init_prg (void)
2186 char buf
[BBINBUFSIZE
];
2189 enum bb_func_mode m
;
2192 /* Initialize destructor. */
2193 atexit (__bb_exit_func
);
2195 if (!(file
= fopen ("bb.in", "r")))
2198 while(fscanf (file
, " %" BBINBUFSIZESTR
"s ", buf
) != EOF
)
2210 if (!strcmp (p
, "__bb_trace__"))
2212 else if (!strcmp (p
, "__bb_jumps__"))
2214 else if (!strcmp (p
, "__bb_hidecall__"))
2216 else if (!strcmp (p
, "__bb_showret__"))
2220 struct bb_func
*f
= (struct bb_func
*) malloc (sizeof (struct bb_func
));
2224 f
->next
= bb_func_head
;
2225 if ((pos
= strchr (p
, ':')))
2227 if (!(f
->funcname
= (char *) malloc (strlen (pos
+1)+1)))
2229 strcpy (f
->funcname
, pos
+1);
2231 if ((f
->filename
= (char *) malloc (l
+1)))
2233 strncpy (f
->filename
, p
, l
);
2234 f
->filename
[l
] = '\0';
2237 f
->filename
= (char *) 0;
2241 if (!(f
->funcname
= (char *) malloc (strlen (p
)+1)))
2243 strcpy (f
->funcname
, p
);
2244 f
->filename
= (char *) 0;
2256 bb_tracefile
= gopen ("bbtrace.gz", "w");
2261 bb_tracefile
= fopen ("bbtrace", "w");
2263 #endif /* HAVE_POPEN */
2267 bb_hashbuckets
= (struct bb_edge
**)
2268 malloc (BB_BUCKETS
* sizeof (struct bb_edge
*));
2270 /* Use a loop here rather than calling bzero to avoid having to
2271 conditionalize its existance. */
2272 for (i
= 0; i
< BB_BUCKETS
; i
++)
2273 bb_hashbuckets
[i
] = 0;
2279 bb_stack
= (unsigned long *) malloc (bb_stacksize
* sizeof (*bb_stack
));
2282 /* Initialize destructor. */
2283 atexit (__bb_exit_trace_func
);
2286 /* Called upon entering a basic block. */
2289 __bb_trace_func (void)
2291 struct bb_edge
*bucket
;
2293 MACHINE_STATE_SAVE("1")
2295 if (!bb_callcount
|| (__bb
.blocks
->flags
&& (__bb
.blocks
->flags
[__bb
.blockno
] & TRACE_OFF
)))
2298 bb_dst
= __bb
.blocks
->addresses
[__bb
.blockno
];
2299 __bb
.blocks
->counts
[__bb
.blockno
]++;
2303 fwrite (&bb_dst
, sizeof (unsigned long), 1, bb_tracefile
);
2308 struct bb_edge
**startbucket
, **oldnext
;
2310 oldnext
= startbucket
2311 = & bb_hashbuckets
[ (((int) bb_src
*8) ^ (int) bb_dst
) % BB_BUCKETS
];
2312 bucket
= *startbucket
;
2314 for (bucket
= *startbucket
; bucket
;
2315 oldnext
= &(bucket
->next
), bucket
= *oldnext
)
2317 if (bucket
->src_addr
== bb_src
2318 && bucket
->dst_addr
== bb_dst
)
2321 *oldnext
= bucket
->next
;
2322 bucket
->next
= *startbucket
;
2323 *startbucket
= bucket
;
2328 bucket
= (struct bb_edge
*) malloc (sizeof (struct bb_edge
));
2334 fprintf (stderr
, "Profiler: out of memory\n");
2341 bucket
->src_addr
= bb_src
;
2342 bucket
->dst_addr
= bb_dst
;
2343 bucket
->next
= *startbucket
;
2344 *startbucket
= bucket
;
2355 MACHINE_STATE_RESTORE("1")
2359 /* Called when returning from a function and `__bb_showret__' is set. */
2362 __bb_trace_func_ret (void)
2364 struct bb_edge
*bucket
;
2366 if (!bb_callcount
|| (__bb
.blocks
->flags
&& (__bb
.blocks
->flags
[__bb
.blockno
] & TRACE_OFF
)))
2371 struct bb_edge
**startbucket
, **oldnext
;
2373 oldnext
= startbucket
2374 = & bb_hashbuckets
[ (((int) bb_dst
* 8) ^ (int) bb_src
) % BB_BUCKETS
];
2375 bucket
= *startbucket
;
2377 for (bucket
= *startbucket
; bucket
;
2378 oldnext
= &(bucket
->next
), bucket
= *oldnext
)
2380 if (bucket
->src_addr
== bb_dst
2381 && bucket
->dst_addr
== bb_src
)
2384 *oldnext
= bucket
->next
;
2385 bucket
->next
= *startbucket
;
2386 *startbucket
= bucket
;
2391 bucket
= (struct bb_edge
*) malloc (sizeof (struct bb_edge
));
2397 fprintf (stderr
, "Profiler: out of memory\n");
2404 bucket
->src_addr
= bb_dst
;
2405 bucket
->dst_addr
= bb_src
;
2406 bucket
->next
= *startbucket
;
2407 *startbucket
= bucket
;
2420 /* Called upon entering the first function of a file. */
2423 __bb_init_file (struct bb
*blocks
)
2426 const struct bb_func
*p
;
2427 long blk
, ncounts
= blocks
->ncounts
;
2428 const char **functions
= blocks
->functions
;
2430 /* Set up linked list. */
2431 blocks
->zero_word
= 1;
2432 blocks
->next
= bb_head
;
2437 || !(blocks
->flags
= (char *) malloc (sizeof (char) * blocks
->ncounts
)))
2440 for (blk
= 0; blk
< ncounts
; blk
++)
2441 blocks
->flags
[blk
] = 0;
2443 for (blk
= 0; blk
< ncounts
; blk
++)
2445 for (p
= bb_func_head
; p
; p
= p
->next
)
2447 if (!strcmp (p
->funcname
, functions
[blk
])
2448 && (!p
->filename
|| !strcmp (p
->filename
, blocks
->filename
)))
2450 blocks
->flags
[blk
] |= p
->mode
;
2457 /* Called when exiting from a function. */
2460 __bb_trace_ret (void)
2463 MACHINE_STATE_SAVE("2")
2467 if ((bb_mode
& 12) && bb_stacksize
> bb_callcount
)
2469 bb_src
= bb_stack
[bb_callcount
];
2471 __bb_trace_func_ret ();
2477 MACHINE_STATE_RESTORE("2")
2481 /* Called when entering a function. */
2484 __bb_init_trace_func (struct bb
*blocks
, unsigned long blockno
)
2486 static int trace_init
= 0;
2488 MACHINE_STATE_SAVE("3")
2490 if (!blocks
->zero_word
)
2497 __bb_init_file (blocks
);
2507 if (bb_callcount
>= bb_stacksize
)
2509 size_t newsize
= bb_callcount
+ 100;
2511 bb_stack
= (unsigned long *) realloc (bb_stack
, newsize
);
2516 fprintf (stderr
, "Profiler: out of memory\n");
2520 goto stack_overflow
;
2522 bb_stacksize
= newsize
;
2524 bb_stack
[bb_callcount
] = bb_src
;
2535 else if (blocks
->flags
&& (blocks
->flags
[blockno
] & TRACE_ON
))
2541 bb_stack
[bb_callcount
] = bb_src
;
2544 MACHINE_STATE_RESTORE("3")
2547 #endif /* not inhibit_libc */
2548 #endif /* not BLOCK_PROFILER_CODE */
2552 unsigned int __shtab
[] = {
2553 0x00000001, 0x00000002, 0x00000004, 0x00000008,
2554 0x00000010, 0x00000020, 0x00000040, 0x00000080,
2555 0x00000100, 0x00000200, 0x00000400, 0x00000800,
2556 0x00001000, 0x00002000, 0x00004000, 0x00008000,
2557 0x00010000, 0x00020000, 0x00040000, 0x00080000,
2558 0x00100000, 0x00200000, 0x00400000, 0x00800000,
2559 0x01000000, 0x02000000, 0x04000000, 0x08000000,
2560 0x10000000, 0x20000000, 0x40000000, 0x80000000
2564 #ifdef L_clear_cache
2565 /* Clear part of an instruction cache. */
2567 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
2570 __clear_cache (char *beg
__attribute__((__unused__
)),
2571 char *end
__attribute__((__unused__
)))
2573 #ifdef CLEAR_INSN_CACHE
2574 CLEAR_INSN_CACHE (beg
, end
);
2576 #ifdef INSN_CACHE_SIZE
2577 static char array
[INSN_CACHE_SIZE
+ INSN_CACHE_PLANE_SIZE
+ INSN_CACHE_LINE_WIDTH
];
2578 static int initialized
;
2582 typedef (*function_ptr
) (void);
2584 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
2585 /* It's cheaper to clear the whole cache.
2586 Put in a series of jump instructions so that calling the beginning
2587 of the cache will clear the whole thing. */
2591 int ptr
= (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
2592 & -INSN_CACHE_LINE_WIDTH
);
2593 int end_ptr
= ptr
+ INSN_CACHE_SIZE
;
2595 while (ptr
< end_ptr
)
2597 *(INSTRUCTION_TYPE
*)ptr
2598 = JUMP_AHEAD_INSTRUCTION
+ INSN_CACHE_LINE_WIDTH
;
2599 ptr
+= INSN_CACHE_LINE_WIDTH
;
2601 *(INSTRUCTION_TYPE
*) (ptr
- INSN_CACHE_LINE_WIDTH
) = RETURN_INSTRUCTION
;
2606 /* Call the beginning of the sequence. */
2607 (((function_ptr
) (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
2608 & -INSN_CACHE_LINE_WIDTH
))
2611 #else /* Cache is large. */
2615 int ptr
= (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
2616 & -INSN_CACHE_LINE_WIDTH
);
2618 while (ptr
< (int) array
+ sizeof array
)
2620 *(INSTRUCTION_TYPE
*)ptr
= RETURN_INSTRUCTION
;
2621 ptr
+= INSN_CACHE_LINE_WIDTH
;
2627 /* Find the location in array that occupies the same cache line as BEG. */
2629 offset
= ((int) beg
& -INSN_CACHE_LINE_WIDTH
) & (INSN_CACHE_PLANE_SIZE
- 1);
2630 start_addr
= (((int) (array
+ INSN_CACHE_PLANE_SIZE
- 1)
2631 & -INSN_CACHE_PLANE_SIZE
)
2634 /* Compute the cache alignment of the place to stop clearing. */
2635 #if 0 /* This is not needed for gcc's purposes. */
2636 /* If the block to clear is bigger than a cache plane,
2637 we clear the entire cache, and OFFSET is already correct. */
2638 if (end
< beg
+ INSN_CACHE_PLANE_SIZE
)
2640 offset
= (((int) (end
+ INSN_CACHE_LINE_WIDTH
- 1)
2641 & -INSN_CACHE_LINE_WIDTH
)
2642 & (INSN_CACHE_PLANE_SIZE
- 1));
2644 #if INSN_CACHE_DEPTH > 1
2645 end_addr
= (start_addr
& -INSN_CACHE_PLANE_SIZE
) + offset
;
2646 if (end_addr
<= start_addr
)
2647 end_addr
+= INSN_CACHE_PLANE_SIZE
;
2649 for (plane
= 0; plane
< INSN_CACHE_DEPTH
; plane
++)
2651 int addr
= start_addr
+ plane
* INSN_CACHE_PLANE_SIZE
;
2652 int stop
= end_addr
+ plane
* INSN_CACHE_PLANE_SIZE
;
2654 while (addr
!= stop
)
2656 /* Call the return instruction at ADDR. */
2657 ((function_ptr
) addr
) ();
2659 addr
+= INSN_CACHE_LINE_WIDTH
;
2662 #else /* just one plane */
2665 /* Call the return instruction at START_ADDR. */
2666 ((function_ptr
) start_addr
) ();
2668 start_addr
+= INSN_CACHE_LINE_WIDTH
;
2670 while ((start_addr
% INSN_CACHE_SIZE
) != offset
);
2671 #endif /* just one plane */
2672 #endif /* Cache is large */
2673 #endif /* Cache exists */
2674 #endif /* CLEAR_INSN_CACHE */
2677 #endif /* L_clear_cache */
2681 /* Jump to a trampoline, loading the static chain address. */
2683 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
2696 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
2700 mprotect (char *addr
, int len
, int prot
)
2717 if (VirtualProtect (addr
, len
, np
, &op
))
2723 #endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
2725 #ifdef TRANSFER_FROM_TRAMPOLINE
2726 TRANSFER_FROM_TRAMPOLINE
2729 #if defined (NeXT) && defined (__MACH__)
2731 /* Make stack executable so we can call trampolines on stack.
2732 This is called from INITIALIZE_TRAMPOLINE in next.h. */
2736 #include <mach/mach.h>
2740 __enable_execute_stack (char *addr
)
2743 char *eaddr
= addr
+ TRAMPOLINE_SIZE
;
2744 vm_address_t a
= (vm_address_t
) addr
;
2746 /* turn on execute access on stack */
2747 r
= vm_protect (task_self (), a
, TRAMPOLINE_SIZE
, FALSE
, VM_PROT_ALL
);
2748 if (r
!= KERN_SUCCESS
)
2750 mach_error("vm_protect VM_PROT_ALL", r
);
2754 /* We inline the i-cache invalidation for speed */
2756 #ifdef CLEAR_INSN_CACHE
2757 CLEAR_INSN_CACHE (addr
, eaddr
);
2759 __clear_cache ((int) addr
, (int) eaddr
);
2763 #endif /* defined (NeXT) && defined (__MACH__) */
2767 /* Make stack executable so we can call trampolines on stack.
2768 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
2770 #include <sys/mman.h>
2771 #include <sys/vmparam.h>
2772 #include <machine/machparam.h>
2775 __enable_execute_stack (void)
2778 static unsigned lowest
= USRSTACK
;
2779 unsigned current
= (unsigned) &fp
& -NBPG
;
2781 if (lowest
> current
)
2783 unsigned len
= lowest
- current
;
2784 mremap (current
, &len
, PROT_READ
| PROT_WRITE
| PROT_EXEC
, MAP_PRIVATE
);
2788 /* Clear instruction cache in case an old trampoline is in it. */
2791 #endif /* __convex__ */
2795 /* Modified from the convex -code above. */
2797 #include <sys/param.h>
2799 #include <sys/m88kbcs.h>
2802 __enable_execute_stack (void)
2805 static unsigned long lowest
= USRSTACK
;
2806 unsigned long current
= (unsigned long) &save_errno
& -NBPC
;
2808 /* Ignore errno being set. memctl sets errno to EINVAL whenever the
2809 address is seen as 'negative'. That is the case with the stack. */
2812 if (lowest
> current
)
2814 unsigned len
=lowest
-current
;
2815 memctl(current
,len
,MCT_TEXT
);
2819 memctl(current
,NBPC
,MCT_TEXT
);
2823 #endif /* __sysV88__ */
2827 #include <sys/signal.h>
2830 /* Motorola forgot to put memctl.o in the libp version of libc881.a,
2831 so define it here, because we need it in __clear_insn_cache below */
2832 /* On older versions of this OS, no memctl or MCT_TEXT are defined;
2833 hence we enable this stuff only if MCT_TEXT is #define'd. */
2848 /* Clear instruction cache so we can call trampolines on stack.
2849 This is called from FINALIZE_TRAMPOLINE in mot3300.h. */
2852 __clear_insn_cache (void)
2857 /* Preserve errno, because users would be surprised to have
2858 errno changing without explicitly calling any system-call. */
2861 /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache.
2862 No need to use an address derived from _start or %sp, as 0 works also. */
2863 memctl(0, 4096, MCT_TEXT
);
2868 #endif /* __sysV68__ */
2872 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2874 #include <sys/mman.h>
2875 #include <sys/types.h>
2876 #include <sys/param.h>
2877 #include <sys/vmmac.h>
2879 /* Modified from the convex -code above.
2880 mremap promises to clear the i-cache. */
2883 __enable_execute_stack (void)
2886 if (mprotect (((unsigned int)&fp
/PAGSIZ
)*PAGSIZ
, PAGSIZ
,
2887 PROT_READ
|PROT_WRITE
|PROT_EXEC
))
2889 perror ("mprotect in __enable_execute_stack");
2894 #endif /* __pyr__ */
2896 #if defined (sony_news) && defined (SYSTYPE_BSD)
2899 #include <sys/types.h>
2900 #include <sys/param.h>
2901 #include <syscall.h>
2902 #include <machine/sysnews.h>
2904 /* cacheflush function for NEWS-OS 4.2.
2905 This function is called from trampoline-initialize code
2906 defined in config/mips/mips.h. */
2909 cacheflush (char *beg
, int size
, int flag
)
2911 if (syscall (SYS_sysnews
, NEWS_CACHEFLUSH
, beg
, size
, FLUSH_BCACHE
))
2913 perror ("cache_flush");
2919 #endif /* sony_news */
2920 #endif /* L_trampoline */
2925 #include "gbl-ctors.h"
2926 /* Some systems use __main in a way incompatible with its use in gcc, in these
2927 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2928 give the same symbol without quotes for an alternative entry point. You
2929 must define both, or neither. */
2931 #define NAME__MAIN "__main"
2932 #define SYMBOL__MAIN __main
2935 #ifdef INIT_SECTION_ASM_OP
2936 #undef HAS_INIT_SECTION
2937 #define HAS_INIT_SECTION
2940 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
2942 /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
2943 code to run constructors. In that case, we need to handle EH here, too. */
2945 #ifdef EH_FRAME_SECTION
2947 extern unsigned char __EH_FRAME_BEGIN__
[];
2950 /* Run all the global destructors on exit from the program. */
2953 __do_global_dtors (void)
2955 #ifdef DO_GLOBAL_DTORS_BODY
2956 DO_GLOBAL_DTORS_BODY
;
2958 static func_ptr
*p
= __DTOR_LIST__
+ 1;
2965 #if defined (EH_FRAME_SECTION) && !defined (HAS_INIT_SECTION)
2967 static int completed
= 0;
2971 __deregister_frame_info (__EH_FRAME_BEGIN__
);
2978 #ifndef HAS_INIT_SECTION
2979 /* Run all the global constructors on entry to the program. */
2982 __do_global_ctors (void)
2984 #ifdef EH_FRAME_SECTION
2986 static struct object object
;
2987 __register_frame_info (__EH_FRAME_BEGIN__
, &object
);
2990 DO_GLOBAL_CTORS_BODY
;
2991 atexit (__do_global_dtors
);
2993 #endif /* no HAS_INIT_SECTION */
2995 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
2996 /* Subroutine called automatically by `main'.
2997 Compiling a global function named `main'
2998 produces an automatic call to this function at the beginning.
3000 For many systems, this routine calls __do_global_ctors.
3001 For systems which support a .init section we use the .init section
3002 to run __do_global_ctors, so we need not do anything here. */
3007 /* Support recursive calls to `main': run initializers just once. */
3008 static int initialized
;
3012 __do_global_ctors ();
3015 #endif /* no HAS_INIT_SECTION or INVOKE__main */
3017 #endif /* L__main */
3018 #endif /* __CYGWIN__ */
3022 #include "gbl-ctors.h"
3024 /* Provide default definitions for the lists of constructors and
3025 destructors, so that we don't get linker errors. These symbols are
3026 intentionally bss symbols, so that gld and/or collect will provide
3027 the right values. */
3029 /* We declare the lists here with two elements each,
3030 so that they are valid empty lists if no other definition is loaded.
3032 If we are using the old "set" extensions to have the gnu linker
3033 collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
3034 must be in the bss/common section.
3036 Long term no port should use those extensions. But many still do. */
3037 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
3038 #if defined (ASM_OUTPUT_CONSTRUCTOR) || defined (USE_COLLECT2)
3039 func_ptr __CTOR_LIST__
[2] = {0, 0};
3040 func_ptr __DTOR_LIST__
[2] = {0, 0};
3042 func_ptr __CTOR_LIST__
[2];
3043 func_ptr __DTOR_LIST__
[2];
3045 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
3046 #endif /* L_ctors */
3050 #include "gbl-ctors.h"
3058 static func_ptr
*atexit_chain
= 0;
3059 static long atexit_chain_length
= 0;
3060 static volatile long last_atexit_chain_slot
= -1;
3063 atexit (func_ptr func
)
3065 if (++last_atexit_chain_slot
== atexit_chain_length
)
3067 atexit_chain_length
+= 32;
3069 atexit_chain
= (func_ptr
*) realloc (atexit_chain
, atexit_chain_length
3070 * sizeof (func_ptr
));
3072 atexit_chain
= (func_ptr
*) malloc (atexit_chain_length
3073 * sizeof (func_ptr
));
3076 atexit_chain_length
= 0;
3077 last_atexit_chain_slot
= -1;
3082 atexit_chain
[last_atexit_chain_slot
] = func
;
3086 extern void _cleanup (void);
3087 extern void _exit (int) __attribute__ ((__noreturn__
));
3094 for ( ; last_atexit_chain_slot
-- >= 0; )
3096 (*atexit_chain
[last_atexit_chain_slot
+ 1]) ();
3097 atexit_chain
[last_atexit_chain_slot
+ 1] = 0;
3099 free (atexit_chain
);
3112 /* Simple; we just need a wrapper for ON_EXIT. */
3114 atexit (func_ptr func
)
3116 return ON_EXIT (func
);
3119 #endif /* ON_EXIT */
3120 #endif /* NEED_ATEXIT */
3128 /* Shared exception handling support routines. */
3130 extern void __default_terminate (void) __attribute__ ((__noreturn__
));
3133 __default_terminate (void)
3138 void (*__terminate_func
)(void) __attribute__ ((__noreturn__
)) =
3139 __default_terminate
;
3144 (*__terminate_func
)();
3148 __throw_type_match (void *catch_type
, void *throw_type
, void *obj
)
3151 printf ("__throw_type_match (): catch_type = %s, throw_type = %s\n",
3152 catch_type
, throw_type
);
3154 if (strcmp ((const char *)catch_type
, (const char *)throw_type
) == 0)
3165 /* Include definitions of EH context and table layout */
3167 #include "eh-common.h"
3168 #ifndef inhibit_libc
3172 /* Allocate and return a new EH context structure. */
3174 extern void __throw (void);
3178 new_eh_context (void)
3180 struct eh_full_context
{
3181 struct eh_context c
;
3183 } *ehfc
= (struct eh_full_context
*) malloc (sizeof *ehfc
);
3188 memset (ehfc
, 0, sizeof *ehfc
);
3190 ehfc
->c
.dynamic_handler_chain
= (void **) ehfc
->top_elt
;
3192 /* This should optimize out entirely. This should always be true,
3193 but just in case it ever isn't, don't allow bogus code to be
3196 if ((void*)(&ehfc
->c
) != (void*)ehfc
)
3202 static __gthread_key_t eh_context_key
;
3204 /* Destructor for struct eh_context. */
3206 eh_context_free (void *ptr
)
3208 __gthread_key_dtor (eh_context_key
, ptr
);
3214 /* Pointer to function to return EH context. */
3216 static struct eh_context
*eh_context_initialize (void);
3217 static struct eh_context
*eh_context_static (void);
3219 static struct eh_context
*eh_context_specific (void);
3222 static struct eh_context
*(*get_eh_context
) (void) = &eh_context_initialize
;
3224 /* Routine to get EH context.
3225 This one will simply call the function pointer. */
3228 __get_eh_context (void)
3230 return (void *) (*get_eh_context
) ();
3233 /* Get and set the language specific info pointer. */
3236 __get_eh_info (void)
3238 struct eh_context
*eh
= (*get_eh_context
) ();
3242 #ifdef DWARF2_UNWIND_INFO
3243 static int dwarf_reg_size_table_initialized
= 0;
3244 static char dwarf_reg_size_table
[FIRST_PSEUDO_REGISTER
];
3247 init_reg_size_table (void)
3249 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table
);
3250 dwarf_reg_size_table_initialized
= 1;
3256 eh_threads_initialize (void)
3258 /* Try to create the key. If it fails, revert to static method,
3259 otherwise start using thread specific EH contexts. */
3260 if (__gthread_key_create (&eh_context_key
, &eh_context_free
) == 0)
3261 get_eh_context
= &eh_context_specific
;
3263 get_eh_context
= &eh_context_static
;
3265 #endif /* no __GTHREADS */
3267 /* Initialize EH context.
3268 This will be called only once, since we change GET_EH_CONTEXT
3269 pointer to another routine. */
3271 static struct eh_context
*
3272 eh_context_initialize (void)
3276 static __gthread_once_t once
= __GTHREAD_ONCE_INIT
;
3277 /* Make sure that get_eh_context does not point to us anymore.
3278 Some systems have dummy thread routines in their libc that
3279 return a success (Solaris 2.6 for example). */
3280 if (__gthread_once (&once
, eh_threads_initialize
) != 0
3281 || get_eh_context
== &eh_context_initialize
)
3283 /* Use static version of EH context. */
3284 get_eh_context
= &eh_context_static
;
3286 #ifdef DWARF2_UNWIND_INFO
3288 static __gthread_once_t once_regsizes
= __GTHREAD_ONCE_INIT
;
3289 if (__gthread_once (&once_regsizes
, init_reg_size_table
) != 0
3290 || ! dwarf_reg_size_table_initialized
)
3291 init_reg_size_table ();
3295 #else /* no __GTHREADS */
3297 /* Use static version of EH context. */
3298 get_eh_context
= &eh_context_static
;
3300 #ifdef DWARF2_UNWIND_INFO
3301 init_reg_size_table ();
3304 #endif /* no __GTHREADS */
3306 return (*get_eh_context
) ();
3309 /* Return a static EH context. */
3311 static struct eh_context
*
3312 eh_context_static (void)
3314 static struct eh_context eh
;
3315 static int initialized
;
3316 static void *top_elt
[2];
3321 memset (&eh
, 0, sizeof eh
);
3322 eh
.dynamic_handler_chain
= top_elt
;
3328 /* Return a thread specific EH context. */
3330 static struct eh_context
*
3331 eh_context_specific (void)
3333 struct eh_context
*eh
;
3334 eh
= (struct eh_context
*) __gthread_getspecific (eh_context_key
);
3337 eh
= new_eh_context ();
3338 if (__gthread_setspecific (eh_context_key
, (void *) eh
) != 0)
3346 /* Support routines for setjmp/longjmp exception handling. */
3348 /* Calls to __sjthrow are generated by the compiler when an exception
3349 is raised when using the setjmp/longjmp exception handling codegen
3352 #ifdef DONT_USE_BUILTIN_SETJMP
3353 extern void longjmp (void *, int);
3356 /* Routine to get the head of the current thread's dynamic handler chain
3357 use for exception handling. */
3360 __get_dynamic_handler_chain (void)
3362 struct eh_context
*eh
= (*get_eh_context
) ();
3363 return &eh
->dynamic_handler_chain
;
3366 /* This is used to throw an exception when the setjmp/longjmp codegen
3367 method is used for exception handling.
3369 We call __terminate if there are no handlers left. Otherwise we run the
3370 cleanup actions off the dynamic cleanup stack, and pop the top of the
3371 dynamic handler chain, and use longjmp to transfer back to the associated
3374 extern void __sjthrow (void) __attribute__ ((__noreturn__
));
3379 struct eh_context
*eh
= (*get_eh_context
) ();
3380 void ***dhc
= &eh
->dynamic_handler_chain
;
3382 void (*func
)(void *, int);
3384 /* The cleanup chain is one word into the buffer. Get the cleanup chain. */
3385 void ***cleanup
= (void***)&(*dhc
)[1];
3387 /* If there are any cleanups in the chain, run them now. */
3391 void **buf
= (void**)store
;
3396 #ifdef DONT_USE_BUILTIN_SETJMP
3397 if (! setjmp (&buf
[2]))
3399 if (! __builtin_setjmp (&buf
[2]))
3405 func
= (void(*)(void*, int))cleanup
[0][1];
3406 arg
= (void*)cleanup
[0][2];
3408 /* Update this before running the cleanup. */
3409 cleanup
[0] = (void **)cleanup
[0][0];
3422 /* We must call terminate if we try and rethrow an exception, when
3423 there is no exception currently active and when there are no
3425 if (! eh
->info
|| (*dhc
)[0] == 0)
3428 /* Find the jmpbuf associated with the top element of the dynamic
3429 handler chain. The jumpbuf starts two words into the buffer. */
3430 jmpbuf
= &(*dhc
)[2];
3432 /* Then we pop the top element off the dynamic handler chain. */
3433 *dhc
= (void**)(*dhc
)[0];
3435 /* And then we jump to the handler. */
3437 #ifdef DONT_USE_BUILTIN_SETJMP
3438 longjmp (jmpbuf
, 1);
3440 __builtin_longjmp (jmpbuf
, 1);
3444 /* Run cleanups on the dynamic cleanup stack for the current dynamic
3445 handler, then pop the handler off the dynamic handler stack, and
3446 then throw. This is used to skip the first handler, and transfer
3447 control to the next handler in the dynamic handler stack. */
3449 extern void __sjpopnthrow (void) __attribute__ ((__noreturn__
));
3452 __sjpopnthrow (void)
3454 struct eh_context
*eh
= (*get_eh_context
) ();
3455 void ***dhc
= &eh
->dynamic_handler_chain
;
3456 void (*func
)(void *, int);
3458 /* The cleanup chain is one word into the buffer. Get the cleanup chain. */
3459 void ***cleanup
= (void***)&(*dhc
)[1];
3461 /* If there are any cleanups in the chain, run them now. */
3465 void **buf
= (void**)store
;
3470 #ifdef DONT_USE_BUILTIN_SETJMP
3471 if (! setjmp (&buf
[2]))
3473 if (! __builtin_setjmp (&buf
[2]))
3479 func
= (void(*)(void*, int))cleanup
[0][1];
3480 arg
= (void*)cleanup
[0][2];
3482 /* Update this before running the cleanup. */
3483 cleanup
[0] = (void **)cleanup
[0][0];
3496 /* Then we pop the top element off the dynamic handler chain. */
3497 *dhc
= (void**)(*dhc
)[0];
3502 /* Support code for all exception region-based exception handling. */
3505 __eh_rtime_match (void *rtime
)
3508 __eh_matcher matcher
;
3511 info
= *(__get_eh_info ());
3512 matcher
= ((__eh_info
*)info
)->match_function
;
3515 #ifndef inhibit_libc
3516 fprintf (stderr
, "Internal Compiler Bug: No runtime type matcher.");
3520 ret
= (*matcher
) (info
, rtime
, (void *)0);
3521 return (ret
!= NULL
);
3524 /* This value identifies the place from which an exception is being
3527 #ifdef EH_TABLE_LOOKUP
3533 #ifdef DWARF2_UNWIND_INFO
3535 /* Return the table version of an exception descriptor */
3538 __get_eh_table_version (exception_descriptor
*table
)
3540 return table
->lang
.version
;
3543 /* Return the originating table language of an exception descriptor */
3546 __get_eh_table_language (exception_descriptor
*table
)
3548 return table
->lang
.language
;
3551 /* This routine takes a PC and a pointer to the exception region TABLE for
3552 its translation unit, and returns the address of the exception handler
3553 associated with the closest exception table handler entry associated
3554 with that PC, or 0 if there are no table entries the PC fits in.
3556 In the advent of a tie, we have to give the last entry, as it represents
3560 old_find_exception_handler (void *pc
, old_exception_table
*table
)
3567 /* We can't do a binary search because the table isn't guaranteed
3568 to be sorted from function to function. */
3569 for (pos
= 0; table
[pos
].start_region
!= (void *) -1; ++pos
)
3571 if (table
[pos
].start_region
<= pc
&& table
[pos
].end_region
> pc
)
3573 /* This can apply. Make sure it is at least as small as
3574 the previous best. */
3575 if (best
== -1 || (table
[pos
].end_region
<= table
[best
].end_region
3576 && table
[pos
].start_region
>= table
[best
].start_region
))
3579 /* But it is sorted by starting PC within a function. */
3580 else if (best
>= 0 && table
[pos
].start_region
> pc
)
3584 return table
[best
].exception_handler
;
3590 /* find_exception_handler finds the correct handler, if there is one, to
3591 handle an exception.
3592 returns a pointer to the handler which controlled should be transferred
3593 to, or NULL if there is nothing left.
3595 PC - pc where the exception originates. If this is a rethrow,
3596 then this starts out as a pointer to the exception table
3597 entry we wish to rethrow out of.
3598 TABLE - exception table for the current module.
3599 EH_INFO - eh info pointer for this exception.
3600 RETHROW - 1 if this is a rethrow. (see incoming value of PC).
3601 CLEANUP - returned flag indicating whether this is a cleanup handler.
3604 find_exception_handler (void *pc
, exception_descriptor
*table
,
3605 __eh_info
*eh_info
, int rethrow
, int *cleanup
)
3608 void *retval
= NULL
;
3613 /* The new model assumed the table is sorted inner-most out so the
3614 first region we find which matches is the correct one */
3616 exception_table
*tab
= &(table
->table
[0]);
3618 /* Subtract 1 from the PC to avoid hitting the next region */
3621 /* pc is actually the region table entry to rethrow out of */
3622 pos
= ((exception_table
*) pc
) - tab
;
3623 pc
= ((exception_table
*) pc
)->end_region
- 1;
3625 /* The label is always on the LAST handler entry for a region,
3626 so we know the next entry is a different region, even if the
3627 addresses are the same. Make sure its not end of table tho. */
3628 if (tab
[pos
].start_region
!= (void *) -1)
3634 /* We can't do a binary search because the table is in inner-most
3635 to outermost address ranges within functions */
3636 for ( ; tab
[pos
].start_region
!= (void *) -1; pos
++)
3638 if (tab
[pos
].start_region
<= pc
&& tab
[pos
].end_region
> pc
)
3640 if (tab
[pos
].match_info
)
3642 __eh_matcher matcher
= eh_info
->match_function
;
3643 /* match info but no matcher is NOT a match */
3646 void *ret
= (*matcher
)((void *) eh_info
,
3647 tab
[pos
].match_info
, table
);
3651 retval
= tab
[pos
].exception_handler
;
3660 retval
= tab
[pos
].exception_handler
;
3667 #endif /* DWARF2_UNWIND_INFO */
3668 #endif /* EH_TABLE_LOOKUP */
3670 #ifdef DWARF2_UNWIND_INFO
3671 /* Support code for exception handling using static unwind information. */
3675 /* This type is used in get_reg and put_reg to deal with ABIs where a void*
3676 is smaller than a word, such as the Irix 6 n32 ABI. We cast twice to
3677 avoid a warning about casting between int and pointer of different
3680 typedef int ptr_type
__attribute__ ((mode (pointer
)));
3682 #ifdef INCOMING_REGNO
3683 /* Is the saved value for register REG in frame UDATA stored in a register
3684 window in the previous frame? */
3686 /* ??? The Sparc INCOMING_REGNO references TARGET_FLAT. This allows us
3687 to use the macro here. One wonders, though, that perhaps TARGET_FLAT
3688 compiled functions won't work with the frame-unwind stuff here.
3689 Perhaps the entireity of in_reg_window should be conditional on having
3690 seen a DW_CFA_GNU_window_save? */
3691 #define target_flags 0
3694 in_reg_window (int reg
, frame_state
*udata
)
3696 if (udata
->saved
[reg
] == REG_SAVED_REG
)
3697 return INCOMING_REGNO (reg
) == reg
;
3698 if (udata
->saved
[reg
] != REG_SAVED_OFFSET
)
3701 #ifdef STACK_GROWS_DOWNWARD
3702 return udata
->reg_or_offset
[reg
] > 0;
3704 return udata
->reg_or_offset
[reg
] < 0;
3709 in_reg_window (int reg
__attribute__ ((__unused__
)),
3710 frame_state
*udata
__attribute__ ((__unused__
)))
3714 #endif /* INCOMING_REGNO */
3716 /* Get the address of register REG as saved in UDATA, where SUB_UDATA is a
3717 frame called by UDATA or 0. */
3720 get_reg_addr (unsigned reg
, frame_state
*udata
, frame_state
*sub_udata
)
3722 while (udata
->saved
[reg
] == REG_SAVED_REG
)
3724 reg
= udata
->reg_or_offset
[reg
];
3725 if (in_reg_window (reg
, udata
))
3731 if (udata
->saved
[reg
] == REG_SAVED_OFFSET
)
3732 return (word_type
*)(udata
->cfa
+ udata
->reg_or_offset
[reg
]);
3737 /* Get the value of register REG as saved in UDATA, where SUB_UDATA is a
3738 frame called by UDATA or 0. */
3740 static inline void *
3741 get_reg (unsigned reg
, frame_state
*udata
, frame_state
*sub_udata
)
3743 return (void *)(ptr_type
) *get_reg_addr (reg
, udata
, sub_udata
);
3746 /* Overwrite the saved value for register REG in frame UDATA with VAL. */
3749 put_reg (unsigned reg
, void *val
, frame_state
*udata
)
3751 *get_reg_addr (reg
, udata
, NULL
) = (word_type
)(ptr_type
) val
;
3754 /* Copy the saved value for register REG from frame UDATA to frame
3755 TARGET_UDATA. Unlike the previous two functions, this can handle
3756 registers that are not one word large. */
3759 copy_reg (unsigned reg
, frame_state
*udata
, frame_state
*target_udata
)
3761 word_type
*preg
= get_reg_addr (reg
, udata
, NULL
);
3762 word_type
*ptreg
= get_reg_addr (reg
, target_udata
, NULL
);
3764 memcpy (ptreg
, preg
, dwarf_reg_size_table
[reg
]);
3767 /* Retrieve the return address for frame UDATA. */
3769 static inline void *
3770 get_return_addr (frame_state
*udata
, frame_state
*sub_udata
)
3772 return __builtin_extract_return_addr
3773 (get_reg (udata
->retaddr_column
, udata
, sub_udata
));
3776 /* Overwrite the return address for frame UDATA with VAL. */
3779 put_return_addr (void *val
, frame_state
*udata
)
3781 val
= __builtin_frob_return_addr (val
);
3782 put_reg (udata
->retaddr_column
, val
, udata
);
3785 /* Given the current frame UDATA and its return address PC, return the
3786 information about the calling frame in CALLER_UDATA. */
3789 next_stack_level (void *pc
, frame_state
*udata
, frame_state
*caller_udata
)
3791 caller_udata
= __frame_state_for (pc
, caller_udata
);
3795 /* Now go back to our caller's stack frame. If our caller's CFA register
3796 was saved in our stack frame, restore it; otherwise, assume the CFA
3797 register is SP and restore it to our CFA value. */
3798 if (udata
->saved
[caller_udata
->cfa_reg
])
3799 caller_udata
->cfa
= get_reg (caller_udata
->cfa_reg
, udata
, 0);
3801 caller_udata
->cfa
= udata
->cfa
;
3802 caller_udata
->cfa
+= caller_udata
->cfa_offset
;
3804 return caller_udata
;
3807 /* Hook to call before __terminate if only cleanup handlers remain. */
3809 __unwinding_cleanup (void)
3813 /* throw_helper performs some of the common grunt work for a throw. This
3814 routine is called by throw and rethrows. This is pretty much split
3815 out from the old __throw routine. An addition has been added which allows
3816 for a dummy call to a routine __unwinding_cleanup() when there are nothing
3817 but cleanups remaining. This allows a debugger to examine the state
3818 at which the throw was executed, before any cleanups, rather than
3819 at the terminate point after the stack has been unwound.
3821 EH is the current eh_context structure.
3822 PC is the address of the call to __throw.
3823 MY_UDATA is the unwind information for __throw.
3824 OFFSET_P is where we return the SP adjustment offset. */
3827 throw_helper (struct eh_context
*eh
, void *pc
, frame_state
*my_udata
,
3830 frame_state ustruct2
, *udata
= &ustruct2
;
3831 frame_state ustruct
;
3832 frame_state
*sub_udata
= &ustruct
;
3833 void *saved_pc
= pc
;
3835 void *handler_p
= 0;
3837 frame_state saved_ustruct
;
3840 int only_cleanup
= 0;
3842 int saved_state
= 0;
3844 __eh_info
*eh_info
= (__eh_info
*)eh
->info
;
3846 /* Do we find a handler based on a re-throw PC? */
3847 if (eh
->table_index
!= (void *) 0)
3850 memcpy (udata
, my_udata
, sizeof (*udata
));
3852 handler
= (void *) 0;
3855 frame_state
*p
= udata
;
3856 udata
= next_stack_level (pc
, udata
, sub_udata
);
3859 /* If we couldn't find the next frame, we lose. */
3863 if (udata
->eh_ptr
== NULL
)
3866 new_eh_model
= (((exception_descriptor
*)(udata
->eh_ptr
))->
3867 runtime_id_field
== NEW_EH_RUNTIME
);
3872 handler
= find_exception_handler (eh
->table_index
, udata
->eh_ptr
,
3873 eh_info
, 1, &cleanup
);
3874 eh
->table_index
= (void *)0;
3878 handler
= find_exception_handler (pc
, udata
->eh_ptr
, eh_info
,
3881 handler
= old_find_exception_handler (pc
, udata
->eh_ptr
);
3883 /* If we found one, we can stop searching, if its not a cleanup.
3884 for cleanups, we save the state, and keep looking. This allows
3885 us to call a debug hook if there are nothing but cleanups left. */
3892 saved_ustruct
= *udata
;
3893 handler_p
= handler
;
3906 /* Otherwise, we continue searching. We subtract 1 from PC to avoid
3907 hitting the beginning of the next region. */
3908 pc
= get_return_addr (udata
, sub_udata
) - 1;
3913 udata
= &saved_ustruct
;
3914 handler
= handler_p
;
3917 __unwinding_cleanup ();
3920 /* If we haven't found a handler by now, this is an unhandled
3925 eh
->handler_label
= handler
;
3927 args_size
= udata
->args_size
;
3930 /* We found a handler in the throw context, no need to unwind. */
3936 /* Unwind all the frames between this one and the handler by copying
3937 their saved register values into our register save slots. */
3939 /* Remember the PC where we found the handler. */
3940 void *handler_pc
= pc
;
3942 /* Start from the throw context again. */
3944 memcpy (udata
, my_udata
, sizeof (*udata
));
3946 while (pc
!= handler_pc
)
3948 frame_state
*p
= udata
;
3949 udata
= next_stack_level (pc
, udata
, sub_udata
);
3952 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; ++i
)
3953 if (i
!= udata
->retaddr_column
&& udata
->saved
[i
])
3955 /* If you modify the saved value of the return address
3956 register on the SPARC, you modify the return address for
3957 your caller's frame. Don't do that here, as it will
3958 confuse get_return_addr. */
3959 if (in_reg_window (i
, udata
)
3960 && udata
->saved
[udata
->retaddr_column
] == REG_SAVED_REG
3961 && udata
->reg_or_offset
[udata
->retaddr_column
] == i
)
3963 copy_reg (i
, udata
, my_udata
);
3966 pc
= get_return_addr (udata
, sub_udata
) - 1;
3969 /* But we do need to update the saved return address register from
3970 the last frame we unwind, or the handler frame will have the wrong
3972 if (udata
->saved
[udata
->retaddr_column
] == REG_SAVED_REG
)
3974 i
= udata
->reg_or_offset
[udata
->retaddr_column
];
3975 if (in_reg_window (i
, udata
))
3976 copy_reg (i
, udata
, my_udata
);
3979 /* udata now refers to the frame called by the handler frame. */
3981 /* We adjust SP by the difference between __throw's CFA and the CFA for
3982 the frame called by the handler frame, because those CFAs correspond
3983 to the SP values at the two call sites. We need to further adjust by
3984 the args_size of the handler frame itself to get the handler frame's
3985 SP from before the args were pushed for that call. */
3986 #ifdef STACK_GROWS_DOWNWARD
3987 *offset_p
= udata
->cfa
- my_udata
->cfa
+ args_size
;
3989 *offset_p
= my_udata
->cfa
- udata
->cfa
- args_size
;
3996 /* We first search for an exception handler, and if we don't find
3997 it, we call __terminate on the current stack frame so that we may
3998 use the debugger to walk the stack and understand why no handler
4001 If we find one, then we unwind the frames down to the one that
4002 has the handler and transfer control into the handler. */
4004 /*extern void __throw(void) __attribute__ ((__noreturn__));*/
4009 struct eh_context
*eh
= (*get_eh_context
) ();
4013 /* XXX maybe make my_ustruct static so we don't have to look it up for
4015 frame_state my_ustruct
, *my_udata
= &my_ustruct
;
4017 /* This is required for C++ semantics. We must call terminate if we
4018 try and rethrow an exception, when there is no exception currently
4023 /* Start at our stack frame. */
4025 my_udata
= __frame_state_for (&&label
, my_udata
);
4029 /* We need to get the value from the CFA register. */
4030 my_udata
->cfa
= __builtin_dwarf_cfa ();
4032 /* Do any necessary initialization to access arbitrary stack frames.
4033 On the SPARC, this means flushing the register windows. */
4034 __builtin_unwind_init ();
4036 /* Now reset pc to the right throw point. */
4037 pc
= __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
4039 handler
= throw_helper (eh
, pc
, my_udata
, &offset
);
4043 __builtin_eh_return ((void *)eh
, offset
, handler
);
4045 /* Epilogue: restore the handler frame's register values and return
4049 /*extern void __rethrow(void *) __attribute__ ((__noreturn__));*/
4052 __rethrow (void *index
)
4054 struct eh_context
*eh
= (*get_eh_context
) ();
4058 /* XXX maybe make my_ustruct static so we don't have to look it up for
4060 frame_state my_ustruct
, *my_udata
= &my_ustruct
;
4062 /* This is required for C++ semantics. We must call terminate if we
4063 try and rethrow an exception, when there is no exception currently
4068 /* This is the table index we want to rethrow from. The value of
4069 the END_REGION label is used for the PC of the throw, and the
4070 search begins with the next table entry. */
4071 eh
->table_index
= index
;
4073 /* Start at our stack frame. */
4075 my_udata
= __frame_state_for (&&label
, my_udata
);
4079 /* We need to get the value from the CFA register. */
4080 my_udata
->cfa
= __builtin_dwarf_cfa ();
4082 /* Do any necessary initialization to access arbitrary stack frames.
4083 On the SPARC, this means flushing the register windows. */
4084 __builtin_unwind_init ();
4086 /* Now reset pc to the right throw point. */
4087 pc
= __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
4089 handler
= throw_helper (eh
, pc
, my_udata
, &offset
);
4093 __builtin_eh_return ((void *)eh
, offset
, handler
);
4095 /* Epilogue: restore the handler frame's register values and return
4098 #endif /* DWARF2_UNWIND_INFO */
4103 #ifndef inhibit_libc
4104 /* This gets us __GNU_LIBRARY__. */
4105 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
4108 #ifdef __GNU_LIBRARY__
4109 /* Avoid forcing the library's meaning of `write' on the user program
4110 by using the "internal" name (for use within the library) */
4111 #define write(fd, buf, n) __write((fd), (buf), (n))
4113 #endif /* inhibit_libc */
4115 #define MESSAGE "pure virtual method called\n"
4117 extern void __terminate (void) __attribute__ ((__noreturn__
));
4120 __pure_virtual (void)
4122 #ifndef inhibit_libc
4123 write (2, MESSAGE
, sizeof (MESSAGE
) - 1);