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, 96, 1997 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) || defined (ASM_OUTPUT_WEAK_ALIAS))
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)
149 w
.s
.high
= -uu
.s
.high
- ((USItype
) w
.s
.low
> 0);
155 /* Unless shift functions are defined whith full ANSI prototypes,
156 parameter b will be promoted to int if word_type is smaller than an int. */
159 __lshrdi3 (DItype u
, word_type b
)
170 bm
= (sizeof (SItype
) * BITS_PER_UNIT
) - b
;
174 w
.s
.low
= (USItype
)uu
.s
.high
>> -bm
;
178 USItype carries
= (USItype
)uu
.s
.high
<< bm
;
179 w
.s
.high
= (USItype
)uu
.s
.high
>> b
;
180 w
.s
.low
= ((USItype
)uu
.s
.low
>> b
) | carries
;
189 __ashldi3 (DItype u
, word_type b
)
200 bm
= (sizeof (SItype
) * BITS_PER_UNIT
) - b
;
204 w
.s
.high
= (USItype
)uu
.s
.low
<< -bm
;
208 USItype carries
= (USItype
)uu
.s
.low
>> bm
;
209 w
.s
.low
= (USItype
)uu
.s
.low
<< b
;
210 w
.s
.high
= ((USItype
)uu
.s
.high
<< b
) | carries
;
219 __ashrdi3 (DItype u
, word_type b
)
230 bm
= (sizeof (SItype
) * BITS_PER_UNIT
) - b
;
233 /* w.s.high = 1..1 or 0..0 */
234 w
.s
.high
= uu
.s
.high
>> (sizeof (SItype
) * BITS_PER_UNIT
- 1);
235 w
.s
.low
= uu
.s
.high
>> -bm
;
239 USItype carries
= (USItype
)uu
.s
.high
<< bm
;
240 w
.s
.high
= uu
.s
.high
>> b
;
241 w
.s
.low
= ((USItype
)uu
.s
.low
>> b
) | carries
;
255 w
.s
.low
= ffs (uu
.s
.low
);
258 w
.s
.low
= ffs (uu
.s
.high
);
261 w
.s
.low
+= BITS_PER_UNIT
* sizeof (SItype
);
270 __muldi3 (DItype u
, DItype v
)
278 w
.ll
= __umulsidi3 (uu
.s
.low
, vv
.s
.low
);
279 w
.s
.high
+= ((USItype
) uu
.s
.low
* (USItype
) vv
.s
.high
280 + (USItype
) uu
.s
.high
* (USItype
) vv
.s
.low
);
287 #if defined (sdiv_qrnnd)
289 __udiv_w_sdiv (USItype
*rp
, USItype a1
, USItype a0
, USItype d
)
296 if (a1
< d
- a1
- (a0
>> (SI_TYPE_SIZE
- 1)))
298 /* dividend, divisor, and quotient are nonnegative */
299 sdiv_qrnnd (q
, r
, a1
, a0
, d
);
303 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
304 sub_ddmmss (c1
, c0
, a1
, a0
, d
>> 1, d
<< (SI_TYPE_SIZE
- 1));
305 /* Divide (c1*2^32 + c0) by d */
306 sdiv_qrnnd (q
, r
, c1
, c0
, d
);
307 /* Add 2^31 to quotient */
308 q
+= (USItype
) 1 << (SI_TYPE_SIZE
- 1);
313 b1
= d
>> 1; /* d/2, between 2^30 and 2^31 - 1 */
314 c1
= a1
>> 1; /* A/2 */
315 c0
= (a1
<< (SI_TYPE_SIZE
- 1)) + (a0
>> 1);
317 if (a1
< b1
) /* A < 2^32*b1, so A/2 < 2^31*b1 */
319 sdiv_qrnnd (q
, r
, c1
, c0
, b1
); /* (A/2) / (d/2) */
321 r
= 2*r
+ (a0
& 1); /* Remainder from A/(2*b1) */
338 else if (c1
< b1
) /* So 2^31 <= (A/2)/b1 < 2^32 */
341 c0
= ~c0
; /* logical NOT */
343 sdiv_qrnnd (q
, r
, c1
, c0
, b1
); /* (A/2) / (d/2) */
345 q
= ~q
; /* (A/2)/b1 */
348 r
= 2*r
+ (a0
& 1); /* A/(2*b1) */
366 else /* Implies c1 = b1 */
367 { /* Hence a1 = d - 1 = 2*b1 - 1 */
385 /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */
387 __udiv_w_sdiv (USItype
*rp
, USItype a1
, USItype a0
, USItype d
)
392 #if (defined (L_udivdi3) || defined (L_divdi3) || \
393 defined (L_umoddi3) || defined (L_moddi3))
398 static const UQItype __clz_tab
[] =
400 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,
401 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,
402 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,
403 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,
404 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,
405 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,
406 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,
407 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,
410 #if (defined (L_udivdi3) || defined (L_divdi3) || \
411 defined (L_umoddi3) || defined (L_moddi3))
415 __udivmoddi4 (UDItype n
, UDItype d
, UDItype
*rp
)
420 USItype d0
, d1
, n0
, n1
, n2
;
432 #if !UDIV_NEEDS_NORMALIZATION
439 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
442 /* Remainder in n0. */
449 d0
= 1 / d0
; /* Divide intentionally by zero. */
451 udiv_qrnnd (q1
, n1
, 0, n1
, d0
);
452 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
454 /* Remainder in n0. */
465 #else /* UDIV_NEEDS_NORMALIZATION */
473 count_leading_zeros (bm
, d0
);
477 /* Normalize, i.e. make the most significant bit of the
481 n1
= (n1
<< bm
) | (n0
>> (SI_TYPE_SIZE
- bm
));
485 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
488 /* Remainder in n0 >> bm. */
495 d0
= 1 / d0
; /* Divide intentionally by zero. */
497 count_leading_zeros (bm
, d0
);
501 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
502 conclude (the most significant bit of n1 is set) /\ (the
503 leading quotient digit q1 = 1).
505 This special case is necessary, not an optimization.
506 (Shifts counts of SI_TYPE_SIZE are undefined.) */
515 b
= SI_TYPE_SIZE
- bm
;
519 n1
= (n1
<< bm
) | (n0
>> b
);
522 udiv_qrnnd (q1
, n1
, n2
, n1
, d0
);
527 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
529 /* Remainder in n0 >> bm. */
539 #endif /* UDIV_NEEDS_NORMALIZATION */
550 /* Remainder in n1n0. */
562 count_leading_zeros (bm
, d1
);
565 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
566 conclude (the most significant bit of n1 is set) /\ (the
567 quotient digit q0 = 0 or 1).
569 This special case is necessary, not an optimization. */
571 /* The condition on the next line takes advantage of that
572 n1 >= d1 (true due to program flow). */
573 if (n1
> d1
|| n0
>= d0
)
576 sub_ddmmss (n1
, n0
, n1
, n0
, d1
, d0
);
595 b
= SI_TYPE_SIZE
- bm
;
597 d1
= (d1
<< bm
) | (d0
>> b
);
600 n1
= (n1
<< bm
) | (n0
>> b
);
603 udiv_qrnnd (q0
, n1
, n2
, n1
, d1
);
604 umul_ppmm (m1
, m0
, q0
, d0
);
606 if (m1
> n1
|| (m1
== n1
&& m0
> n0
))
609 sub_ddmmss (m1
, m0
, m1
, m0
, d1
, d0
);
614 /* Remainder in (n1n0 - m1m0) >> bm. */
617 sub_ddmmss (n1
, n0
, n1
, n0
, m1
, m0
);
618 rr
.s
.low
= (n1
<< b
) | (n0
>> bm
);
619 rr
.s
.high
= n1
>> bm
;
633 UDItype
__udivmoddi4 ();
636 __divdi3 (DItype u
, DItype v
)
647 uu
.ll
= __negdi2 (uu
.ll
);
650 vv
.ll
= __negdi2 (vv
.ll
);
652 w
= __udivmoddi4 (uu
.ll
, vv
.ll
, (UDItype
*) 0);
661 UDItype
__udivmoddi4 ();
663 __moddi3 (DItype u
, DItype v
)
674 uu
.ll
= __negdi2 (uu
.ll
);
676 vv
.ll
= __negdi2 (vv
.ll
);
678 (void) __udivmoddi4 (uu
.ll
, vv
.ll
, &w
);
687 UDItype
__udivmoddi4 ();
689 __umoddi3 (UDItype u
, UDItype v
)
693 (void) __udivmoddi4 (u
, v
, &w
);
700 UDItype
__udivmoddi4 ();
702 __udivdi3 (UDItype n
, UDItype d
)
704 return __udivmoddi4 (n
, d
, (UDItype
*) 0);
710 __cmpdi2 (DItype a
, DItype b
)
714 au
.ll
= a
, bu
.ll
= b
;
716 if (au
.s
.high
< bu
.s
.high
)
718 else if (au
.s
.high
> bu
.s
.high
)
720 if ((USItype
) au
.s
.low
< (USItype
) bu
.s
.low
)
722 else if ((USItype
) au
.s
.low
> (USItype
) bu
.s
.low
)
730 __ucmpdi2 (DItype a
, DItype b
)
734 au
.ll
= a
, bu
.ll
= b
;
736 if ((USItype
) au
.s
.high
< (USItype
) bu
.s
.high
)
738 else if ((USItype
) au
.s
.high
> (USItype
) bu
.s
.high
)
740 if ((USItype
) au
.s
.low
< (USItype
) bu
.s
.low
)
742 else if ((USItype
) au
.s
.low
> (USItype
) bu
.s
.low
)
748 #if defined(L_fixunstfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
749 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
750 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
753 __fixunstfdi (TFtype a
)
761 /* Compute high word of result, as a flonum. */
762 b
= (a
/ HIGH_WORD_COEFF
);
763 /* Convert that to fixed (but not to DItype!),
764 and shift it into the high word. */
767 /* Remove high part from the TFtype, leaving the low part as flonum. */
769 /* Convert that to fixed (but not to DItype!) and add it in.
770 Sometimes A comes out negative. This is significant, since
771 A has more bits than a long int does. */
773 v
-= (USItype
) (- a
);
780 #if defined(L_fixtfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
785 return - __fixunstfdi (-a
);
786 return __fixunstfdi (a
);
790 #if defined(L_fixunsxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
791 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
792 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
795 __fixunsxfdi (XFtype a
)
803 /* Compute high word of result, as a flonum. */
804 b
= (a
/ HIGH_WORD_COEFF
);
805 /* Convert that to fixed (but not to DItype!),
806 and shift it into the high word. */
809 /* Remove high part from the XFtype, leaving the low part as flonum. */
811 /* Convert that to fixed (but not to DItype!) and add it in.
812 Sometimes A comes out negative. This is significant, since
813 A has more bits than a long int does. */
815 v
-= (USItype
) (- a
);
822 #if defined(L_fixxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
827 return - __fixunsxfdi (-a
);
828 return __fixunsxfdi (a
);
833 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
834 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
837 __fixunsdfdi (DFtype a
)
845 /* Compute high word of result, as a flonum. */
846 b
= (a
/ HIGH_WORD_COEFF
);
847 /* Convert that to fixed (but not to DItype!),
848 and shift it into the high word. */
851 /* Remove high part from the DFtype, leaving the low part as flonum. */
853 /* Convert that to fixed (but not to DItype!) and add it in.
854 Sometimes A comes out negative. This is significant, since
855 A has more bits than a long int does. */
857 v
-= (USItype
) (- a
);
869 return - __fixunsdfdi (-a
);
870 return __fixunsdfdi (a
);
875 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
876 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
879 __fixunssfdi (SFtype original_a
)
881 /* Convert the SFtype to a DFtype, because that is surely not going
882 to lose any bits. Some day someone else can write a faster version
883 that avoids converting to DFtype, and verify it really works right. */
884 DFtype a
= original_a
;
891 /* Compute high word of result, as a flonum. */
892 b
= (a
/ HIGH_WORD_COEFF
);
893 /* Convert that to fixed (but not to DItype!),
894 and shift it into the high word. */
897 /* Remove high part from the DFtype, leaving the low part as flonum. */
899 /* Convert that to fixed (but not to DItype!) and add it in.
900 Sometimes A comes out negative. This is significant, since
901 A has more bits than a long int does. */
903 v
-= (USItype
) (- a
);
915 return - __fixunssfdi (-a
);
916 return __fixunssfdi (a
);
920 #if defined(L_floatdixf) && (LONG_DOUBLE_TYPE_SIZE == 96)
921 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
922 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
923 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
926 __floatdixf (DItype u
)
934 d
= (USItype
) (u
>> WORD_SIZE
);
935 d
*= HIGH_HALFWORD_COEFF
;
936 d
*= HIGH_HALFWORD_COEFF
;
937 d
+= (USItype
) (u
& (HIGH_WORD_COEFF
- 1));
939 return (negate
? -d
: d
);
943 #if defined(L_floatditf) && (LONG_DOUBLE_TYPE_SIZE == 128)
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)
949 __floatditf (DItype u
)
957 d
= (USItype
) (u
>> WORD_SIZE
);
958 d
*= HIGH_HALFWORD_COEFF
;
959 d
*= HIGH_HALFWORD_COEFF
;
960 d
+= (USItype
) (u
& (HIGH_WORD_COEFF
- 1));
962 return (negate
? -d
: d
);
967 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
968 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
969 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
972 __floatdidf (DItype u
)
980 d
= (USItype
) (u
>> WORD_SIZE
);
981 d
*= HIGH_HALFWORD_COEFF
;
982 d
*= HIGH_HALFWORD_COEFF
;
983 d
+= (USItype
) (u
& (HIGH_WORD_COEFF
- 1));
985 return (negate
? -d
: d
);
990 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
991 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
992 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
993 #define DI_SIZE (sizeof (DItype) * BITS_PER_UNIT)
995 /* Define codes for all the float formats that we know of. Note
996 that this is copied from real.h. */
998 #define UNKNOWN_FLOAT_FORMAT 0
999 #define IEEE_FLOAT_FORMAT 1
1000 #define VAX_FLOAT_FORMAT 2
1001 #define IBM_FLOAT_FORMAT 3
1003 /* Default to IEEE float if not specified. Nearly all machines use it. */
1004 #ifndef HOST_FLOAT_FORMAT
1005 #define HOST_FLOAT_FORMAT IEEE_FLOAT_FORMAT
1008 #if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1013 #if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
1018 #if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
1024 __floatdisf (DItype u
)
1026 /* Do the calculation in DFmode
1027 so that we don't lose any of the precision of the high word
1028 while multiplying it. */
1035 /* Protect against double-rounding error.
1036 Represent any low-order bits, that might be truncated in DFmode,
1037 by a bit that won't be lost. The bit can go in anywhere below the
1038 rounding position of the SFmode. A fixed mask and bit position
1039 handles all usual configurations. It doesn't handle the case
1040 of 128-bit DImode, however. */
1041 if (DF_SIZE
< DI_SIZE
1042 && DF_SIZE
> (DI_SIZE
- DF_SIZE
+ SF_SIZE
))
1044 #define REP_BIT ((USItype) 1 << (DI_SIZE - DF_SIZE))
1045 if (u
>= ((UDItype
) 1 << DF_SIZE
))
1047 if ((USItype
) u
& (REP_BIT
- 1))
1051 f
= (USItype
) (u
>> WORD_SIZE
);
1052 f
*= HIGH_HALFWORD_COEFF
;
1053 f
*= HIGH_HALFWORD_COEFF
;
1054 f
+= (USItype
) (u
& (HIGH_WORD_COEFF
- 1));
1056 return (SFtype
) (negate
? -f
: f
);
1060 #if defined(L_fixunsxfsi) && LONG_DOUBLE_TYPE_SIZE == 96
1061 /* Reenable the normal types, in case limits.h needs them. */
1074 __fixunsxfsi (XFtype a
)
1076 if (a
>= - (DFtype
) LONG_MIN
)
1077 return (SItype
) (a
+ LONG_MIN
) - LONG_MIN
;
1083 /* Reenable the normal types, in case limits.h needs them. */
1096 __fixunsdfsi (DFtype a
)
1098 if (a
>= - (DFtype
) LONG_MIN
)
1099 return (SItype
) (a
+ LONG_MIN
) - LONG_MIN
;
1105 /* Reenable the normal types, in case limits.h needs them. */
1118 __fixunssfsi (SFtype a
)
1120 if (a
>= - (SFtype
) LONG_MIN
)
1121 return (SItype
) (a
+ LONG_MIN
) - LONG_MIN
;
1126 /* From here on down, the routines use normal data types. */
1128 #define SItype bogus_type
1129 #define USItype bogus_type
1130 #define DItype bogus_type
1131 #define UDItype bogus_type
1132 #define SFtype bogus_type
1133 #define DFtype bogus_type
1145 /* Like bcmp except the sign is meaningful.
1146 Result is negative if S1 is less than S2,
1147 positive if S1 is greater, 0 if S1 and S2 are equal. */
1150 __gcc_bcmp (unsigned char *s1
, unsigned char *s2
, size_t size
)
1154 unsigned char c1
= *s1
++, c2
= *s2
++;
1171 #if defined(__svr4__) || defined(__alliant__)
1175 /* The Alliant needs the added underscore. */
1176 asm (".globl __builtin_saveregs");
1177 asm ("__builtin_saveregs:");
1178 asm (".globl ___builtin_saveregs");
1179 asm ("___builtin_saveregs:");
1181 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
1182 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
1183 area and also for a new va_list
1185 /* Save all argument registers in the arg reg save area. The
1186 arg reg save area must have the following layout (according
1198 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
1199 asm (" fst.q %f12,16(%sp)");
1201 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
1202 asm (" st.l %r17,36(%sp)");
1203 asm (" st.l %r18,40(%sp)");
1204 asm (" st.l %r19,44(%sp)");
1205 asm (" st.l %r20,48(%sp)");
1206 asm (" st.l %r21,52(%sp)");
1207 asm (" st.l %r22,56(%sp)");
1208 asm (" st.l %r23,60(%sp)");
1209 asm (" st.l %r24,64(%sp)");
1210 asm (" st.l %r25,68(%sp)");
1211 asm (" st.l %r26,72(%sp)");
1212 asm (" st.l %r27,76(%sp)");
1214 asm (" adds 80,%sp,%r16"); /* compute the address of the new
1215 va_list structure. Put in into
1216 r16 so that it will be returned
1219 /* Initialize all fields of the new va_list structure. This
1220 structure looks like:
1223 unsigned long ireg_used;
1224 unsigned long freg_used;
1230 asm (" st.l %r0, 0(%r16)"); /* nfixed */
1231 asm (" st.l %r0, 4(%r16)"); /* nfloating */
1232 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
1233 asm (" bri %r1"); /* delayed return */
1234 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
1236 #else /* not __svr4__ */
1237 #if defined(__PARAGON__)
1239 * we'll use SVR4-ish varargs but need SVR3.2 assembler syntax,
1240 * and we stand a better chance of hooking into libraries
1241 * compiled by PGI. [andyp@ssd.intel.com]
1245 asm (".globl __builtin_saveregs");
1246 asm ("__builtin_saveregs:");
1247 asm (".globl ___builtin_saveregs");
1248 asm ("___builtin_saveregs:");
1250 asm (" andnot 0x0f,sp,sp"); /* round down to 16-byte boundary */
1251 asm (" adds -96,sp,sp"); /* allocate stack space for reg save
1252 area and also for a new va_list
1254 /* Save all argument registers in the arg reg save area. The
1255 arg reg save area must have the following layout (according
1267 asm (" fst.q f8, 0(sp)");
1268 asm (" fst.q f12,16(sp)");
1269 asm (" st.l r16,32(sp)");
1270 asm (" st.l r17,36(sp)");
1271 asm (" st.l r18,40(sp)");
1272 asm (" st.l r19,44(sp)");
1273 asm (" st.l r20,48(sp)");
1274 asm (" st.l r21,52(sp)");
1275 asm (" st.l r22,56(sp)");
1276 asm (" st.l r23,60(sp)");
1277 asm (" st.l r24,64(sp)");
1278 asm (" st.l r25,68(sp)");
1279 asm (" st.l r26,72(sp)");
1280 asm (" st.l r27,76(sp)");
1282 asm (" adds 80,sp,r16"); /* compute the address of the new
1283 va_list structure. Put in into
1284 r16 so that it will be returned
1287 /* Initialize all fields of the new va_list structure. This
1288 structure looks like:
1291 unsigned long ireg_used;
1292 unsigned long freg_used;
1298 asm (" st.l r0, 0(r16)"); /* nfixed */
1299 asm (" st.l r0, 4(r16)"); /* nfloating */
1300 asm (" st.l sp, 8(r16)"); /* __va_ctl points to __va_struct. */
1301 asm (" bri r1"); /* delayed return */
1302 asm (" st.l r28,12(r16)"); /* pointer to overflow args */
1303 #else /* not __PARAGON__ */
1307 asm (".globl ___builtin_saveregs");
1308 asm ("___builtin_saveregs:");
1309 asm (" mov sp,r30");
1310 asm (" andnot 0x0f,sp,sp");
1311 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
1313 /* Fill in the __va_struct. */
1314 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
1315 asm (" st.l r17, 4(sp)"); /* int fixed[12] */
1316 asm (" st.l r18, 8(sp)");
1317 asm (" st.l r19,12(sp)");
1318 asm (" st.l r20,16(sp)");
1319 asm (" st.l r21,20(sp)");
1320 asm (" st.l r22,24(sp)");
1321 asm (" st.l r23,28(sp)");
1322 asm (" st.l r24,32(sp)");
1323 asm (" st.l r25,36(sp)");
1324 asm (" st.l r26,40(sp)");
1325 asm (" st.l r27,44(sp)");
1327 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
1328 asm (" fst.q f12,64(sp)"); /* int floating[8] */
1330 /* Fill in the __va_ctl. */
1331 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
1332 asm (" st.l r28,84(sp)"); /* pointer to more args */
1333 asm (" st.l r0, 88(sp)"); /* nfixed */
1334 asm (" st.l r0, 92(sp)"); /* nfloating */
1336 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
1338 asm (" mov r30,sp");
1339 /* recover stack and pass address to start
1341 #endif /* not __PARAGON__ */
1342 #endif /* not __svr4__ */
1343 #else /* not __i860__ */
1345 asm (".global __builtin_saveregs");
1346 asm ("__builtin_saveregs:");
1347 asm (".global ___builtin_saveregs");
1348 asm ("___builtin_saveregs:");
1349 #ifdef NEED_PROC_COMMAND
1352 asm ("st %i0,[%fp+68]");
1353 asm ("st %i1,[%fp+72]");
1354 asm ("st %i2,[%fp+76]");
1355 asm ("st %i3,[%fp+80]");
1356 asm ("st %i4,[%fp+84]");
1358 asm ("st %i5,[%fp+88]");
1359 #ifdef NEED_TYPE_COMMAND
1360 asm (".type __builtin_saveregs,#function");
1361 asm (".size __builtin_saveregs,.-__builtin_saveregs");
1363 #else /* not __sparc__ */
1364 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1367 asm (" .ent __builtin_saveregs");
1368 asm (" .globl __builtin_saveregs");
1369 asm ("__builtin_saveregs:");
1370 asm (" sw $4,0($30)");
1371 asm (" sw $5,4($30)");
1372 asm (" sw $6,8($30)");
1373 asm (" sw $7,12($30)");
1375 asm (" .end __builtin_saveregs");
1376 #else /* not __mips__, etc. */
1379 __builtin_saveregs ()
1384 #endif /* not __mips__ */
1385 #endif /* not __sparc__ */
1386 #endif /* not __i860__ */
1390 #ifndef inhibit_libc
1392 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1394 /* This is used by the `assert' macro. */
1396 __eprintf (const char *string
, const char *expression
,
1397 int line
, const char *filename
)
1399 fprintf (stderr
, string
, expression
, line
, filename
);
1409 /* Structure emitted by -a */
1413 const char *filename
;
1417 const unsigned long *addresses
;
1419 /* Older GCC's did not emit these fields. */
1421 const char **functions
;
1422 const long *line_nums
;
1423 const char **filenames
;
1427 #ifdef BLOCK_PROFILER_CODE
1430 #ifndef inhibit_libc
1432 /* Simple minded basic block profiling output dumper for
1433 systems that don't provide tcov support. At present,
1434 it requires atexit and stdio. */
1436 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1440 #include "gbl-ctors.h"
1442 static struct bb
*bb_head
;
1444 /* Return the number of digits needed to print a value */
1445 /* __inline__ */ static int num_digits (long value
, int base
)
1447 int minus
= (value
< 0 && base
!= 16);
1448 unsigned long v
= (minus
) ? -value
: value
;
1462 __bb_exit_func (void)
1464 FILE *file
= fopen ("bb.out", "a");
1474 /* This is somewhat type incorrect, but it avoids worrying about
1475 exactly where time.h is included from. It should be ok unless
1476 a void * differs from other pointer formats, or if sizeof (long)
1477 is < sizeof (time_t). It would be nice if we could assume the
1478 use of rationale standards here. */
1480 time ((void *) &time_value
);
1481 fprintf (file
, "Basic block profiling finished on %s\n", ctime ((void *) &time_value
));
1483 /* We check the length field explicitly in order to allow compatibility
1484 with older GCC's which did not provide it. */
1486 for (ptr
= bb_head
; ptr
!= (struct bb
*) 0; ptr
= ptr
->next
)
1489 int func_p
= (ptr
->nwords
>= sizeof (struct bb
) && ptr
->nwords
<= 1000);
1490 int line_p
= (func_p
&& ptr
->line_nums
);
1491 int file_p
= (func_p
&& ptr
->filenames
);
1492 long ncounts
= ptr
->ncounts
;
1498 int blk_len
= num_digits (ncounts
, 10);
1503 fprintf (file
, "File %s, %ld basic blocks \n\n",
1504 ptr
->filename
, ncounts
);
1506 /* Get max values for each field. */
1507 for (i
= 0; i
< ncounts
; i
++)
1512 if (cnt_max
< ptr
->counts
[i
])
1513 cnt_max
= ptr
->counts
[i
];
1515 if (addr_max
< ptr
->addresses
[i
])
1516 addr_max
= ptr
->addresses
[i
];
1518 if (line_p
&& line_max
< ptr
->line_nums
[i
])
1519 line_max
= ptr
->line_nums
[i
];
1523 p
= (ptr
->functions
[i
]) ? (ptr
->functions
[i
]) : "<none>";
1531 p
= (ptr
->filenames
[i
]) ? (ptr
->filenames
[i
]) : "<none>";
1538 addr_len
= num_digits (addr_max
, 16);
1539 cnt_len
= num_digits (cnt_max
, 10);
1540 line_len
= num_digits (line_max
, 10);
1542 /* Now print out the basic block information. */
1543 for (i
= 0; i
< ncounts
; i
++)
1546 " Block #%*d: executed %*ld time(s) address= 0x%.*lx",
1548 cnt_len
, ptr
->counts
[i
],
1549 addr_len
, ptr
->addresses
[i
]);
1552 fprintf (file
, " function= %-*s", func_len
,
1553 (ptr
->functions
[i
]) ? ptr
->functions
[i
] : "<none>");
1556 fprintf (file
, " line= %*ld", line_len
, ptr
->line_nums
[i
]);
1559 fprintf (file
, " file= %s",
1560 (ptr
->filenames
[i
]) ? ptr
->filenames
[i
] : "<none>");
1562 fprintf (file
, "\n");
1565 fprintf (file
, "\n");
1569 fprintf (file
, "\n\n");
1575 __bb_init_func (struct bb
*blocks
)
1577 /* User is supposed to check whether the first word is non-0,
1578 but just in case.... */
1580 if (blocks
->zero_word
)
1584 /* Initialize destructor. */
1586 ON_EXIT (__bb_exit_func
, 0);
1589 /* Set up linked list. */
1590 blocks
->zero_word
= 1;
1591 blocks
->next
= bb_head
;
1595 #ifndef MACHINE_STATE_SAVE
1596 #define MACHINE_STATE_SAVE(ID)
1598 #ifndef MACHINE_STATE_RESTORE
1599 #define MACHINE_STATE_RESTORE(ID)
1604 /* Number of buckets in hashtable of basic block addresses. */
1606 #define BB_BUCKETS 311
1608 /* Maximum length of string in file bb.in. */
1610 #define BBINBUFSIZE 500
1612 /* BBINBUFSIZE-1 with double quotes. We could use #BBINBUFSIZE or
1613 "BBINBUFSIZE" but want to avoid trouble with preprocessors. */
1615 #define BBINBUFSIZESTR "499"
1619 struct bb_edge
*next
;
1620 unsigned long src_addr
;
1621 unsigned long dst_addr
;
1622 unsigned long count
;
1627 TRACE_KEEP
= 0, TRACE_ON
= 1, TRACE_OFF
= 2
1632 struct bb_func
*next
;
1635 enum bb_func_mode mode
;
1638 /* This is the connection to the outside world.
1639 The BLOCK_PROFILER macro must set __bb.blocks
1640 and __bb.blockno. */
1643 unsigned long blockno
;
1647 /* Vars to store addrs of source and destination basic blocks
1650 static unsigned long bb_src
= 0;
1651 static unsigned long bb_dst
= 0;
1653 static FILE *bb_tracefile
= (FILE *) 0;
1654 static struct bb_edge
**bb_hashbuckets
= (struct bb_edge
**) 0;
1655 static struct bb_func
*bb_func_head
= (struct bb_func
*) 0;
1656 static unsigned long bb_callcount
= 0;
1657 static int bb_mode
= 0;
1659 static unsigned long *bb_stack
= (unsigned long *) 0;
1660 static size_t bb_stacksize
= 0;
1662 static int reported
= 0;
1665 Always : Print execution frequencies of basic blocks
1667 bb_mode & 1 != 0 : Dump trace of basic blocks to file bbtrace[.gz]
1668 bb_mode & 2 != 0 : Print jump frequencies to file bb.out.
1669 bb_mode & 4 != 0 : Cut call instructions from basic block flow.
1670 bb_mode & 8 != 0 : Insert return instructions in basic block flow.
1675 /*#include <sys/types.h>*/
1676 #include <sys/stat.h>
1677 /*#include <malloc.h>*/
1679 /* Commands executed by gopen. */
1681 #define GOPENDECOMPRESS "gzip -cd "
1682 #define GOPENCOMPRESS "gzip -c >"
1684 /* Like fopen but pipes through gzip. mode may only be "r" or "w".
1685 If it does not compile, simply replace gopen by fopen and delete
1686 '.gz' from any first parameter to gopen. */
1689 gopen (char *fn
, char *mode
)
1697 if (mode
[0] != 'r' && mode
[0] != 'w')
1700 p
= fn
+ strlen (fn
)-1;
1701 use_gzip
= ((p
[-1] == '.' && (p
[0] == 'Z' || p
[0] == 'z')) ||
1702 (p
[-2] == '.' && p
[-1] == 'g' && p
[0] == 'z'));
1709 char *s
= (char *) malloc (sizeof (char) * strlen (fn
)
1710 + sizeof (GOPENDECOMPRESS
));
1711 strcpy (s
, GOPENDECOMPRESS
);
1712 strcpy (s
+ (sizeof (GOPENDECOMPRESS
)-1), fn
);
1713 f
= popen (s
, mode
);
1721 char *s
= (char *) malloc (sizeof (char) * strlen (fn
)
1722 + sizeof (GOPENCOMPRESS
));
1723 strcpy (s
, GOPENCOMPRESS
);
1724 strcpy (s
+ (sizeof (GOPENCOMPRESS
)-1), fn
);
1725 if (!(f
= popen (s
, mode
)))
1726 f
= fopen (s
, mode
);
1733 return fopen (fn
, mode
);
1743 if (!fstat (fileno (f
), &buf
) && S_ISFIFO (buf
.st_mode
))
1751 #endif /* HAVE_POPEN */
1753 /* Called once per program. */
1756 __bb_exit_trace_func ()
1758 FILE *file
= fopen ("bb.out", "a");
1772 gclose (bb_tracefile
);
1774 fclose (bb_tracefile
);
1775 #endif /* HAVE_POPEN */
1778 /* Check functions in `bb.in'. */
1783 const struct bb_func
*p
;
1784 int printed_something
= 0;
1788 /* This is somewhat type incorrect. */
1789 time ((void *) &time_value
);
1791 for (p
= bb_func_head
; p
!= (struct bb_func
*) 0; p
= p
->next
)
1793 for (ptr
= bb_head
; ptr
!= (struct bb
*) 0; ptr
= ptr
->next
)
1795 if (!ptr
->filename
|| p
->filename
!= (char *) 0 && strcmp (p
->filename
, ptr
->filename
))
1797 for (blk
= 0; blk
< ptr
->ncounts
; blk
++)
1799 if (!strcmp (p
->funcname
, ptr
->functions
[blk
]))
1804 if (!printed_something
)
1806 fprintf (file
, "Functions in `bb.in' not executed during basic block profiling on %s\n", ctime ((void *) &time_value
));
1807 printed_something
= 1;
1810 fprintf (file
, "\tFunction %s", p
->funcname
);
1812 fprintf (file
, " of file %s", p
->filename
);
1813 fprintf (file
, "\n" );
1818 if (printed_something
)
1819 fprintf (file
, "\n");
1825 if (!bb_hashbuckets
)
1829 fprintf (stderr
, "Profiler: out of memory\n");
1839 unsigned long addr_max
= 0;
1840 unsigned long cnt_max
= 0;
1844 /* This is somewhat type incorrect, but it avoids worrying about
1845 exactly where time.h is included from. It should be ok unless
1846 a void * differs from other pointer formats, or if sizeof (long)
1847 is < sizeof (time_t). It would be nice if we could assume the
1848 use of rationale standards here. */
1850 time ((void *) &time_value
);
1851 fprintf (file
, "Basic block jump tracing");
1853 switch (bb_mode
& 12)
1856 fprintf (file
, " (with call)");
1860 /* Print nothing. */
1864 fprintf (file
, " (with call & ret)");
1868 fprintf (file
, " (with ret)");
1872 fprintf (file
, " finished on %s\n", ctime ((void *) &time_value
));
1874 for (i
= 0; i
< BB_BUCKETS
; i
++)
1876 struct bb_edge
*bucket
= bb_hashbuckets
[i
];
1877 for ( ; bucket
; bucket
= bucket
->next
)
1879 if (addr_max
< bucket
->src_addr
)
1880 addr_max
= bucket
->src_addr
;
1881 if (addr_max
< bucket
->dst_addr
)
1882 addr_max
= bucket
->dst_addr
;
1883 if (cnt_max
< bucket
->count
)
1884 cnt_max
= bucket
->count
;
1887 addr_len
= num_digits (addr_max
, 16);
1888 cnt_len
= num_digits (cnt_max
, 10);
1890 for ( i
= 0; i
< BB_BUCKETS
; i
++)
1892 struct bb_edge
*bucket
= bb_hashbuckets
[i
];
1893 for ( ; bucket
; bucket
= bucket
->next
)
1895 fprintf (file
, "Jump from block 0x%.*lx to "
1896 "block 0x%.*lx executed %*d time(s)\n",
1897 addr_len
, bucket
->src_addr
,
1898 addr_len
, bucket
->dst_addr
,
1899 cnt_len
, bucket
->count
);
1903 fprintf (file
, "\n");
1911 /* Free allocated memory. */
1916 struct bb_func
*old
= f
;
1919 if (old
->funcname
) free (old
->funcname
);
1920 if (old
->filename
) free (old
->filename
);
1931 for (i
= 0; i
< BB_BUCKETS
; i
++)
1933 struct bb_edge
*old
, *bucket
= bb_hashbuckets
[i
];
1938 bucket
= bucket
->next
;
1942 free (bb_hashbuckets
);
1945 for (b
= bb_head
; b
; b
= b
->next
)
1946 if (b
->flags
) free (b
->flags
);
1949 /* Called once per program. */
1956 char buf
[BBINBUFSIZE
];
1959 enum bb_func_mode m
;
1962 /* Initialize destructor. */
1963 ON_EXIT (__bb_exit_func
, 0);
1966 if (!(file
= fopen ("bb.in", "r")))
1969 while(fscanf (file
, " %" BBINBUFSIZESTR
"s ", buf
) != EOF
)
1981 if (!strcmp (p
, "__bb_trace__"))
1983 else if (!strcmp (p
, "__bb_jumps__"))
1985 else if (!strcmp (p
, "__bb_hidecall__"))
1987 else if (!strcmp (p
, "__bb_showret__"))
1991 struct bb_func
*f
= (struct bb_func
*) malloc (sizeof (struct bb_func
));
1995 f
->next
= bb_func_head
;
1996 if (pos
= strchr (p
, ':'))
1998 if (!(f
->funcname
= (char *) malloc (strlen (pos
+1)+1)))
2000 strcpy (f
->funcname
, pos
+1);
2002 if ((f
->filename
= (char *) malloc (l
+1)))
2004 strncpy (f
->filename
, p
, l
);
2005 f
->filename
[l
] = '\0';
2008 f
->filename
= (char *) 0;
2012 if (!(f
->funcname
= (char *) malloc (strlen (p
)+1)))
2014 strcpy (f
->funcname
, p
);
2015 f
->filename
= (char *) 0;
2027 bb_tracefile
= gopen ("bbtrace.gz", "w");
2032 bb_tracefile
= fopen ("bbtrace", "w");
2034 #endif /* HAVE_POPEN */
2038 bb_hashbuckets
= (struct bb_edge
**)
2039 malloc (BB_BUCKETS
* sizeof (struct bb_edge
*));
2041 bzero ((char *) bb_hashbuckets
, BB_BUCKETS
);
2047 bb_stack
= (unsigned long *) malloc (bb_stacksize
* sizeof (*bb_stack
));
2051 /* Initialize destructor. */
2052 ON_EXIT (__bb_exit_trace_func
, 0);
2057 /* Called upon entering a basic block. */
2062 struct bb_edge
*bucket
;
2064 MACHINE_STATE_SAVE("1")
2066 if (!bb_callcount
|| (__bb
.blocks
->flags
&& (__bb
.blocks
->flags
[__bb
.blockno
] & TRACE_OFF
)))
2069 bb_dst
= __bb
.blocks
->addresses
[__bb
.blockno
];
2070 __bb
.blocks
->counts
[__bb
.blockno
]++;
2074 fwrite (&bb_dst
, sizeof (unsigned long), 1, bb_tracefile
);
2079 struct bb_edge
**startbucket
, **oldnext
;
2081 oldnext
= startbucket
=
2082 & bb_hashbuckets
[ (((int) bb_src
*8) ^ (int) bb_dst
) % BB_BUCKETS
];
2083 bucket
= *startbucket
;
2085 for (bucket
= *startbucket
; bucket
;
2086 oldnext
= &(bucket
->next
), bucket
= *oldnext
)
2088 if ( bucket
->src_addr
== bb_src
&&
2089 bucket
->dst_addr
== bb_dst
)
2092 *oldnext
= bucket
->next
;
2093 bucket
->next
= *startbucket
;
2094 *startbucket
= bucket
;
2099 bucket
= (struct bb_edge
*) malloc (sizeof (struct bb_edge
));
2105 fprintf (stderr
, "Profiler: out of memory\n");
2112 bucket
->src_addr
= bb_src
;
2113 bucket
->dst_addr
= bb_dst
;
2114 bucket
->next
= *startbucket
;
2115 *startbucket
= bucket
;
2126 MACHINE_STATE_RESTORE("1")
2130 /* Called when returning from a function and `__bb_showret__' is set. */
2133 __bb_trace_func_ret ()
2135 struct bb_edge
*bucket
;
2137 if (!bb_callcount
|| (__bb
.blocks
->flags
&& (__bb
.blocks
->flags
[__bb
.blockno
] & TRACE_OFF
)))
2142 struct bb_edge
**startbucket
, **oldnext
;
2144 oldnext
= startbucket
=
2145 & bb_hashbuckets
[ (((int) bb_dst
* 8) ^ (int) bb_src
) % BB_BUCKETS
];
2146 bucket
= *startbucket
;
2148 for (bucket
= *startbucket
; bucket
;
2149 oldnext
= &(bucket
->next
), bucket
= *oldnext
)
2151 if ( bucket
->src_addr
== bb_dst
&&
2152 bucket
->dst_addr
== bb_src
)
2155 *oldnext
= bucket
->next
;
2156 bucket
->next
= *startbucket
;
2157 *startbucket
= bucket
;
2162 bucket
= (struct bb_edge
*) malloc (sizeof (struct bb_edge
));
2168 fprintf (stderr
, "Profiler: out of memory\n");
2175 bucket
->src_addr
= bb_dst
;
2176 bucket
->dst_addr
= bb_src
;
2177 bucket
->next
= *startbucket
;
2178 *startbucket
= bucket
;
2191 /* Called upon entering the first function of a file. */
2194 __bb_init_file (struct bb
*blocks
)
2197 const struct bb_func
*p
;
2198 long blk
, ncounts
= blocks
->ncounts
;
2199 const char **functions
= blocks
->functions
;
2201 /* Set up linked list. */
2202 blocks
->zero_word
= 1;
2203 blocks
->next
= bb_head
;
2207 if (!bb_func_head
||
2208 !(blocks
->flags
= (char *) malloc (sizeof (char) * blocks
->ncounts
)))
2211 for (blk
= 0; blk
< ncounts
; blk
++)
2212 blocks
->flags
[blk
] = 0;
2214 for (blk
= 0; blk
< ncounts
; blk
++)
2216 for (p
= bb_func_head
; p
; p
= p
->next
)
2218 if (!strcmp (p
->funcname
, functions
[blk
]) &&
2219 (!p
->filename
|| !strcmp (p
->filename
, blocks
->filename
)))
2221 blocks
->flags
[blk
] |= p
->mode
;
2228 /* Called when exiting from a function. */
2234 MACHINE_STATE_SAVE("2")
2238 if ((bb_mode
& 12) && bb_stacksize
> bb_callcount
)
2240 bb_src
= bb_stack
[bb_callcount
];
2242 __bb_trace_func_ret ();
2248 MACHINE_STATE_RESTORE("2")
2252 /* Called when entering a function. */
2255 __bb_init_trace_func (struct bb
*blocks
, unsigned long blockno
)
2257 static int trace_init
= 0;
2259 MACHINE_STATE_SAVE("3")
2261 if (!blocks
->zero_word
)
2268 __bb_init_file (blocks
);
2278 if (bb_callcount
>= bb_stacksize
)
2280 size_t newsize
= bb_callcount
+ 100;
2282 bb_stack
= (unsigned long *) realloc (bb_stack
, newsize
);
2287 fprintf (stderr
, "Profiler: out of memory\n");
2291 goto stack_overflow
;
2293 bb_stacksize
= newsize
;
2295 bb_stack
[bb_callcount
] = bb_src
;
2306 else if (blocks
->flags
&& (blocks
->flags
[blockno
] & TRACE_ON
))
2312 bb_stack
[bb_callcount
] = bb_src
;
2315 MACHINE_STATE_RESTORE("3")
2318 #endif /* not inhibit_libc */
2319 #endif /* not BLOCK_PROFILER_CODE */
2322 /* Default free-store management functions for C++, per sections 12.5 and
2323 17.3.3 of the Working Paper. */
2326 /* operator new (size_t), described in 17.3.3.5. This function is used by
2327 C++ programs to allocate a block of memory to hold a single object. */
2329 typedef void (*vfp
)(void);
2330 extern vfp __new_handler
;
2331 extern void __default_new_handler (void);
2334 void * __builtin_new (size_t sz
)
2335 __attribute__ ((weak
, alias ("___builtin_new")));
2337 ___builtin_new (size_t sz
)
2340 __builtin_new (size_t sz
)
2344 vfp handler
= (__new_handler
) ? __new_handler
: __default_new_handler
;
2346 /* malloc (0) is unpredictable; avoid it. */
2349 p
= (void *) malloc (sz
);
2353 p
= (void *) malloc (sz
);
2358 #endif /* L_op_new */
2361 /* void * operator new [] (size_t), described in 17.3.3.6. This function
2362 is used by C++ programs to allocate a block of memory for an array. */
2364 extern void * __builtin_new (size_t);
2367 void * __builtin_vec_new (size_t sz
)
2368 __attribute__ ((weak
, alias ("___builtin_vec_new")));
2370 ___builtin_vec_new (size_t sz
)
2373 __builtin_vec_new (size_t sz
)
2376 return __builtin_new (sz
);
2378 #endif /* L_op_vnew */
2380 #ifdef L_new_handler
2381 /* set_new_handler (fvoid_t *) and the default new handler, described in
2382 17.3.3.2 and 17.3.3.5. These functions define the result of a failure
2383 to allocate the amount of memory requested from operator new or new []. */
2385 #ifndef inhibit_libc
2386 /* This gets us __GNU_LIBRARY__. */
2387 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2390 #ifdef __GNU_LIBRARY__
2391 /* Avoid forcing the library's meaning of `write' on the user program
2392 by using the "internal" name (for use within the library) */
2393 #define write(fd, buf, n) __write((fd), (buf), (n))
2395 #endif /* inhibit_libc */
2397 typedef void (*vfp
)(void);
2398 void __default_new_handler (void);
2400 vfp __new_handler
= (vfp
) 0;
2403 set_new_handler (vfp handler
)
2407 prev_handler
= __new_handler
;
2408 if (handler
== 0) handler
= __default_new_handler
;
2409 __new_handler
= handler
;
2410 return prev_handler
;
2413 #define MESSAGE "Virtual memory exceeded in `new'\n"
2416 __default_new_handler ()
2418 #ifndef inhibit_libc
2419 /* don't use fprintf (stderr, ...) because it may need to call malloc. */
2420 /* This should really print the name of the program, but that is hard to
2421 do. We need a standard, clean way to get at the name. */
2422 write (2, MESSAGE
, sizeof (MESSAGE
));
2424 /* don't call exit () because that may call global destructors which
2425 may cause a loop. */
2431 /* operator delete (void *), described in 17.3.3.3. This function is used
2432 by C++ programs to return to the free store a block of memory allocated
2433 as a single object. */
2436 void __builtin_delete (void *ptr
)
2437 __attribute__ ((weak
, alias ("___builtin_delete")));
2439 ___builtin_delete (void *ptr
)
2442 __builtin_delete (void *ptr
)
2451 /* operator delete [] (void *), described in 17.3.3.4. This function is
2452 used by C++ programs to return to the free store a block of memory
2453 allocated as an array. */
2455 extern void __builtin_delete (void *);
2458 void __builtin_vec_delete (void *ptr
)
2459 __attribute__ ((weak
, alias ("___builtin_vec_delete")));
2461 ___builtin_vec_delete (void *ptr
)
2464 __builtin_vec_delete (void *ptr
)
2467 __builtin_delete (ptr
);
2471 /* End of C++ free-store management functions */
2474 unsigned int __shtab
[] = {
2475 0x00000001, 0x00000002, 0x00000004, 0x00000008,
2476 0x00000010, 0x00000020, 0x00000040, 0x00000080,
2477 0x00000100, 0x00000200, 0x00000400, 0x00000800,
2478 0x00001000, 0x00002000, 0x00004000, 0x00008000,
2479 0x00010000, 0x00020000, 0x00040000, 0x00080000,
2480 0x00100000, 0x00200000, 0x00400000, 0x00800000,
2481 0x01000000, 0x02000000, 0x04000000, 0x08000000,
2482 0x10000000, 0x20000000, 0x40000000, 0x80000000
2486 #ifdef L_clear_cache
2487 /* Clear part of an instruction cache. */
2489 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
2492 __clear_cache (char *beg
, char *end
)
2494 #ifdef CLEAR_INSN_CACHE
2495 CLEAR_INSN_CACHE (beg
, end
);
2497 #ifdef INSN_CACHE_SIZE
2498 static char array
[INSN_CACHE_SIZE
+ INSN_CACHE_PLANE_SIZE
+ INSN_CACHE_LINE_WIDTH
];
2499 static int initialized
;
2503 typedef (*function_ptr
) ();
2505 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
2506 /* It's cheaper to clear the whole cache.
2507 Put in a series of jump instructions so that calling the beginning
2508 of the cache will clear the whole thing. */
2512 int ptr
= (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
2513 & -INSN_CACHE_LINE_WIDTH
);
2514 int end_ptr
= ptr
+ INSN_CACHE_SIZE
;
2516 while (ptr
< end_ptr
)
2518 *(INSTRUCTION_TYPE
*)ptr
2519 = JUMP_AHEAD_INSTRUCTION
+ INSN_CACHE_LINE_WIDTH
;
2520 ptr
+= INSN_CACHE_LINE_WIDTH
;
2522 *(INSTRUCTION_TYPE
*) (ptr
- INSN_CACHE_LINE_WIDTH
) = RETURN_INSTRUCTION
;
2527 /* Call the beginning of the sequence. */
2528 (((function_ptr
) (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
2529 & -INSN_CACHE_LINE_WIDTH
))
2532 #else /* Cache is large. */
2536 int ptr
= (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
2537 & -INSN_CACHE_LINE_WIDTH
);
2539 while (ptr
< (int) array
+ sizeof array
)
2541 *(INSTRUCTION_TYPE
*)ptr
= RETURN_INSTRUCTION
;
2542 ptr
+= INSN_CACHE_LINE_WIDTH
;
2548 /* Find the location in array that occupies the same cache line as BEG. */
2550 offset
= ((int) beg
& -INSN_CACHE_LINE_WIDTH
) & (INSN_CACHE_PLANE_SIZE
- 1);
2551 start_addr
= (((int) (array
+ INSN_CACHE_PLANE_SIZE
- 1)
2552 & -INSN_CACHE_PLANE_SIZE
)
2555 /* Compute the cache alignment of the place to stop clearing. */
2556 #if 0 /* This is not needed for gcc's purposes. */
2557 /* If the block to clear is bigger than a cache plane,
2558 we clear the entire cache, and OFFSET is already correct. */
2559 if (end
< beg
+ INSN_CACHE_PLANE_SIZE
)
2561 offset
= (((int) (end
+ INSN_CACHE_LINE_WIDTH
- 1)
2562 & -INSN_CACHE_LINE_WIDTH
)
2563 & (INSN_CACHE_PLANE_SIZE
- 1));
2565 #if INSN_CACHE_DEPTH > 1
2566 end_addr
= (start_addr
& -INSN_CACHE_PLANE_SIZE
) + offset
;
2567 if (end_addr
<= start_addr
)
2568 end_addr
+= INSN_CACHE_PLANE_SIZE
;
2570 for (plane
= 0; plane
< INSN_CACHE_DEPTH
; plane
++)
2572 int addr
= start_addr
+ plane
* INSN_CACHE_PLANE_SIZE
;
2573 int stop
= end_addr
+ plane
* INSN_CACHE_PLANE_SIZE
;
2575 while (addr
!= stop
)
2577 /* Call the return instruction at ADDR. */
2578 ((function_ptr
) addr
) ();
2580 addr
+= INSN_CACHE_LINE_WIDTH
;
2583 #else /* just one plane */
2586 /* Call the return instruction at START_ADDR. */
2587 ((function_ptr
) start_addr
) ();
2589 start_addr
+= INSN_CACHE_LINE_WIDTH
;
2591 while ((start_addr
% INSN_CACHE_SIZE
) != offset
);
2592 #endif /* just one plane */
2593 #endif /* Cache is large */
2594 #endif /* Cache exists */
2595 #endif /* CLEAR_INSN_CACHE */
2598 #endif /* L_clear_cache */
2602 /* Jump to a trampoline, loading the static chain address. */
2615 int mprotect(char *addr
, int len
, int prot
)
2619 if (prot
== 7) np
= 0x40;
2620 else if (prot
== 5) np
= 0x20;
2621 else if (prot
== 4) np
= 0x10;
2622 else if (prot
== 3) np
= 0x04;
2623 else if (prot
== 1) np
= 0x02;
2624 else if (prot
== 0) np
= 0x01;
2626 if (VirtualProtect (addr
, len
, np
, &op
))
2635 #ifdef TRANSFER_FROM_TRAMPOLINE
2636 TRANSFER_FROM_TRAMPOLINE
2639 #if defined (NeXT) && defined (__MACH__)
2641 /* Make stack executable so we can call trampolines on stack.
2642 This is called from INITIALIZE_TRAMPOLINE in next.h. */
2646 #include <mach/mach.h>
2650 __enable_execute_stack (char *addr
)
2653 char *eaddr
= addr
+ TRAMPOLINE_SIZE
;
2654 vm_address_t a
= (vm_address_t
) addr
;
2656 /* turn on execute access on stack */
2657 r
= vm_protect (task_self (), a
, TRAMPOLINE_SIZE
, FALSE
, VM_PROT_ALL
);
2658 if (r
!= KERN_SUCCESS
)
2660 mach_error("vm_protect VM_PROT_ALL", r
);
2664 /* We inline the i-cache invalidation for speed */
2666 #ifdef CLEAR_INSN_CACHE
2667 CLEAR_INSN_CACHE (addr
, eaddr
);
2669 __clear_cache ((int) addr
, (int) eaddr
);
2673 #endif /* defined (NeXT) && defined (__MACH__) */
2677 /* Make stack executable so we can call trampolines on stack.
2678 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
2680 #include <sys/mman.h>
2681 #include <sys/vmparam.h>
2682 #include <machine/machparam.h>
2685 __enable_execute_stack ()
2688 static unsigned lowest
= USRSTACK
;
2689 unsigned current
= (unsigned) &fp
& -NBPG
;
2691 if (lowest
> current
)
2693 unsigned len
= lowest
- current
;
2694 mremap (current
, &len
, PROT_READ
| PROT_WRITE
| PROT_EXEC
, MAP_PRIVATE
);
2698 /* Clear instruction cache in case an old trampoline is in it. */
2701 #endif /* __convex__ */
2705 /* Modified from the convex -code above. */
2707 #include <sys/param.h>
2709 #include <sys/m88kbcs.h>
2712 __enable_execute_stack ()
2715 static unsigned long lowest
= USRSTACK
;
2716 unsigned long current
= (unsigned long) &save_errno
& -NBPC
;
2718 /* Ignore errno being set. memctl sets errno to EINVAL whenever the
2719 address is seen as 'negative'. That is the case with the stack. */
2722 if (lowest
> current
)
2724 unsigned len
=lowest
-current
;
2725 memctl(current
,len
,MCT_TEXT
);
2729 memctl(current
,NBPC
,MCT_TEXT
);
2733 #endif /* __DOLPHIN__ */
2737 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2739 #include <sys/mman.h>
2740 #include <sys/types.h>
2741 #include <sys/param.h>
2742 #include <sys/vmmac.h>
2744 /* Modified from the convex -code above.
2745 mremap promises to clear the i-cache. */
2748 __enable_execute_stack ()
2751 if (mprotect (((unsigned int)&fp
/PAGSIZ
)*PAGSIZ
, PAGSIZ
,
2752 PROT_READ
|PROT_WRITE
|PROT_EXEC
))
2754 perror ("mprotect in __enable_execute_stack");
2759 #endif /* __pyr__ */
2761 #if defined (sony_news) && defined (SYSTYPE_BSD)
2764 #include <sys/types.h>
2765 #include <sys/param.h>
2766 #include <syscall.h>
2767 #include <machine/sysnews.h>
2769 /* cacheflush function for NEWS-OS 4.2.
2770 This function is called from trampoline-initialize code
2771 defined in config/mips/mips.h. */
2774 cacheflush (char *beg
, int size
, int flag
)
2776 if (syscall (SYS_sysnews
, NEWS_CACHEFLUSH
, beg
, size
, FLUSH_BCACHE
))
2778 perror ("cache_flush");
2784 #endif /* sony_news */
2785 #endif /* L_trampoline */
2789 #include "gbl-ctors.h"
2790 /* Some systems use __main in a way incompatible with its use in gcc, in these
2791 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2792 give the same symbol without quotes for an alternative entry point. You
2793 must define both, or neither. */
2795 #define NAME__MAIN "__main"
2796 #define SYMBOL__MAIN __main
2799 #ifdef INIT_SECTION_ASM_OP
2800 #undef HAS_INIT_SECTION
2801 #define HAS_INIT_SECTION
2804 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
2805 /* Run all the global destructors on exit from the program. */
2808 __do_global_dtors ()
2810 #ifdef DO_GLOBAL_DTORS_BODY
2811 DO_GLOBAL_DTORS_BODY
;
2813 static func_ptr
*p
= __DTOR_LIST__
+ 1;
2823 #ifndef HAS_INIT_SECTION
2824 /* Run all the global constructors on entry to the program. */
2827 #define ON_EXIT(a, b)
2829 /* Make sure the exit routine is pulled in to define the globals as
2830 bss symbols, just in case the linker does not automatically pull
2831 bss definitions from the library. */
2833 extern int _exit_dummy_decl
;
2834 int *_exit_dummy_ref
= &_exit_dummy_decl
;
2835 #endif /* ON_EXIT */
2838 __do_global_ctors ()
2840 DO_GLOBAL_CTORS_BODY
;
2841 ON_EXIT (__do_global_dtors
, 0);
2843 #endif /* no HAS_INIT_SECTION */
2845 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
2846 /* Subroutine called automatically by `main'.
2847 Compiling a global function named `main'
2848 produces an automatic call to this function at the beginning.
2850 For many systems, this routine calls __do_global_ctors.
2851 For systems which support a .init section we use the .init section
2852 to run __do_global_ctors, so we need not do anything here. */
2857 /* Support recursive calls to `main': run initializers just once. */
2858 static int initialized
;
2862 __do_global_ctors ();
2865 #endif /* no HAS_INIT_SECTION or INVOKE__main */
2867 #endif /* L__main */
2871 #include "gbl-ctors.h"
2873 /* Provide default definitions for the lists of constructors and
2874 destructors, so that we don't get linker errors. These symbols are
2875 intentionally bss symbols, so that gld and/or collect will provide
2876 the right values. */
2878 /* We declare the lists here with two elements each,
2879 so that they are valid empty lists if no other definition is loaded. */
2880 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
2881 #if defined(__NeXT__) || defined(_AIX)
2882 /* After 2.3, try this definition on all systems. */
2883 func_ptr __CTOR_LIST__
[2] = {0, 0};
2884 func_ptr __DTOR_LIST__
[2] = {0, 0};
2886 func_ptr __CTOR_LIST__
[2];
2887 func_ptr __DTOR_LIST__
[2];
2889 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
2890 #endif /* L_ctors */
2894 #include "gbl-ctors.h"
2900 int _exit_dummy_decl
= 0; /* prevent compiler & linker warnings */
2908 static func_ptr
*atexit_chain
= NULL
;
2909 static long atexit_chain_length
= 0;
2910 static volatile long last_atexit_chain_slot
= -1;
2912 int atexit (func_ptr func
)
2914 if (++last_atexit_chain_slot
== atexit_chain_length
)
2916 atexit_chain_length
+= 32;
2918 atexit_chain
= realloc (atexit_chain
,
2919 atexit_chain_length
* sizeof (func_ptr
));
2921 atexit_chain
= malloc (atexit_chain_length
* sizeof (func_ptr
));
2924 atexit_chain_length
= 0;
2925 last_atexit_chain_slot
= -1;
2930 atexit_chain
[last_atexit_chain_slot
] = func
;
2933 #endif /* NEED_ATEXIT */
2935 /* If we have no known way of registering our own __do_global_dtors
2936 routine so that it will be invoked at program exit time, then we
2937 have to define our own exit routine which will get this to happen. */
2939 extern void __do_global_dtors ();
2940 extern void _cleanup ();
2941 extern void _exit () __attribute__ ((noreturn
));
2946 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2950 for ( ; last_atexit_chain_slot
-- >= 0; )
2952 (*atexit_chain
[last_atexit_chain_slot
+ 1]) ();
2953 atexit_chain
[last_atexit_chain_slot
+ 1] = NULL
;
2955 free (atexit_chain
);
2956 atexit_chain
= NULL
;
2958 #else /* No NEED_ATEXIT */
2959 __do_global_dtors ();
2960 #endif /* No NEED_ATEXIT */
2971 int _exit_dummy_decl
= 0; /* prevent compiler & linker warnings */
2978 #ifdef EH_TABLE_LOOKUP
2987 void *exception_handler
;
2990 struct exception_table_node
{
2991 exception_table
*table
;
2994 struct exception_table_node
*next
;
2997 static struct exception_table_node
*exception_table_list
;
2999 static exception_table
*
3000 find_exception_table (void *pc
)
3002 register struct exception_table_node
*table
= exception_table_list
;
3003 for ( ; table
!= 0; table
= table
->next
)
3005 if (table
->start
<= pc
&& table
->end
> pc
)
3006 return table
->table
;
3011 /* this routine takes a pc, and the address of the exception handler associated
3012 with the closest exception table handler entry associated with that PC,
3013 or 0 if there are no table entries the PC fits in. The algorithm works
3014 something like this:
3016 while(current_entry exists) {
3017 if(current_entry.start < pc )
3018 current_entry = next_entry;
3020 if(prev_entry.start <= pc && prev_entry.end > pc) {
3021 save pointer to prev_entry;
3022 return prev_entry.exception_handler;
3029 Assuming a correctly sorted table (ascending order) this routine should
3030 return the tightest match...
3032 In the advent of a tie, we have to give the last entry, as it represents
3036 __find_first_exception_table_match (void *pc
)
3038 exception_table
*table
= find_exception_table (pc
);
3044 printf ("find_first_exception_table_match (): pc = %x!\n", pc
);
3048 /* We can't do this yet, as we don't know that the table is sorted. */
3051 if (table
[pos
].start
> pc
)
3052 /* found the first table[pos].start > pc, so the previous
3053 entry better be the one we want! */
3055 } while (table
[pos
].exception_handler
!= (void *) -1);
3058 if (table
[pos
].start
<= pc
&& table
[pos
].end
> pc
)
3061 printf ("find_first_eh_table_match (): found match: %x\n", table
[pos
].exception_handler
);
3063 return table
[pos
].exception_handler
;
3066 while (table
[++pos
].exception_handler
!= (void *) -1) {
3067 if (table
[pos
].start
<= pc
&& table
[pos
].end
> pc
)
3069 /* This can apply. Make sure it is better or as good as the previous
3071 /* The best one ends first. */
3072 if (best
== 0 || (table
[pos
].end
<= table
[best
].end
3073 /* The best one starts last. */
3074 && table
[pos
].start
>= table
[best
].start
))
3079 return table
[best
].exception_handler
;
3083 printf ("find_first_eh_table_match (): else: returning NULL!\n");
3089 __register_exceptions (exception_table
*table
)
3091 struct exception_table_node
*node
;
3092 exception_table
*range
= table
+ 1;
3094 if (range
->start
== (void *) -1)
3097 node
= (struct exception_table_node
*)
3098 malloc (sizeof (struct exception_table_node
));
3099 node
->table
= table
;
3101 /* This look can be optimized away either if the table
3102 is sorted, or if we pass in extra parameters. */
3103 node
->start
= range
->start
;
3104 node
->end
= range
->end
;
3105 for (range
++ ; range
->start
!= (void *) (-1); range
++)
3107 if (range
->start
< node
->start
)
3108 node
->start
= range
->start
;
3109 if (range
->end
> node
->end
)
3110 node
->end
= range
->end
;
3113 node
->next
= exception_table_list
;
3114 exception_table_list
= node
;
3119 __throw_type_match (void *catch_type
, void *throw_type
, void *obj
)
3122 printf ("__throw_type_match (): catch_type = %s, throw_type = %s\n",
3123 catch_type
, throw_type
);
3125 if (strcmp ((const char *)catch_type
, (const char *)throw_type
) == 0)
3130 /* Throw stub routine.
3132 This is work in progress, but not completed yet. */
3140 /* This value identifies the place from which an exception is being
3152 __unwind_function(void *ptr
)
3154 asm("movl 8(%esp),%ecx");
3155 /* Undo current frame */
3156 asm("movl %ebp,%esp");
3158 /* like ret, but stay here */
3159 asm("addl $4,%esp");
3161 /* Now, undo previous frame. */
3162 /* This is a test routine, as we have to dynamically probe to find out
3163 what to pop for certain, this is just a guess. */
3164 asm("leal -16(%ebp),%esp");
3168 asm("movl %ebp,%esp");
3171 asm("movl %ecx,0(%esp)");
3174 #elif #machine(rs6000) && !defined _ARCH_PPC
3175 __unwind_function(void *ptr
)
3184 /* use 31 as a scratch register to restore the link register. */
3185 asm("l 31, 8(1);mtlr 31 # l lr,8(1)");
3188 asm("mtctr 3;bctr # b 3");
3190 #elif (#machine(rs6000) || #machine(powerpc)) && defined _ARCH_PPC
3191 __unwind_function(void *ptr
)
3195 asm("lwz 31,-4(1)");
3200 /* use 31 as a scratch register to restore the link register. */
3201 asm("lwz 31, 8(1);mtlr 31 # l lr,8(1)");
3202 asm("lwz 31,-4(1)");
3204 asm("mtctr 3;bctr # b 3");
3207 __unwind_function(void *ptr
)
3209 __label__ return_again
;
3211 /* Replace our frame's return address with the label below.
3212 During execution, we will first return here instead of to
3213 caller, then second return takes caller's frame off the stack.
3214 Two returns matches two actual calls, so is less likely to
3215 confuse debuggers. `16' corresponds to RETURN_ADDRESS_OFFSET. */
3216 __asm ("movl %0,16(fp)" : : "p" (&& return_again
));
3223 __unwind_function(void *ptr
)
3227 #endif /* powerpc */
3231 #ifndef inhibit_libc
3232 /* This gets us __GNU_LIBRARY__. */
3233 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
3236 #ifdef __GNU_LIBRARY__
3237 /* Avoid forcing the library's meaning of `write' on the user program
3238 by using the "internal" name (for use within the library) */
3239 #define write(fd, buf, n) __write((fd), (buf), (n))
3241 #endif /* inhibit_libc */
3243 #define MESSAGE "pure virtual method called\n"
3248 #ifndef inhibit_libc
3249 write (2, MESSAGE
, sizeof (MESSAGE
) - 1);