1 /* More subroutines needed by GCC output code on some machines. */
2 /* Compile this one with gcc. */
3 /* Copyright (C) 1989, 92, 93, 94, 95, 1996 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
40 /* Don't use `fancy_abort' here even if config.h says to use it. */
45 #if (SUPPORTS_WEAK == 1) && defined (ASM_OUTPUT_DEF)
49 /* Permit the tm.h file to select the endianness to use just for this
50 file. This is used when the endianness is determined when the
53 #ifndef LIBGCC2_WORDS_BIG_ENDIAN
54 #define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
57 /* In the first part of this file, we are interfacing to calls generated
58 by the compiler itself. These calls pass values into these routines
59 which have very specific modes (rather than very specific types), and
60 these compiler-generated calls also expect any return values to have
61 very specific modes (rather than very specific types). Thus, we need
62 to avoid using regular C language type names in this part of the file
63 because the sizes for those types can be configured to be anything.
64 Instead we use the following special type names. */
66 typedef unsigned int UQItype
__attribute__ ((mode (QI
)));
67 typedef int SItype
__attribute__ ((mode (SI
)));
68 typedef unsigned int USItype
__attribute__ ((mode (SI
)));
69 typedef int DItype
__attribute__ ((mode (DI
)));
70 typedef unsigned int UDItype
__attribute__ ((mode (DI
)));
72 typedef float SFtype
__attribute__ ((mode (SF
)));
73 typedef float DFtype
__attribute__ ((mode (DF
)));
75 #if LONG_DOUBLE_TYPE_SIZE == 96
76 typedef float XFtype
__attribute__ ((mode (XF
)));
78 #if LONG_DOUBLE_TYPE_SIZE == 128
79 typedef float TFtype
__attribute__ ((mode (TF
)));
82 typedef int word_type
__attribute__ ((mode (__word__
)));
84 /* Make sure that we don't accidentally use any normal C language built-in
85 type names in the first part of this file. Instead we want to use *only*
86 the type names defined above. The following macro definitions insure
87 that if we *do* accidentally use some normal C language built-in type name,
88 we will get a syntax error. */
90 #define char bogus_type
91 #define short bogus_type
92 #define int bogus_type
93 #define long bogus_type
94 #define unsigned bogus_type
95 #define float bogus_type
96 #define double bogus_type
98 #define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
100 /* DIstructs are pairs of SItype values in the order determined by
101 LIBGCC2_WORDS_BIG_ENDIAN. */
103 #if LIBGCC2_WORDS_BIG_ENDIAN
104 struct DIstruct
{SItype high
, low
;};
106 struct DIstruct
{SItype low
, high
;};
109 /* We need this union to unpack/pack DImode values, since we don't have
110 any arithmetic yet. Incoming DImode parameters are stored into the
111 `ll' field, and the unpacked result is read from the struct `s'. */
119 #if (defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_w_sdiv)\
120 || defined (L_divdi3) || defined (L_udivdi3) \
121 || defined (L_moddi3) || defined (L_umoddi3))
123 #include "longlong.h"
125 #endif /* udiv or mul */
127 extern DItype
__fixunssfdi (SFtype a
);
128 extern DItype
__fixunsdfdi (DFtype a
);
129 #if LONG_DOUBLE_TYPE_SIZE == 96
130 extern DItype
__fixunsxfdi (XFtype a
);
132 #if LONG_DOUBLE_TYPE_SIZE == 128
133 extern DItype
__fixunstfdi (TFtype a
);
136 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
137 #if defined (L_divdi3) || defined (L_moddi3)
150 w
.s
.high
= -uu
.s
.high
- ((USItype
) w
.s
.low
> 0);
171 bm
= (sizeof (SItype
) * BITS_PER_UNIT
) - b
;
175 w
.s
.low
= (USItype
)uu
.s
.high
>> -bm
;
179 USItype carries
= (USItype
)uu
.s
.high
<< bm
;
180 w
.s
.high
= (USItype
)uu
.s
.high
>> b
;
181 w
.s
.low
= ((USItype
)uu
.s
.low
>> b
) | carries
;
203 bm
= (sizeof (SItype
) * BITS_PER_UNIT
) - b
;
207 w
.s
.high
= (USItype
)uu
.s
.low
<< -bm
;
211 USItype carries
= (USItype
)uu
.s
.low
>> bm
;
212 w
.s
.low
= (USItype
)uu
.s
.low
<< b
;
213 w
.s
.high
= ((USItype
)uu
.s
.high
<< b
) | carries
;
235 bm
= (sizeof (SItype
) * BITS_PER_UNIT
) - b
;
238 /* w.s.high = 1..1 or 0..0 */
239 w
.s
.high
= uu
.s
.high
>> (sizeof (SItype
) * BITS_PER_UNIT
- 1);
240 w
.s
.low
= uu
.s
.high
>> -bm
;
244 USItype carries
= (USItype
)uu
.s
.high
<< bm
;
245 w
.s
.high
= uu
.s
.high
>> b
;
246 w
.s
.low
= ((USItype
)uu
.s
.low
>> b
) | carries
;
261 w
.s
.low
= ffs (uu
.s
.low
);
264 w
.s
.low
= ffs (uu
.s
.high
);
267 w
.s
.low
+= BITS_PER_UNIT
* sizeof (SItype
);
285 w
.ll
= __umulsidi3 (uu
.s
.low
, vv
.s
.low
);
286 w
.s
.high
+= ((USItype
) uu
.s
.low
* (USItype
) vv
.s
.high
287 + (USItype
) uu
.s
.high
* (USItype
) vv
.s
.low
);
294 #if defined (sdiv_qrnnd)
296 __udiv_w_sdiv (rp
, a1
, a0
, d
)
297 USItype
*rp
, a1
, a0
, d
;
304 if (a1
< d
- a1
- (a0
>> (SI_TYPE_SIZE
- 1)))
306 /* dividend, divisor, and quotient are nonnegative */
307 sdiv_qrnnd (q
, r
, a1
, a0
, d
);
311 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
312 sub_ddmmss (c1
, c0
, a1
, a0
, d
>> 1, d
<< (SI_TYPE_SIZE
- 1));
313 /* Divide (c1*2^32 + c0) by d */
314 sdiv_qrnnd (q
, r
, c1
, c0
, d
);
315 /* Add 2^31 to quotient */
316 q
+= (USItype
) 1 << (SI_TYPE_SIZE
- 1);
321 b1
= d
>> 1; /* d/2, between 2^30 and 2^31 - 1 */
322 c1
= a1
>> 1; /* A/2 */
323 c0
= (a1
<< (SI_TYPE_SIZE
- 1)) + (a0
>> 1);
325 if (a1
< b1
) /* A < 2^32*b1, so A/2 < 2^31*b1 */
327 sdiv_qrnnd (q
, r
, c1
, c0
, b1
); /* (A/2) / (d/2) */
329 r
= 2*r
+ (a0
& 1); /* Remainder from A/(2*b1) */
346 else if (c1
< b1
) /* So 2^31 <= (A/2)/b1 < 2^32 */
349 c0
= ~c0
; /* logical NOT */
351 sdiv_qrnnd (q
, r
, c1
, c0
, b1
); /* (A/2) / (d/2) */
353 q
= ~q
; /* (A/2)/b1 */
356 r
= 2*r
+ (a0
& 1); /* A/(2*b1) */
374 else /* Implies c1 = b1 */
375 { /* Hence a1 = d - 1 = 2*b1 - 1 */
393 /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */
395 __udiv_w_sdiv (rp
, a1
, a0
, d
)
396 USItype
*rp
, a1
, a0
, d
;
401 #if (defined (L_udivdi3) || defined (L_divdi3) || \
402 defined (L_umoddi3) || defined (L_moddi3))
407 static const UQItype __clz_tab
[] =
409 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,
410 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,
411 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,
412 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,
413 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,
414 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,
415 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,
416 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,
419 #if (defined (L_udivdi3) || defined (L_divdi3) || \
420 defined (L_umoddi3) || defined (L_moddi3))
424 __udivmoddi4 (n
, d
, rp
)
431 USItype d0
, d1
, n0
, n1
, n2
;
443 #if !UDIV_NEEDS_NORMALIZATION
450 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
453 /* Remainder in n0. */
460 d0
= 1 / d0
; /* Divide intentionally by zero. */
462 udiv_qrnnd (q1
, n1
, 0, n1
, d0
);
463 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
465 /* Remainder in n0. */
476 #else /* UDIV_NEEDS_NORMALIZATION */
484 count_leading_zeros (bm
, d0
);
488 /* Normalize, i.e. make the most significant bit of the
492 n1
= (n1
<< bm
) | (n0
>> (SI_TYPE_SIZE
- bm
));
496 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
499 /* Remainder in n0 >> bm. */
506 d0
= 1 / d0
; /* Divide intentionally by zero. */
508 count_leading_zeros (bm
, d0
);
512 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
513 conclude (the most significant bit of n1 is set) /\ (the
514 leading quotient digit q1 = 1).
516 This special case is necessary, not an optimization.
517 (Shifts counts of SI_TYPE_SIZE are undefined.) */
526 b
= SI_TYPE_SIZE
- bm
;
530 n1
= (n1
<< bm
) | (n0
>> b
);
533 udiv_qrnnd (q1
, n1
, n2
, n1
, d0
);
538 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
540 /* Remainder in n0 >> bm. */
550 #endif /* UDIV_NEEDS_NORMALIZATION */
561 /* Remainder in n1n0. */
573 count_leading_zeros (bm
, d1
);
576 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
577 conclude (the most significant bit of n1 is set) /\ (the
578 quotient digit q0 = 0 or 1).
580 This special case is necessary, not an optimization. */
582 /* The condition on the next line takes advantage of that
583 n1 >= d1 (true due to program flow). */
584 if (n1
> d1
|| n0
>= d0
)
587 sub_ddmmss (n1
, n0
, n1
, n0
, d1
, d0
);
606 b
= SI_TYPE_SIZE
- bm
;
608 d1
= (d1
<< bm
) | (d0
>> b
);
611 n1
= (n1
<< bm
) | (n0
>> b
);
614 udiv_qrnnd (q0
, n1
, n2
, n1
, d1
);
615 umul_ppmm (m1
, m0
, q0
, d0
);
617 if (m1
> n1
|| (m1
== n1
&& m0
> n0
))
620 sub_ddmmss (m1
, m0
, m1
, m0
, d1
, d0
);
625 /* Remainder in (n1n0 - m1m0) >> bm. */
628 sub_ddmmss (n1
, n0
, n1
, n0
, m1
, m0
);
629 rr
.s
.low
= (n1
<< b
) | (n0
>> bm
);
630 rr
.s
.high
= n1
>> bm
;
644 UDItype
__udivmoddi4 ();
659 uu
.ll
= __negdi2 (uu
.ll
);
662 vv
.ll
= __negdi2 (vv
.ll
);
664 w
= __udivmoddi4 (uu
.ll
, vv
.ll
, (UDItype
*) 0);
673 UDItype
__udivmoddi4 ();
687 uu
.ll
= __negdi2 (uu
.ll
);
689 vv
.ll
= __negdi2 (vv
.ll
);
691 (void) __udivmoddi4 (uu
.ll
, vv
.ll
, &w
);
700 UDItype
__udivmoddi4 ();
707 (void) __udivmoddi4 (u
, v
, &w
);
714 UDItype
__udivmoddi4 ();
719 return __udivmoddi4 (n
, d
, (UDItype
*) 0);
730 au
.ll
= a
, bu
.ll
= b
;
732 if (au
.s
.high
< bu
.s
.high
)
734 else if (au
.s
.high
> bu
.s
.high
)
736 if ((USItype
) au
.s
.low
< (USItype
) bu
.s
.low
)
738 else if ((USItype
) au
.s
.low
> (USItype
) bu
.s
.low
)
751 au
.ll
= a
, bu
.ll
= b
;
753 if ((USItype
) au
.s
.high
< (USItype
) bu
.s
.high
)
755 else if ((USItype
) au
.s
.high
> (USItype
) bu
.s
.high
)
757 if ((USItype
) au
.s
.low
< (USItype
) bu
.s
.low
)
759 else if ((USItype
) au
.s
.low
> (USItype
) bu
.s
.low
)
765 #if defined(L_fixunstfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
766 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
767 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
779 /* Compute high word of result, as a flonum. */
780 b
= (a
/ HIGH_WORD_COEFF
);
781 /* Convert that to fixed (but not to DItype!),
782 and shift it into the high word. */
785 /* Remove high part from the TFtype, leaving the low part as flonum. */
787 /* Convert that to fixed (but not to DItype!) and add it in.
788 Sometimes A comes out negative. This is significant, since
789 A has more bits than a long int does. */
791 v
-= (USItype
) (- a
);
798 #if defined(L_fixtfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
804 return - __fixunstfdi (-a
);
805 return __fixunstfdi (a
);
809 #if defined(L_fixunsxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
810 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
811 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
823 /* Compute high word of result, as a flonum. */
824 b
= (a
/ HIGH_WORD_COEFF
);
825 /* Convert that to fixed (but not to DItype!),
826 and shift it into the high word. */
829 /* Remove high part from the XFtype, leaving the low part as flonum. */
831 /* Convert that to fixed (but not to DItype!) and add it in.
832 Sometimes A comes out negative. This is significant, since
833 A has more bits than a long int does. */
835 v
-= (USItype
) (- a
);
842 #if defined(L_fixxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
848 return - __fixunsxfdi (-a
);
849 return __fixunsxfdi (a
);
854 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
855 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
867 /* Compute high word of result, as a flonum. */
868 b
= (a
/ HIGH_WORD_COEFF
);
869 /* Convert that to fixed (but not to DItype!),
870 and shift it into the high word. */
873 /* Remove high part from the DFtype, leaving the low part as flonum. */
875 /* Convert that to fixed (but not to DItype!) and add it in.
876 Sometimes A comes out negative. This is significant, since
877 A has more bits than a long int does. */
879 v
-= (USItype
) (- a
);
892 return - __fixunsdfdi (-a
);
893 return __fixunsdfdi (a
);
898 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
899 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
902 __fixunssfdi (SFtype original_a
)
904 /* Convert the SFtype to a DFtype, because that is surely not going
905 to lose any bits. Some day someone else can write a faster version
906 that avoids converting to DFtype, and verify it really works right. */
907 DFtype a
= original_a
;
914 /* Compute high word of result, as a flonum. */
915 b
= (a
/ HIGH_WORD_COEFF
);
916 /* Convert that to fixed (but not to DItype!),
917 and shift it into the high word. */
920 /* Remove high part from the DFtype, leaving the low part as flonum. */
922 /* Convert that to fixed (but not to DItype!) and add it in.
923 Sometimes A comes out negative. This is significant, since
924 A has more bits than a long int does. */
926 v
-= (USItype
) (- a
);
938 return - __fixunssfdi (-a
);
939 return __fixunssfdi (a
);
943 #if defined(L_floatdixf) && (LONG_DOUBLE_TYPE_SIZE == 96)
944 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
945 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
946 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
958 d
= (USItype
) (u
>> WORD_SIZE
);
959 d
*= HIGH_HALFWORD_COEFF
;
960 d
*= HIGH_HALFWORD_COEFF
;
961 d
+= (USItype
) (u
& (HIGH_WORD_COEFF
- 1));
963 return (negate
? -d
: d
);
967 #if defined(L_floatditf) && (LONG_DOUBLE_TYPE_SIZE == 128)
968 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
969 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
970 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
982 d
= (USItype
) (u
>> WORD_SIZE
);
983 d
*= HIGH_HALFWORD_COEFF
;
984 d
*= HIGH_HALFWORD_COEFF
;
985 d
+= (USItype
) (u
& (HIGH_WORD_COEFF
- 1));
987 return (negate
? -d
: d
);
992 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
993 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
994 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
1006 d
= (USItype
) (u
>> WORD_SIZE
);
1007 d
*= HIGH_HALFWORD_COEFF
;
1008 d
*= HIGH_HALFWORD_COEFF
;
1009 d
+= (USItype
) (u
& (HIGH_WORD_COEFF
- 1));
1011 return (negate
? -d
: d
);
1016 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
1017 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
1018 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
1019 #define DI_SIZE (sizeof (DItype) * BITS_PER_UNIT)
1021 /* Define codes for all the float formats that we know of. Note
1022 that this is copied from real.h. */
1024 #define UNKNOWN_FLOAT_FORMAT 0
1025 #define IEEE_FLOAT_FORMAT 1
1026 #define VAX_FLOAT_FORMAT 2
1027 #define IBM_FLOAT_FORMAT 3
1029 /* Default to IEEE float if not specified. Nearly all machines use it. */
1030 #ifndef HOST_FLOAT_FORMAT
1031 #define HOST_FLOAT_FORMAT IEEE_FLOAT_FORMAT
1034 #if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1039 #if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
1044 #if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
1053 /* Do the calculation in DFmode
1054 so that we don't lose any of the precision of the high word
1055 while multiplying it. */
1062 /* Protect against double-rounding error.
1063 Represent any low-order bits, that might be truncated in DFmode,
1064 by a bit that won't be lost. The bit can go in anywhere below the
1065 rounding position of the SFmode. A fixed mask and bit position
1066 handles all usual configurations. It doesn't handle the case
1067 of 128-bit DImode, however. */
1068 if (DF_SIZE
< DI_SIZE
1069 && DF_SIZE
> (DI_SIZE
- DF_SIZE
+ SF_SIZE
))
1071 #define REP_BIT ((USItype) 1 << (DI_SIZE - DF_SIZE))
1072 if (u
>= ((UDItype
) 1 << DF_SIZE
))
1074 if ((USItype
) u
& (REP_BIT
- 1))
1078 f
= (USItype
) (u
>> WORD_SIZE
);
1079 f
*= HIGH_HALFWORD_COEFF
;
1080 f
*= HIGH_HALFWORD_COEFF
;
1081 f
+= (USItype
) (u
& (HIGH_WORD_COEFF
- 1));
1083 return (SFtype
) (negate
? -f
: f
);
1087 #if defined(L_fixunsxfsi) && LONG_DOUBLE_TYPE_SIZE == 96
1088 /* Reenable the normal types, in case limits.h needs them. */
1104 if (a
>= - (DFtype
) LONG_MIN
)
1105 return (SItype
) (a
+ LONG_MIN
) - LONG_MIN
;
1111 /* Reenable the normal types, in case limits.h needs them. */
1127 if (a
>= - (DFtype
) LONG_MIN
)
1128 return (SItype
) (a
+ LONG_MIN
) - LONG_MIN
;
1134 /* Reenable the normal types, in case limits.h needs them. */
1147 __fixunssfsi (SFtype a
)
1149 if (a
>= - (SFtype
) LONG_MIN
)
1150 return (SItype
) (a
+ LONG_MIN
) - LONG_MIN
;
1155 /* From here on down, the routines use normal data types. */
1157 #define SItype bogus_type
1158 #define USItype bogus_type
1159 #define DItype bogus_type
1160 #define UDItype bogus_type
1161 #define SFtype bogus_type
1162 #define DFtype bogus_type
1174 /* Like bcmp except the sign is meaningful.
1175 Result is negative if S1 is less than S2,
1176 positive if S1 is greater, 0 if S1 and S2 are equal. */
1179 __gcc_bcmp (s1
, s2
, size
)
1180 unsigned char *s1
, *s2
;
1185 unsigned char c1
= *s1
++, c2
= *s2
++;
1202 #if defined(__svr4__) || defined(__alliant__)
1206 /* The Alliant needs the added underscore. */
1207 asm (".globl __builtin_saveregs");
1208 asm ("__builtin_saveregs:");
1209 asm (".globl ___builtin_saveregs");
1210 asm ("___builtin_saveregs:");
1212 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
1213 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
1214 area and also for a new va_list
1216 /* Save all argument registers in the arg reg save area. The
1217 arg reg save area must have the following layout (according
1229 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
1230 asm (" fst.q %f12,16(%sp)");
1232 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
1233 asm (" st.l %r17,36(%sp)");
1234 asm (" st.l %r18,40(%sp)");
1235 asm (" st.l %r19,44(%sp)");
1236 asm (" st.l %r20,48(%sp)");
1237 asm (" st.l %r21,52(%sp)");
1238 asm (" st.l %r22,56(%sp)");
1239 asm (" st.l %r23,60(%sp)");
1240 asm (" st.l %r24,64(%sp)");
1241 asm (" st.l %r25,68(%sp)");
1242 asm (" st.l %r26,72(%sp)");
1243 asm (" st.l %r27,76(%sp)");
1245 asm (" adds 80,%sp,%r16"); /* compute the address of the new
1246 va_list structure. Put in into
1247 r16 so that it will be returned
1250 /* Initialize all fields of the new va_list structure. This
1251 structure looks like:
1254 unsigned long ireg_used;
1255 unsigned long freg_used;
1261 asm (" st.l %r0, 0(%r16)"); /* nfixed */
1262 asm (" st.l %r0, 4(%r16)"); /* nfloating */
1263 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
1264 asm (" bri %r1"); /* delayed return */
1265 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
1267 #else /* not __svr4__ */
1268 #if defined(__PARAGON__)
1270 * we'll use SVR4-ish varargs but need SVR3.2 assembler syntax,
1271 * and we stand a better chance of hooking into libraries
1272 * compiled by PGI. [andyp@ssd.intel.com]
1276 asm (".globl __builtin_saveregs");
1277 asm ("__builtin_saveregs:");
1278 asm (".globl ___builtin_saveregs");
1279 asm ("___builtin_saveregs:");
1281 asm (" andnot 0x0f,sp,sp"); /* round down to 16-byte boundary */
1282 asm (" adds -96,sp,sp"); /* allocate stack space for reg save
1283 area and also for a new va_list
1285 /* Save all argument registers in the arg reg save area. The
1286 arg reg save area must have the following layout (according
1298 asm (" fst.q f8, 0(sp)");
1299 asm (" fst.q f12,16(sp)");
1300 asm (" st.l r16,32(sp)");
1301 asm (" st.l r17,36(sp)");
1302 asm (" st.l r18,40(sp)");
1303 asm (" st.l r19,44(sp)");
1304 asm (" st.l r20,48(sp)");
1305 asm (" st.l r21,52(sp)");
1306 asm (" st.l r22,56(sp)");
1307 asm (" st.l r23,60(sp)");
1308 asm (" st.l r24,64(sp)");
1309 asm (" st.l r25,68(sp)");
1310 asm (" st.l r26,72(sp)");
1311 asm (" st.l r27,76(sp)");
1313 asm (" adds 80,sp,r16"); /* compute the address of the new
1314 va_list structure. Put in into
1315 r16 so that it will be returned
1318 /* Initialize all fields of the new va_list structure. This
1319 structure looks like:
1322 unsigned long ireg_used;
1323 unsigned long freg_used;
1329 asm (" st.l r0, 0(r16)"); /* nfixed */
1330 asm (" st.l r0, 4(r16)"); /* nfloating */
1331 asm (" st.l sp, 8(r16)"); /* __va_ctl points to __va_struct. */
1332 asm (" bri r1"); /* delayed return */
1333 asm (" st.l r28,12(r16)"); /* pointer to overflow args */
1334 #else /* not __PARAGON__ */
1338 asm (".globl ___builtin_saveregs");
1339 asm ("___builtin_saveregs:");
1340 asm (" mov sp,r30");
1341 asm (" andnot 0x0f,sp,sp");
1342 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
1344 /* Fill in the __va_struct. */
1345 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
1346 asm (" st.l r17, 4(sp)"); /* int fixed[12] */
1347 asm (" st.l r18, 8(sp)");
1348 asm (" st.l r19,12(sp)");
1349 asm (" st.l r20,16(sp)");
1350 asm (" st.l r21,20(sp)");
1351 asm (" st.l r22,24(sp)");
1352 asm (" st.l r23,28(sp)");
1353 asm (" st.l r24,32(sp)");
1354 asm (" st.l r25,36(sp)");
1355 asm (" st.l r26,40(sp)");
1356 asm (" st.l r27,44(sp)");
1358 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
1359 asm (" fst.q f12,64(sp)"); /* int floating[8] */
1361 /* Fill in the __va_ctl. */
1362 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
1363 asm (" st.l r28,84(sp)"); /* pointer to more args */
1364 asm (" st.l r0, 88(sp)"); /* nfixed */
1365 asm (" st.l r0, 92(sp)"); /* nfloating */
1367 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
1369 asm (" mov r30,sp");
1370 /* recover stack and pass address to start
1372 #endif /* not __PARAGON__ */
1373 #endif /* not __svr4__ */
1374 #else /* not __i860__ */
1376 asm (".global __builtin_saveregs");
1377 asm ("__builtin_saveregs:");
1378 asm (".global ___builtin_saveregs");
1379 asm ("___builtin_saveregs:");
1380 #ifdef NEED_PROC_COMMAND
1383 asm ("st %i0,[%fp+68]");
1384 asm ("st %i1,[%fp+72]");
1385 asm ("st %i2,[%fp+76]");
1386 asm ("st %i3,[%fp+80]");
1387 asm ("st %i4,[%fp+84]");
1389 asm ("st %i5,[%fp+88]");
1390 #ifdef NEED_TYPE_COMMAND
1391 asm (".type __builtin_saveregs,#function");
1392 asm (".size __builtin_saveregs,.-__builtin_saveregs");
1394 #else /* not __sparc__ */
1395 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1398 asm (" .ent __builtin_saveregs");
1399 asm (" .globl __builtin_saveregs");
1400 asm ("__builtin_saveregs:");
1401 asm (" sw $4,0($30)");
1402 asm (" sw $5,4($30)");
1403 asm (" sw $6,8($30)");
1404 asm (" sw $7,12($30)");
1406 asm (" .end __builtin_saveregs");
1407 #else /* not __mips__, etc. */
1410 __builtin_saveregs ()
1415 #endif /* not __mips__ */
1416 #endif /* not __sparc__ */
1417 #endif /* not __i860__ */
1421 #ifndef inhibit_libc
1423 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1425 /* This is used by the `assert' macro. */
1427 __eprintf (string
, expression
, line
, filename
)
1429 const char *expression
;
1431 const char *filename
;
1433 fprintf (stderr
, string
, expression
, line
, filename
);
1443 /* Structure emitted by -a */
1447 const char *filename
;
1451 const unsigned long *addresses
;
1453 /* Older GCC's did not emit these fields. */
1455 const char **functions
;
1456 const long *line_nums
;
1457 const char **filenames
;
1461 #ifdef BLOCK_PROFILER_CODE
1464 #ifndef inhibit_libc
1466 /* Simple minded basic block profiling output dumper for
1467 systems that don't provide tcov support. At present,
1468 it requires atexit and stdio. */
1470 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1474 #include "gbl-ctors.h"
1476 static struct bb
*bb_head
;
1478 /* Return the number of digits needed to print a value */
1479 /* __inline__ */ static int num_digits (long value
, int base
)
1481 int minus
= (value
< 0 && base
!= 16);
1482 unsigned long v
= (minus
) ? -value
: value
;
1496 __bb_exit_func (void)
1498 FILE *file
= fopen ("bb.out", "a");
1508 /* This is somewhat type incorrect, but it avoids worrying about
1509 exactly where time.h is included from. It should be ok unless
1510 a void * differs from other pointer formats, or if sizeof (long)
1511 is < sizeof (time_t). It would be nice if we could assume the
1512 use of rationale standards here. */
1514 time ((void *) &time_value
);
1515 fprintf (file
, "Basic block profiling finished on %s\n", ctime ((void *) &time_value
));
1517 /* We check the length field explicitly in order to allow compatibility
1518 with older GCC's which did not provide it. */
1520 for (ptr
= bb_head
; ptr
!= (struct bb
*)0; ptr
= ptr
->next
)
1523 int func_p
= (ptr
->nwords
>= sizeof (struct bb
) && ptr
->nwords
<= 1000);
1524 int line_p
= (func_p
&& ptr
->line_nums
);
1525 int file_p
= (func_p
&& ptr
->filenames
);
1526 long ncounts
= ptr
->ncounts
;
1532 int blk_len
= num_digits (ncounts
, 10);
1537 fprintf (file
, "File %s, %ld basic blocks \n\n",
1538 ptr
->filename
, ncounts
);
1540 /* Get max values for each field. */
1541 for (i
= 0; i
< ncounts
; i
++)
1546 if (cnt_max
< ptr
->counts
[i
])
1547 cnt_max
= ptr
->counts
[i
];
1549 if (addr_max
< ptr
->addresses
[i
])
1550 addr_max
= ptr
->addresses
[i
];
1552 if (line_p
&& line_max
< ptr
->line_nums
[i
])
1553 line_max
= ptr
->line_nums
[i
];
1557 p
= (ptr
->functions
[i
]) ? (ptr
->functions
[i
]) : "<none>";
1565 p
= (ptr
->filenames
[i
]) ? (ptr
->filenames
[i
]) : "<none>";
1572 addr_len
= num_digits (addr_max
, 16);
1573 cnt_len
= num_digits (cnt_max
, 10);
1574 line_len
= num_digits (line_max
, 10);
1576 /* Now print out the basic block information. */
1577 for (i
= 0; i
< ncounts
; i
++)
1580 " Block #%*d: executed %*ld time(s) address= 0x%.*lx",
1582 cnt_len
, ptr
->counts
[i
],
1583 addr_len
, ptr
->addresses
[i
]);
1586 fprintf (file
, " function= %-*s", func_len
,
1587 (ptr
->functions
[i
]) ? ptr
->functions
[i
] : "<none>");
1590 fprintf (file
, " line= %*ld", line_len
, ptr
->line_nums
[i
]);
1593 fprintf (file
, " file= %s",
1594 (ptr
->filenames
[i
]) ? ptr
->filenames
[i
] : "<none>");
1596 fprintf (file
, "\n");
1599 fprintf (file
, "\n");
1603 fprintf (file
, "\n\n");
1609 __bb_init_func (struct bb
*blocks
)
1611 /* User is supposed to check whether the first word is non-0,
1612 but just in case.... */
1614 if (blocks
->zero_word
)
1618 /* Initialize destructor. */
1620 ON_EXIT (__bb_exit_func
, 0);
1623 /* Set up linked list. */
1624 blocks
->zero_word
= 1;
1625 blocks
->next
= bb_head
;
1629 #ifndef MACHINE_STATE_SAVE
1630 #define MACHINE_STATE_SAVE(ID)
1632 #ifndef MACHINE_STATE_RESTORE
1633 #define MACHINE_STATE_RESTORE(ID)
1638 /* Number of buckets in hashtable of basic block addresses. */
1640 #define BB_BUCKETS 311
1642 /* Maximum length of string in file bb.in. */
1644 #define BBINBUFSIZE 500
1646 /* BBINBUFSIZE-1 with double quotes. We could use #BBINBUFSIZE or
1647 "BBINBUFSIZE" but want to avoid trouble with preprocessors. */
1649 #define BBINBUFSIZESTR "499"
1653 struct bb_edge
*next
;
1654 unsigned long src_addr
;
1655 unsigned long dst_addr
;
1656 unsigned long count
;
1661 TRACE_KEEP
= 0, TRACE_ON
= 1, TRACE_OFF
= 2
1666 struct bb_func
*next
;
1669 enum bb_func_mode mode
;
1672 /* This is the connection to the outside world.
1673 The BLOCK_PROFILER macro must set __bb.blocks
1674 and __bb.blockno. */
1677 unsigned long blockno
;
1681 /* Vars to store addrs of source and destination basic blocks
1684 static unsigned long bb_src
= 0;
1685 static unsigned long bb_dst
= 0;
1687 static FILE *bb_tracefile
= (FILE*)0;
1688 static struct bb_edge
**bb_hashbuckets
= (struct bb_edge
**)0;
1689 static struct bb_func
*bb_func_head
= (struct bb_func
*)0;
1690 static unsigned long bb_callcount
= 0;
1691 static int bb_mode
= 0;
1693 static unsigned long *bb_stack
= (unsigned long *)0;
1694 static size_t bb_stacksize
= 0;
1696 static int reported
= 0;
1699 Always : Print execution frequencies of basic blocks
1701 bb_mode & 1 != 0 : Dump trace of basic blocks to file bbtrace[.gz]
1702 bb_mode & 2 != 0 : Print jump frequencies to file bb.out.
1703 bb_mode & 4 != 0 : Cut call instructions from basic block flow.
1704 bb_mode & 8 != 0 : Insert return instructions in basic block flow.
1709 /*#include <sys/types.h>*/
1710 #include <sys/stat.h>
1711 /*#include <malloc.h>*/
1713 /* Commands executed by gopen. */
1715 #define GOPENDECOMPRESS "gzip -cd "
1716 #define GOPENCOMPRESS "gzip -c >"
1718 /* Like fopen but pipes through gzip. mode may only be "r" or "w".
1719 If it does not compile, simply replace gopen by fopen and delete
1720 '.gz' from any first parameter to gopen. */
1733 if (mode
[0] != 'r' && mode
[0] != 'w')
1736 p
= fn
+ strlen (fn
)-1;
1737 use_gzip
= ((p
[-1] == '.' && (p
[0] == 'Z' || p
[0] == 'z')) ||
1738 (p
[-2] == '.' && p
[-1] == 'g' && p
[0] == 'z'));
1745 char *s
= (char*) malloc (sizeof (char) * strlen (fn
)
1746 + sizeof (GOPENDECOMPRESS
));
1747 strcpy (s
, GOPENDECOMPRESS
);
1748 strcpy (s
+ (sizeof (GOPENDECOMPRESS
)-1), fn
);
1749 f
= popen (s
, mode
);
1757 char *s
= (char*) malloc (sizeof (char) * strlen (fn
)
1758 + sizeof (GOPENCOMPRESS
));
1759 strcpy (s
, GOPENCOMPRESS
);
1760 strcpy (s
+ (sizeof (GOPENCOMPRESS
)-1), fn
);
1761 if (!(f
= popen (s
, mode
)))
1762 f
= fopen (s
, mode
);
1769 return fopen (fn
, mode
);
1780 if (!fstat (fileno (f
), &buf
) && S_ISFIFO (buf
.st_mode
))
1788 #endif /* HAVE_POPEN */
1790 /* Called once per program. */
1793 __bb_exit_trace_func ()
1795 FILE *file
= fopen ("bb.out", "a");
1809 gclose (bb_tracefile
);
1811 fclose (bb_tracefile
);
1812 #endif /* HAVE_POPEN */
1815 /* Check functions in `bb.in'. */
1820 const struct bb_func
*p
;
1821 int printed_something
= 0;
1825 /* This is somewhat type incorrect. */
1826 time ((void *) &time_value
);
1828 for (p
= bb_func_head
; p
!= (struct bb_func
*)0; p
= p
->next
)
1830 for (ptr
= bb_head
; ptr
!= (struct bb
*)0; ptr
= ptr
->next
)
1832 if (!ptr
->filename
|| p
->filename
!= (char *)0 && strcmp (p
->filename
, ptr
->filename
))
1834 for (blk
= 0; blk
< ptr
->ncounts
; blk
++)
1836 if (!strcmp (p
->funcname
, ptr
->functions
[blk
]))
1841 if (!printed_something
)
1843 fprintf (file
, "Functions in `bb.in' not executed during basic block profiling on %s\n", ctime ((void *) &time_value
));
1844 printed_something
= 1;
1847 fprintf (file
, "\tFunction %s", p
->funcname
);
1849 fprintf (file
, " of file %s", p
->filename
);
1850 fprintf (file
, "\n" );
1855 if (printed_something
)
1856 fprintf (file
, "\n");
1862 if (!bb_hashbuckets
)
1866 fprintf (stderr
, "Profiler: out of memory\n");
1876 unsigned long addr_max
= 0;
1877 unsigned long cnt_max
= 0;
1881 /* This is somewhat type incorrect, but it avoids worrying about
1882 exactly where time.h is included from. It should be ok unless
1883 a void * differs from other pointer formats, or if sizeof (long)
1884 is < sizeof (time_t). It would be nice if we could assume the
1885 use of rationale standards here. */
1887 time ((void *) &time_value
);
1888 fprintf (file
, "Basic block jump tracing");
1890 switch (bb_mode
& 12)
1893 fprintf (file
, " (with call)");
1897 /* Print nothing. */
1901 fprintf (file
, " (with call & ret)");
1905 fprintf (file
, " (with ret)");
1909 fprintf (file
, " finished on %s\n", ctime ((void *) &time_value
));
1911 for (i
= 0; i
< BB_BUCKETS
; i
++)
1913 struct bb_edge
*bucket
= bb_hashbuckets
[i
];
1914 for ( ; bucket
; bucket
= bucket
->next
)
1916 if (addr_max
< bucket
->src_addr
)
1917 addr_max
= bucket
->src_addr
;
1918 if (addr_max
< bucket
->dst_addr
)
1919 addr_max
= bucket
->dst_addr
;
1920 if (cnt_max
< bucket
->count
)
1921 cnt_max
= bucket
->count
;
1924 addr_len
= num_digits (addr_max
, 16);
1925 cnt_len
= num_digits (cnt_max
, 10);
1927 for ( i
= 0; i
< BB_BUCKETS
; i
++)
1929 struct bb_edge
*bucket
= bb_hashbuckets
[i
];
1930 for ( ; bucket
; bucket
= bucket
->next
)
1932 fprintf (file
, "Jump from block 0x%.*lx to "
1933 "block 0x%.*lx executed %*d time(s)\n",
1934 addr_len
, bucket
->src_addr
,
1935 addr_len
, bucket
->dst_addr
,
1936 cnt_len
, bucket
->count
);
1940 fprintf (file
, "\n");
1948 /* Free allocated memory. */
1953 struct bb_func
*old
= f
;
1956 if (old
->funcname
) free (old
->funcname
);
1957 if (old
->filename
) free (old
->filename
);
1968 for (i
= 0; i
< BB_BUCKETS
; i
++)
1970 struct bb_edge
*old
, *bucket
= bb_hashbuckets
[i
];
1975 bucket
= bucket
->next
;
1979 free (bb_hashbuckets
);
1982 for (b
= bb_head
; b
; b
= b
->next
)
1983 if (b
->flags
) free (b
->flags
);
1986 /* Called once per program. */
1993 char buf
[BBINBUFSIZE
];
1996 enum bb_func_mode m
;
1999 /* Initialize destructor. */
2000 ON_EXIT (__bb_exit_func
, 0);
2003 if (!(file
= fopen ("bb.in", "r")))
2006 while(fscanf (file
, " %" BBINBUFSIZESTR
"s ", buf
) != EOF
)
2018 if (!strcmp (p
, "__bb_trace__"))
2020 else if (!strcmp (p
, "__bb_jumps__"))
2022 else if (!strcmp (p
, "__bb_hidecall__"))
2024 else if (!strcmp (p
, "__bb_showret__"))
2028 struct bb_func
*f
= (struct bb_func
*) malloc (sizeof (struct bb_func
));
2032 f
->next
= bb_func_head
;
2033 if (pos
= strchr (p
, ':'))
2035 if (!(f
->funcname
= (char*) malloc (strlen (pos
+1)+1)))
2037 strcpy (f
->funcname
, pos
+1);
2039 if ((f
->filename
= (char*) malloc (l
+1)))
2041 strncpy (f
->filename
, p
, l
);
2042 f
->filename
[l
] = '\0';
2045 f
->filename
= (char*)0;
2049 if (!(f
->funcname
= (char*) malloc (strlen (p
)+1)))
2051 strcpy (f
->funcname
, p
);
2052 f
->filename
= (char*)0;
2064 bb_tracefile
= gopen ("bbtrace.gz", "w");
2069 bb_tracefile
= fopen ("bbtrace", "w");
2071 #endif /* HAVE_POPEN */
2075 bb_hashbuckets
= (struct bb_edge
**)
2076 malloc (BB_BUCKETS
* sizeof (struct bb_edge
*));
2078 bzero ((char *) bb_hashbuckets
, BB_BUCKETS
);
2084 bb_stack
= (unsigned long *) malloc (bb_stacksize
* sizeof (*bb_stack
));
2088 /* Initialize destructor. */
2089 ON_EXIT (__bb_exit_trace_func
, 0);
2094 /* Called upon entering a basic block. */
2099 struct bb_edge
*bucket
;
2101 MACHINE_STATE_SAVE("1")
2103 if (!bb_callcount
|| (__bb
.blocks
->flags
&& (__bb
.blocks
->flags
[__bb
.blockno
] & TRACE_OFF
)))
2106 bb_dst
= __bb
.blocks
->addresses
[__bb
.blockno
];
2107 __bb
.blocks
->counts
[__bb
.blockno
]++;
2111 fwrite (&bb_dst
, sizeof (unsigned long), 1, bb_tracefile
);
2116 struct bb_edge
**startbucket
, **oldnext
;
2118 oldnext
= startbucket
=
2119 & bb_hashbuckets
[ (((int)bb_src
*8)^(int)bb_dst
) % BB_BUCKETS
];
2120 bucket
= *startbucket
;
2122 for (bucket
= *startbucket
; bucket
;
2123 oldnext
= &(bucket
->next
), bucket
= *oldnext
)
2125 if ( bucket
->src_addr
== bb_src
&&
2126 bucket
->dst_addr
== bb_dst
)
2129 *oldnext
= bucket
->next
;
2130 bucket
->next
= *startbucket
;
2131 *startbucket
= bucket
;
2136 bucket
= (struct bb_edge
*) malloc (sizeof (struct bb_edge
));
2142 fprintf (stderr
, "Profiler: out of memory\n");
2149 bucket
->src_addr
= bb_src
;
2150 bucket
->dst_addr
= bb_dst
;
2151 bucket
->next
= *startbucket
;
2152 *startbucket
= bucket
;
2163 MACHINE_STATE_RESTORE("1")
2167 /* Called when returning from a function and `__bb_showret__' is set. */
2170 __bb_trace_func_ret ()
2172 struct bb_edge
*bucket
;
2174 if (!bb_callcount
|| (__bb
.blocks
->flags
&& (__bb
.blocks
->flags
[__bb
.blockno
] & TRACE_OFF
)))
2179 struct bb_edge
**startbucket
, **oldnext
;
2181 oldnext
= startbucket
=
2182 & bb_hashbuckets
[ (((int)bb_dst
*8)^(int)bb_src
) % BB_BUCKETS
];
2183 bucket
= *startbucket
;
2185 for (bucket
= *startbucket
; bucket
;
2186 oldnext
= &(bucket
->next
), bucket
= *oldnext
)
2188 if ( bucket
->src_addr
== bb_dst
&&
2189 bucket
->dst_addr
== bb_src
)
2192 *oldnext
= bucket
->next
;
2193 bucket
->next
= *startbucket
;
2194 *startbucket
= bucket
;
2199 bucket
= (struct bb_edge
*) malloc (sizeof (struct bb_edge
));
2205 fprintf (stderr
, "Profiler: out of memory\n");
2212 bucket
->src_addr
= bb_dst
;
2213 bucket
->dst_addr
= bb_src
;
2214 bucket
->next
= *startbucket
;
2215 *startbucket
= bucket
;
2228 /* Called upon entering the first function of a file. */
2231 __bb_init_file (blocks
)
2235 const struct bb_func
*p
;
2236 long blk
, ncounts
= blocks
->ncounts
;
2237 const char **functions
= blocks
->functions
;
2239 /* Set up linked list. */
2240 blocks
->zero_word
= 1;
2241 blocks
->next
= bb_head
;
2245 if (!bb_func_head
||
2246 !(blocks
->flags
= (char*) malloc (sizeof (char) * blocks
->ncounts
)))
2249 for (blk
= 0; blk
< ncounts
; blk
++)
2250 blocks
->flags
[blk
] = 0;
2252 for (blk
= 0; blk
< ncounts
; blk
++)
2254 for (p
= bb_func_head
; p
; p
= p
->next
)
2256 if (!strcmp (p
->funcname
, functions
[blk
]) &&
2257 (!p
->filename
|| !strcmp (p
->filename
, blocks
->filename
)))
2259 blocks
->flags
[blk
] |= p
->mode
;
2266 /* Called when exiting from a function. */
2272 MACHINE_STATE_SAVE("2")
2276 if ((bb_mode
& 12) && bb_stacksize
> bb_callcount
)
2278 bb_src
= bb_stack
[bb_callcount
];
2280 __bb_trace_func_ret ();
2286 MACHINE_STATE_RESTORE("2")
2290 /* Called when entering a function. */
2293 __bb_init_trace_func (blocks
, blockno
)
2295 unsigned long blockno
;
2297 static int trace_init
= 0;
2299 MACHINE_STATE_SAVE("3")
2301 if (!blocks
->zero_word
)
2308 __bb_init_file (blocks
);
2318 if (bb_callcount
>= bb_stacksize
)
2320 size_t newsize
= bb_callcount
+ 100;
2322 bb_stack
= (unsigned long *) realloc (bb_stack
, newsize
);
2327 fprintf (stderr
, "Profiler: out of memory\n");
2331 goto stack_overflow
;
2333 bb_stacksize
= newsize
;
2335 bb_stack
[bb_callcount
] = bb_src
;
2346 else if (blocks
->flags
&& (blocks
->flags
[blockno
] & TRACE_ON
))
2352 bb_stack
[bb_callcount
] = bb_src
;
2355 MACHINE_STATE_RESTORE("3")
2358 #endif /* not inhibit_libc */
2359 #endif /* not BLOCK_PROFILER_CODE */
2362 /* Default free-store management functions for C++, per sections 12.5 and
2363 17.3.3 of the Working Paper. */
2366 /* operator new (size_t), described in 17.3.3.5. This function is used by
2367 C++ programs to allocate a block of memory to hold a single object. */
2369 typedef void (*vfp
)(void);
2370 extern vfp __new_handler
;
2371 extern void __default_new_handler (void);
2374 void * __builtin_new (size_t sz
)
2375 __attribute__ ((weak
, alias ("___builtin_new")));
2377 ___builtin_new (size_t sz
)
2380 __builtin_new (size_t sz
)
2384 vfp handler
= (__new_handler
) ? __new_handler
: __default_new_handler
;
2386 /* malloc (0) is unpredictable; avoid it. */
2389 p
= (void *) malloc (sz
);
2393 p
= (void *) malloc (sz
);
2398 #endif /* L_op_new */
2401 /* void * operator new [] (size_t), described in 17.3.3.6. This function
2402 is used by C++ programs to allocate a block of memory for an array. */
2404 extern void * __builtin_new (size_t);
2407 void * __builtin_vec_new (size_t sz
)
2408 __attribute__ ((weak
, alias ("___builtin_vec_new")));
2410 ___builtin_vec_new (size_t sz
)
2413 __builtin_vec_new (size_t sz
)
2416 return __builtin_new (sz
);
2418 #endif /* L_op_vnew */
2420 #ifdef L_new_handler
2421 /* set_new_handler (fvoid_t *) and the default new handler, described in
2422 17.3.3.2 and 17.3.3.5. These functions define the result of a failure
2423 to allocate the amount of memory requested from operator new or new []. */
2425 #ifndef inhibit_libc
2426 /* This gets us __GNU_LIBRARY__. */
2427 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2430 #ifdef __GNU_LIBRARY__
2431 /* Avoid forcing the library's meaning of `write' on the user program
2432 by using the "internal" name (for use within the library) */
2433 #define write(fd, buf, n) __write((fd), (buf), (n))
2435 #endif /* inhibit_libc */
2437 typedef void (*vfp
)(void);
2438 void __default_new_handler (void);
2440 vfp __new_handler
= (vfp
)0;
2443 set_new_handler (vfp handler
)
2447 prev_handler
= __new_handler
;
2448 if (handler
== 0) handler
= __default_new_handler
;
2449 __new_handler
= handler
;
2450 return prev_handler
;
2453 #define MESSAGE "Virtual memory exceeded in `new'\n"
2456 __default_new_handler ()
2458 #ifndef inhibit_libc
2459 /* don't use fprintf (stderr, ...) because it may need to call malloc. */
2460 /* This should really print the name of the program, but that is hard to
2461 do. We need a standard, clean way to get at the name. */
2462 write (2, MESSAGE
, sizeof (MESSAGE
));
2464 /* don't call exit () because that may call global destructors which
2465 may cause a loop. */
2471 /* operator delete (void *), described in 17.3.3.3. This function is used
2472 by C++ programs to return to the free store a block of memory allocated
2473 as a single object. */
2476 void __builtin_delete (void *ptr
)
2477 __attribute__ ((weak
, alias ("___builtin_delete")));
2479 ___builtin_delete (void *ptr
)
2482 __builtin_delete (void *ptr
)
2491 /* operator delete [] (void *), described in 17.3.3.4. This function is
2492 used by C++ programs to return to the free store a block of memory
2493 allocated as an array. */
2495 extern void __builtin_delete (void *);
2498 void __builtin_vec_delete (void *ptr
)
2499 __attribute__ ((weak
, alias ("___builtin_vec_delete")));
2501 ___builtin_vec_delete (void *ptr
)
2504 __builtin_vec_delete (void *ptr
)
2507 __builtin_delete (ptr
);
2511 /* End of C++ free-store management functions */
2514 unsigned int __shtab
[] = {
2515 0x00000001, 0x00000002, 0x00000004, 0x00000008,
2516 0x00000010, 0x00000020, 0x00000040, 0x00000080,
2517 0x00000100, 0x00000200, 0x00000400, 0x00000800,
2518 0x00001000, 0x00002000, 0x00004000, 0x00008000,
2519 0x00010000, 0x00020000, 0x00040000, 0x00080000,
2520 0x00100000, 0x00200000, 0x00400000, 0x00800000,
2521 0x01000000, 0x02000000, 0x04000000, 0x08000000,
2522 0x10000000, 0x20000000, 0x40000000, 0x80000000
2526 #ifdef L_clear_cache
2527 /* Clear part of an instruction cache. */
2529 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
2532 __clear_cache (beg
, end
)
2535 #ifdef CLEAR_INSN_CACHE
2536 CLEAR_INSN_CACHE (beg
, end
);
2538 #ifdef INSN_CACHE_SIZE
2539 static char array
[INSN_CACHE_SIZE
+ INSN_CACHE_PLANE_SIZE
+ INSN_CACHE_LINE_WIDTH
];
2540 static int initialized
;
2544 typedef (*function_ptr
) ();
2546 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
2547 /* It's cheaper to clear the whole cache.
2548 Put in a series of jump instructions so that calling the beginning
2549 of the cache will clear the whole thing. */
2553 int ptr
= (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
2554 & -INSN_CACHE_LINE_WIDTH
);
2555 int end_ptr
= ptr
+ INSN_CACHE_SIZE
;
2557 while (ptr
< end_ptr
)
2559 *(INSTRUCTION_TYPE
*)ptr
2560 = JUMP_AHEAD_INSTRUCTION
+ INSN_CACHE_LINE_WIDTH
;
2561 ptr
+= INSN_CACHE_LINE_WIDTH
;
2563 *(INSTRUCTION_TYPE
*)(ptr
- INSN_CACHE_LINE_WIDTH
) = RETURN_INSTRUCTION
;
2568 /* Call the beginning of the sequence. */
2569 (((function_ptr
) (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
2570 & -INSN_CACHE_LINE_WIDTH
))
2573 #else /* Cache is large. */
2577 int ptr
= (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
2578 & -INSN_CACHE_LINE_WIDTH
);
2580 while (ptr
< (int) array
+ sizeof array
)
2582 *(INSTRUCTION_TYPE
*)ptr
= RETURN_INSTRUCTION
;
2583 ptr
+= INSN_CACHE_LINE_WIDTH
;
2589 /* Find the location in array that occupies the same cache line as BEG. */
2591 offset
= ((int) beg
& -INSN_CACHE_LINE_WIDTH
) & (INSN_CACHE_PLANE_SIZE
- 1);
2592 start_addr
= (((int) (array
+ INSN_CACHE_PLANE_SIZE
- 1)
2593 & -INSN_CACHE_PLANE_SIZE
)
2596 /* Compute the cache alignment of the place to stop clearing. */
2597 #if 0 /* This is not needed for gcc's purposes. */
2598 /* If the block to clear is bigger than a cache plane,
2599 we clear the entire cache, and OFFSET is already correct. */
2600 if (end
< beg
+ INSN_CACHE_PLANE_SIZE
)
2602 offset
= (((int) (end
+ INSN_CACHE_LINE_WIDTH
- 1)
2603 & -INSN_CACHE_LINE_WIDTH
)
2604 & (INSN_CACHE_PLANE_SIZE
- 1));
2606 #if INSN_CACHE_DEPTH > 1
2607 end_addr
= (start_addr
& -INSN_CACHE_PLANE_SIZE
) + offset
;
2608 if (end_addr
<= start_addr
)
2609 end_addr
+= INSN_CACHE_PLANE_SIZE
;
2611 for (plane
= 0; plane
< INSN_CACHE_DEPTH
; plane
++)
2613 int addr
= start_addr
+ plane
* INSN_CACHE_PLANE_SIZE
;
2614 int stop
= end_addr
+ plane
* INSN_CACHE_PLANE_SIZE
;
2616 while (addr
!= stop
)
2618 /* Call the return instruction at ADDR. */
2619 ((function_ptr
) addr
) ();
2621 addr
+= INSN_CACHE_LINE_WIDTH
;
2624 #else /* just one plane */
2627 /* Call the return instruction at START_ADDR. */
2628 ((function_ptr
) start_addr
) ();
2630 start_addr
+= INSN_CACHE_LINE_WIDTH
;
2632 while ((start_addr
% INSN_CACHE_SIZE
) != offset
);
2633 #endif /* just one plane */
2634 #endif /* Cache is large */
2635 #endif /* Cache exists */
2636 #endif /* CLEAR_INSN_CACHE */
2639 #endif /* L_clear_cache */
2643 /* Jump to a trampoline, loading the static chain address. */
2656 int mprotect(addr
, len
, prot
)
2662 if (prot
== 7) np
= 0x40;
2663 else if (prot
== 5) np
= 0x20;
2664 else if (prot
== 4) np
= 0x10;
2665 else if (prot
== 3) np
= 0x04;
2666 else if (prot
== 1) np
= 0x02;
2667 else if (prot
== 0) np
= 0x01;
2669 if (VirtualProtect (addr
, len
, np
, &op
))
2678 #ifdef TRANSFER_FROM_TRAMPOLINE
2679 TRANSFER_FROM_TRAMPOLINE
2682 #if defined (NeXT) && defined (__MACH__)
2684 /* Make stack executable so we can call trampolines on stack.
2685 This is called from INITIALIZE_TRAMPOLINE in next.h. */
2689 #include <mach/mach.h>
2693 __enable_execute_stack (addr
)
2697 char *eaddr
= addr
+ TRAMPOLINE_SIZE
;
2698 vm_address_t a
= (vm_address_t
) addr
;
2700 /* turn on execute access on stack */
2701 r
= vm_protect (task_self (), a
, TRAMPOLINE_SIZE
, FALSE
, VM_PROT_ALL
);
2702 if (r
!= KERN_SUCCESS
)
2704 mach_error("vm_protect VM_PROT_ALL", r
);
2708 /* We inline the i-cache invalidation for speed */
2710 #ifdef CLEAR_INSN_CACHE
2711 CLEAR_INSN_CACHE (addr
, eaddr
);
2713 __clear_cache ((int) addr
, (int) eaddr
);
2717 #endif /* defined (NeXT) && defined (__MACH__) */
2721 /* Make stack executable so we can call trampolines on stack.
2722 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
2724 #include <sys/mman.h>
2725 #include <sys/vmparam.h>
2726 #include <machine/machparam.h>
2729 __enable_execute_stack ()
2732 static unsigned lowest
= USRSTACK
;
2733 unsigned current
= (unsigned) &fp
& -NBPG
;
2735 if (lowest
> current
)
2737 unsigned len
= lowest
- current
;
2738 mremap (current
, &len
, PROT_READ
| PROT_WRITE
| PROT_EXEC
, MAP_PRIVATE
);
2742 /* Clear instruction cache in case an old trampoline is in it. */
2745 #endif /* __convex__ */
2749 /* Modified from the convex -code above. */
2751 #include <sys/param.h>
2753 #include <sys/m88kbcs.h>
2756 __enable_execute_stack ()
2759 static unsigned long lowest
= USRSTACK
;
2760 unsigned long current
= (unsigned long) &save_errno
& -NBPC
;
2762 /* Ignore errno being set. memctl sets errno to EINVAL whenever the
2763 address is seen as 'negative'. That is the case with the stack. */
2766 if (lowest
> current
)
2768 unsigned len
=lowest
-current
;
2769 memctl(current
,len
,MCT_TEXT
);
2773 memctl(current
,NBPC
,MCT_TEXT
);
2777 #endif /* __DOLPHIN__ */
2781 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2783 #include <sys/mman.h>
2784 #include <sys/types.h>
2785 #include <sys/param.h>
2786 #include <sys/vmmac.h>
2788 /* Modified from the convex -code above.
2789 mremap promises to clear the i-cache. */
2792 __enable_execute_stack ()
2795 if (mprotect (((unsigned int)&fp
/PAGSIZ
)*PAGSIZ
, PAGSIZ
,
2796 PROT_READ
|PROT_WRITE
|PROT_EXEC
))
2798 perror ("mprotect in __enable_execute_stack");
2803 #endif /* __pyr__ */
2804 #endif /* L_trampoline */
2808 #include "gbl-ctors.h"
2809 /* Some systems use __main in a way incompatible with its use in gcc, in these
2810 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2811 give the same symbol without quotes for an alternative entry point. You
2812 must define both, or neither. */
2814 #define NAME__MAIN "__main"
2815 #define SYMBOL__MAIN __main
2818 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2819 /* Run all the global destructors on exit from the program. */
2822 __do_global_dtors ()
2824 #ifdef DO_GLOBAL_DTORS_BODY
2825 DO_GLOBAL_DTORS_BODY
;
2828 for (p
= __DTOR_LIST__
+ 1; *p
; )
2834 #ifndef INIT_SECTION_ASM_OP
2835 /* Run all the global constructors on entry to the program. */
2838 #define ON_EXIT(a, b)
2840 /* Make sure the exit routine is pulled in to define the globals as
2841 bss symbols, just in case the linker does not automatically pull
2842 bss definitions from the library. */
2844 extern int _exit_dummy_decl
;
2845 int *_exit_dummy_ref
= &_exit_dummy_decl
;
2846 #endif /* ON_EXIT */
2849 __do_global_ctors ()
2851 DO_GLOBAL_CTORS_BODY
;
2852 ON_EXIT (__do_global_dtors
, 0);
2854 #endif /* no INIT_SECTION_ASM_OP */
2856 #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
2857 /* Subroutine called automatically by `main'.
2858 Compiling a global function named `main'
2859 produces an automatic call to this function at the beginning.
2861 For many systems, this routine calls __do_global_ctors.
2862 For systems which support a .init section we use the .init section
2863 to run __do_global_ctors, so we need not do anything here. */
2868 /* Support recursive calls to `main': run initializers just once. */
2869 static int initialized
;
2873 __do_global_ctors ();
2876 #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
2878 #endif /* L__main */
2882 #include "gbl-ctors.h"
2884 /* Provide default definitions for the lists of constructors and
2885 destructors, so that we don't get linker errors. These symbols are
2886 intentionally bss symbols, so that gld and/or collect will provide
2887 the right values. */
2889 /* We declare the lists here with two elements each,
2890 so that they are valid empty lists if no other definition is loaded. */
2891 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
2892 #if defined(__NeXT__) || defined(_AIX)
2893 /* After 2.3, try this definition on all systems. */
2894 func_ptr __CTOR_LIST__
[2] = {0, 0};
2895 func_ptr __DTOR_LIST__
[2] = {0, 0};
2897 func_ptr __CTOR_LIST__
[2];
2898 func_ptr __DTOR_LIST__
[2];
2900 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
2901 #endif /* L_ctors */
2905 #include "gbl-ctors.h"
2911 int _exit_dummy_decl
= 0; /* prevent compiler & linker warnings */
2919 extern void *malloc ();
2920 extern void *realloc ();
2922 static func_ptr
*atexit_chain
= NULL
;
2923 static long atexit_chain_length
= 0;
2924 static volatile long last_atexit_chain_slot
= -1;
2926 int atexit (func_ptr func
)
2928 if (++last_atexit_chain_slot
== atexit_chain_length
)
2930 atexit_chain_length
+= 32;
2932 atexit_chain
= realloc (atexit_chain
,
2933 atexit_chain_length
* sizeof (func_ptr
));
2935 atexit_chain
= malloc (atexit_chain_length
* sizeof (func_ptr
));
2938 atexit_chain_length
= 0;
2939 last_atexit_chain_slot
= -1;
2944 atexit_chain
[last_atexit_chain_slot
] = func
;
2947 #endif /* NEED_ATEXIT */
2949 /* If we have no known way of registering our own __do_global_dtors
2950 routine so that it will be invoked at program exit time, then we
2951 have to define our own exit routine which will get this to happen. */
2953 extern void __do_global_dtors ();
2954 extern void _cleanup ();
2955 extern void _exit () __attribute__ ((noreturn
));
2961 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2965 for ( ; last_atexit_chain_slot
-- >= 0; )
2967 (*atexit_chain
[last_atexit_chain_slot
+ 1]) ();
2968 atexit_chain
[last_atexit_chain_slot
+ 1] = NULL
;
2970 free (atexit_chain
);
2971 atexit_chain
= NULL
;
2973 #else /* No NEED_ATEXIT */
2974 __do_global_dtors ();
2975 #endif /* No NEED_ATEXIT */
2986 int _exit_dummy_decl
= 0; /* prevent compiler & linker warnings */
2995 void *exception_handler
;
2998 struct exception_table_node
{
2999 exception_table
*table
;
3002 struct exception_table_node
*next
;
3005 static int except_table_pos
;
3006 static void *except_pc
;
3007 static struct exception_table_node
*exception_table_list
;
3009 static exception_table
*
3010 find_exception_table (pc
)
3013 register struct exception_table_node
*table
= exception_table_list
;
3014 for ( ; table
!= 0; table
= table
->next
)
3016 if (table
->start
<= pc
&& table
->end
> pc
)
3017 return table
->table
;
3022 /* this routine takes a pc, and the address of the exception handler associated
3023 with the closest exception table handler entry associated with that PC,
3024 or 0 if there are no table entries the PC fits in. The algorithm works
3025 something like this:
3027 while(current_entry exists) {
3028 if(current_entry.start < pc )
3029 current_entry = next_entry;
3031 if(prev_entry.start <= pc && prev_entry.end > pc) {
3032 save pointer to prev_entry;
3033 return prev_entry.exception_handler;
3040 Assuming a correctly sorted table (ascending order) this routine should
3041 return the tightest match...
3043 In the advent of a tie, we have to give the last entry, as it represents
3049 __find_first_exception_table_match(pc
)
3052 exception_table
*table
= find_exception_table (pc
);
3058 printf("find_first_exception_table_match(): pc = %x!\n",pc
);
3064 /* We can't do this yet, as we don't know that the table is sorted. */
3067 if (table
[pos
].start
> except_pc
)
3068 /* found the first table[pos].start > except_pc, so the previous
3069 entry better be the one we want! */
3071 } while(table
[pos
].exception_handler
!= (void*)-1);
3074 if (table
[pos
].start
<= except_pc
&& table
[pos
].end
> except_pc
)
3076 except_table_pos
= pos
;
3078 printf("find_first_eh_table_match(): found match: %x\n",table
[pos
].exception_handler
);
3080 return table
[pos
].exception_handler
;
3083 while (table
[++pos
].exception_handler
!= (void*)-1) {
3084 if (table
[pos
].start
<= except_pc
&& table
[pos
].end
> except_pc
)
3086 /* This can apply. Make sure it is better or as good as the previous
3088 /* The best one ends first. */
3089 if (best
== 0 || (table
[pos
].end
<= table
[best
].end
3090 /* The best one starts last. */
3091 && table
[pos
].start
>= table
[best
].start
))
3096 return table
[best
].exception_handler
;
3100 printf("find_first_eh_table_match(): else: returning NULL!\n");
3106 __throw_type_match (void *catch_type
, void *throw_type
, void* obj
)
3109 printf("__throw_type_match (): catch_type = %s, throw_type = %s\n",
3110 catch_type
, throw_type
);
3112 if (strcmp ((const char *)catch_type
, (const char *)throw_type
) == 0)
3118 __register_exceptions (exception_table
*table
)
3120 struct exception_table_node
*node
;
3121 exception_table
*range
= table
+ 1;
3123 if (range
->start
== (void*)-1)
3126 node
= (struct exception_table_node
*)
3127 malloc (sizeof (struct exception_table_node
));
3128 node
->table
= table
;
3130 /* This look can be optimized away either if the table
3131 is sorted, or if we pass in extra parameters. */
3132 node
->start
= range
->start
;
3133 node
->end
= range
->end
;
3134 for (range
++ ; range
->start
!= (void*)(-1); range
++)
3136 if (range
->start
< node
->start
)
3137 node
->start
= range
->start
;
3138 if (range
->end
> node
->end
)
3139 node
->end
= range
->end
;
3142 node
->next
= exception_table_list
;
3143 exception_table_list
= node
;
3153 __unwind_function(void *ptr
)
3155 asm("movl 8(%esp),%ecx");
3156 /* Undo current frame */
3157 asm("movl %ebp,%esp");
3159 /* like ret, but stay here */
3160 asm("addl $4,%esp");
3162 /* Now, undo previous frame. */
3163 /* This is a test routine, as we have to dynamically probe to find out
3164 what to pop for certain, this is just a guess. */
3165 asm("leal -16(%ebp),%esp");
3169 asm("movl %ebp,%esp");
3172 asm("movl %ecx,0(%esp)");
3175 #elif #machine(rs6000) && !defined _ARCH_PPC
3176 __unwind_function(void *ptr
)
3185 /* use 31 as a scratch register to restore the link register. */
3186 asm("l 31, 8(1);mtlr 31 # l lr,8(1)");
3189 asm("mtctr 3;bctr # b 3");
3191 #elif (#machine(rs6000) || #machine(powerpc)) && defined _ARCH_PPC
3192 __unwind_function(void *ptr
)
3196 asm("lwz 31,-4(1)");
3201 /* use 31 as a scratch register to restore the link register. */
3202 asm("lwz 31, 8(1);mtlr 31 # l lr,8(1)");
3203 asm("lwz 31,-4(1)");
3205 asm("mtctr 3;bctr # b 3");
3208 __unwind_function(void *ptr
)
3210 __label__ return_again
;
3212 /* Replace our frame's return address with the label below.
3213 During execution, we will first return here instead of to
3214 caller, then second return takes caller's frame off the stack.
3215 Two returns matches two actual calls, so is less likely to
3216 confuse debuggers. `16' corresponds to RETURN_ADDRESS_OFFSET. */
3217 __asm ("movl %0,16(fp)" : : "p" (&& return_again
));
3224 __unwind_function(void *ptr
)
3228 #endif /* powerpc */
3232 #ifndef inhibit_libc
3233 /* This gets us __GNU_LIBRARY__. */
3234 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
3237 #ifdef __GNU_LIBRARY__
3238 /* Avoid forcing the library's meaning of `write' on the user program
3239 by using the "internal" name (for use within the library) */
3240 #define write(fd, buf, n) __write((fd), (buf), (n))
3242 #endif /* inhibit_libc */
3244 #define MESSAGE "pure virtual method called\n"
3249 #ifndef inhibit_libc
3250 write (2, MESSAGE
, sizeof (MESSAGE
) - 1);