]>
gcc.gnu.org Git - gcc.git/blob - gcc/libgcc2.c
1 /* More subroutines needed by GCC output code on some machines. */
2 /* Compile this one with gcc. */
3 /* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 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)
121 #include "longlong.h"
123 #endif /* udiv or mul */
125 extern DItype
__fixunssfdi (SFtype a
);
126 extern DItype
__fixunsdfdi (DFtype a
);
127 #if LONG_DOUBLE_TYPE_SIZE == 96
128 extern DItype
__fixunsxfdi (XFtype a
);
130 #if LONG_DOUBLE_TYPE_SIZE == 128
131 extern DItype
__fixunstfdi (TFtype a
);
134 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
135 #if defined (L_divdi3) || defined (L_moddi3)
148 w
.s
.high
= -uu
.s
.high
- ((USItype
) w
.s
.low
> 0);
169 bm
= (sizeof (SItype
) * BITS_PER_UNIT
) - b
;
173 w
.s
.low
= (USItype
)uu
.s
.high
>> -bm
;
177 USItype carries
= (USItype
)uu
.s
.high
<< bm
;
178 w
.s
.high
= (USItype
)uu
.s
.high
>> b
;
179 w
.s
.low
= ((USItype
)uu
.s
.low
>> b
) | carries
;
201 bm
= (sizeof (SItype
) * BITS_PER_UNIT
) - b
;
205 w
.s
.high
= (USItype
)uu
.s
.low
<< -bm
;
209 USItype carries
= (USItype
)uu
.s
.low
>> bm
;
210 w
.s
.low
= (USItype
)uu
.s
.low
<< b
;
211 w
.s
.high
= ((USItype
)uu
.s
.high
<< b
) | carries
;
233 bm
= (sizeof (SItype
) * BITS_PER_UNIT
) - b
;
236 /* w.s.high = 1..1 or 0..0 */
237 w
.s
.high
= uu
.s
.high
>> (sizeof (SItype
) * BITS_PER_UNIT
- 1);
238 w
.s
.low
= uu
.s
.high
>> -bm
;
242 USItype carries
= (USItype
)uu
.s
.high
<< bm
;
243 w
.s
.high
= uu
.s
.high
>> b
;
244 w
.s
.low
= ((USItype
)uu
.s
.low
>> b
) | carries
;
259 w
.s
.low
= ffs (uu
.s
.low
);
262 w
.s
.low
= ffs (uu
.s
.high
);
265 w
.s
.low
+= BITS_PER_UNIT
* sizeof (SItype
);
283 w
.ll
= __umulsidi3 (uu
.s
.low
, vv
.s
.low
);
284 w
.s
.high
+= ((USItype
) uu
.s
.low
* (USItype
) vv
.s
.high
285 + (USItype
) uu
.s
.high
* (USItype
) vv
.s
.low
);
293 __udiv_w_sdiv (rp
, a1
, a0
, d
)
294 USItype
*rp
, a1
, a0
, d
;
301 if (a1
< d
- a1
- (a0
>> (SI_TYPE_SIZE
- 1)))
303 /* dividend, divisor, and quotient are nonnegative */
304 sdiv_qrnnd (q
, r
, a1
, a0
, d
);
308 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
309 sub_ddmmss (c1
, c0
, a1
, a0
, d
>> 1, d
<< (SI_TYPE_SIZE
- 1));
310 /* Divide (c1*2^32 + c0) by d */
311 sdiv_qrnnd (q
, r
, c1
, c0
, d
);
312 /* Add 2^31 to quotient */
313 q
+= (USItype
) 1 << (SI_TYPE_SIZE
- 1);
318 b1
= d
>> 1; /* d/2, between 2^30 and 2^31 - 1 */
319 c1
= a1
>> 1; /* A/2 */
320 c0
= (a1
<< (SI_TYPE_SIZE
- 1)) + (a0
>> 1);
322 if (a1
< b1
) /* A < 2^32*b1, so A/2 < 2^31*b1 */
324 sdiv_qrnnd (q
, r
, c1
, c0
, b1
); /* (A/2) / (d/2) */
326 r
= 2*r
+ (a0
& 1); /* Remainder from A/(2*b1) */
343 else if (c1
< b1
) /* So 2^31 <= (A/2)/b1 < 2^32 */
346 c0
= ~c0
; /* logical NOT */
348 sdiv_qrnnd (q
, r
, c1
, c0
, b1
); /* (A/2) / (d/2) */
350 q
= ~q
; /* (A/2)/b1 */
353 r
= 2*r
+ (a0
& 1); /* A/(2*b1) */
371 else /* Implies c1 = b1 */
372 { /* Hence a1 = d - 1 = 2*b1 - 1 */
392 static const UQItype __clz_tab
[] =
394 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,
395 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,
396 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
397 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,
398 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
399 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
400 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
401 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 __udivmoddi4 (n
, d
, rp
)
412 USItype d0
, d1
, n0
, n1
, n2
;
424 #if !UDIV_NEEDS_NORMALIZATION
431 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
434 /* Remainder in n0. */
441 d0
= 1 / d0
; /* Divide intentionally by zero. */
443 udiv_qrnnd (q1
, n1
, 0, n1
, d0
);
444 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
446 /* Remainder in n0. */
457 #else /* UDIV_NEEDS_NORMALIZATION */
465 count_leading_zeros (bm
, d0
);
469 /* Normalize, i.e. make the most significant bit of the
473 n1
= (n1
<< bm
) | (n0
>> (SI_TYPE_SIZE
- bm
));
477 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
480 /* Remainder in n0 >> bm. */
487 d0
= 1 / d0
; /* Divide intentionally by zero. */
489 count_leading_zeros (bm
, d0
);
493 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
494 conclude (the most significant bit of n1 is set) /\ (the
495 leading quotient digit q1 = 1).
497 This special case is necessary, not an optimization.
498 (Shifts counts of SI_TYPE_SIZE are undefined.) */
507 b
= SI_TYPE_SIZE
- bm
;
511 n1
= (n1
<< bm
) | (n0
>> b
);
514 udiv_qrnnd (q1
, n1
, n2
, n1
, d0
);
519 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
521 /* Remainder in n0 >> bm. */
531 #endif /* UDIV_NEEDS_NORMALIZATION */
542 /* Remainder in n1n0. */
554 count_leading_zeros (bm
, d1
);
557 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
558 conclude (the most significant bit of n1 is set) /\ (the
559 quotient digit q0 = 0 or 1).
561 This special case is necessary, not an optimization. */
563 /* The condition on the next line takes advantage of that
564 n1 >= d1 (true due to program flow). */
565 if (n1
> d1
|| n0
>= d0
)
568 sub_ddmmss (n1
, n0
, n1
, n0
, d1
, d0
);
587 b
= SI_TYPE_SIZE
- bm
;
589 d1
= (d1
<< bm
) | (d0
>> b
);
592 n1
= (n1
<< bm
) | (n0
>> b
);
595 udiv_qrnnd (q0
, n1
, n2
, n1
, d1
);
596 umul_ppmm (m1
, m0
, q0
, d0
);
598 if (m1
> n1
|| (m1
== n1
&& m0
> n0
))
601 sub_ddmmss (m1
, m0
, m1
, m0
, d1
, d0
);
606 /* Remainder in (n1n0 - m1m0) >> bm. */
609 sub_ddmmss (n1
, n0
, n1
, n0
, m1
, m0
);
610 rr
.s
.low
= (n1
<< b
) | (n0
>> bm
);
611 rr
.s
.high
= n1
>> bm
;
625 UDItype
__udivmoddi4 ();
640 uu
.ll
= __negdi2 (uu
.ll
);
643 vv
.ll
= __negdi2 (vv
.ll
);
645 w
= __udivmoddi4 (uu
.ll
, vv
.ll
, (UDItype
*) 0);
654 UDItype
__udivmoddi4 ();
668 uu
.ll
= __negdi2 (uu
.ll
);
670 vv
.ll
= __negdi2 (vv
.ll
);
672 (void) __udivmoddi4 (uu
.ll
, vv
.ll
, &w
);
681 UDItype
__udivmoddi4 ();
688 (void) __udivmoddi4 (u
, v
, &w
);
695 UDItype
__udivmoddi4 ();
700 return __udivmoddi4 (n
, d
, (UDItype
*) 0);
711 au
.ll
= a
, bu
.ll
= b
;
713 if (au
.s
.high
< bu
.s
.high
)
715 else if (au
.s
.high
> bu
.s
.high
)
717 if ((USItype
) au
.s
.low
< (USItype
) bu
.s
.low
)
719 else if ((USItype
) au
.s
.low
> (USItype
) bu
.s
.low
)
732 au
.ll
= a
, bu
.ll
= b
;
734 if ((USItype
) au
.s
.high
< (USItype
) bu
.s
.high
)
736 else if ((USItype
) au
.s
.high
> (USItype
) bu
.s
.high
)
738 if ((USItype
) au
.s
.low
< (USItype
) bu
.s
.low
)
740 else if ((USItype
) au
.s
.low
> (USItype
) bu
.s
.low
)
746 #if defined(L_fixunstfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
747 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
748 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
760 /* Compute high word of result, as a flonum. */
761 b
= (a
/ HIGH_WORD_COEFF
);
762 /* Convert that to fixed (but not to DItype!),
763 and shift it into the high word. */
766 /* Remove high part from the TFtype, leaving the low part as flonum. */
768 /* Convert that to fixed (but not to DItype!) and add it in.
769 Sometimes A comes out negative. This is significant, since
770 A has more bits than a long int does. */
772 v
-= (USItype
) (- a
);
779 #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)
804 /* Compute high word of result, as a flonum. */
805 b
= (a
/ HIGH_WORD_COEFF
);
806 /* Convert that to fixed (but not to DItype!),
807 and shift it into the high word. */
810 /* Remove high part from the XFtype, leaving the low part as flonum. */
812 /* Convert that to fixed (but not to DItype!) and add it in.
813 Sometimes A comes out negative. This is significant, since
814 A has more bits than a long int does. */
816 v
-= (USItype
) (- a
);
823 #if defined(L_fixxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
829 return - __fixunsxfdi (-a
);
830 return __fixunsxfdi (a
);
835 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
836 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
848 /* Compute high word of result, as a flonum. */
849 b
= (a
/ HIGH_WORD_COEFF
);
850 /* Convert that to fixed (but not to DItype!),
851 and shift it into the high word. */
854 /* Remove high part from the DFtype, leaving the low part as flonum. */
856 /* Convert that to fixed (but not to DItype!) and add it in.
857 Sometimes A comes out negative. This is significant, since
858 A has more bits than a long int does. */
860 v
-= (USItype
) (- a
);
873 return - __fixunsdfdi (-a
);
874 return __fixunsdfdi (a
);
879 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
880 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
883 __fixunssfdi (SFtype original_a
)
885 /* Convert the SFtype to a DFtype, because that is surely not going
886 to lose any bits. Some day someone else can write a faster version
887 that avoids converting to DFtype, and verify it really works right. */
888 DFtype a
= original_a
;
895 /* Compute high word of result, as a flonum. */
896 b
= (a
/ HIGH_WORD_COEFF
);
897 /* Convert that to fixed (but not to DItype!),
898 and shift it into the high word. */
901 /* Remove high part from the DFtype, leaving the low part as flonum. */
903 /* Convert that to fixed (but not to DItype!) and add it in.
904 Sometimes A comes out negative. This is significant, since
905 A has more bits than a long int does. */
907 v
-= (USItype
) (- a
);
919 return - __fixunssfdi (-a
);
920 return __fixunssfdi (a
);
924 #if defined(L_floatdixf) && (LONG_DOUBLE_TYPE_SIZE == 96)
925 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
926 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
927 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
939 d
= (USItype
) (u
>> WORD_SIZE
);
940 d
*= HIGH_HALFWORD_COEFF
;
941 d
*= HIGH_HALFWORD_COEFF
;
942 d
+= (USItype
) (u
& (HIGH_WORD_COEFF
- 1));
944 return (negate
? -d
: d
);
948 #if defined(L_floatditf) && (LONG_DOUBLE_TYPE_SIZE == 128)
949 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
950 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
951 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
963 d
= (USItype
) (u
>> WORD_SIZE
);
964 d
*= HIGH_HALFWORD_COEFF
;
965 d
*= HIGH_HALFWORD_COEFF
;
966 d
+= (USItype
) (u
& (HIGH_WORD_COEFF
- 1));
968 return (negate
? -d
: d
);
973 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
974 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
975 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
987 d
= (USItype
) (u
>> WORD_SIZE
);
988 d
*= HIGH_HALFWORD_COEFF
;
989 d
*= HIGH_HALFWORD_COEFF
;
990 d
+= (USItype
) (u
& (HIGH_WORD_COEFF
- 1));
992 return (negate
? -d
: d
);
997 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
998 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
999 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
1000 #define DI_SIZE (sizeof (DItype) * BITS_PER_UNIT)
1002 /* Define codes for all the float formats that we know of. Note
1003 that this is copied from real.h. */
1005 #define UNKNOWN_FLOAT_FORMAT 0
1006 #define IEEE_FLOAT_FORMAT 1
1007 #define VAX_FLOAT_FORMAT 2
1008 #define IBM_FLOAT_FORMAT 3
1010 /* Default to IEEE float if not specified. Nearly all machines use it. */
1011 #ifndef HOST_FLOAT_FORMAT
1012 #define HOST_FLOAT_FORMAT IEEE_FLOAT_FORMAT
1015 #if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1020 #if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
1025 #if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
1034 /* Do the calculation in DFmode
1035 so that we don't lose any of the precision of the high word
1036 while multiplying it. */
1043 /* Protect against double-rounding error.
1044 Represent any low-order bits, that might be truncated in DFmode,
1045 by a bit that won't be lost. The bit can go in anywhere below the
1046 rounding position of the SFmode. A fixed mask and bit position
1047 handles all usual configurations. It doesn't handle the case
1048 of 128-bit DImode, however. */
1049 if (DF_SIZE
< DI_SIZE
1050 && DF_SIZE
> (DI_SIZE
- DF_SIZE
+ SF_SIZE
))
1052 #define REP_BIT ((USItype) 1 << (DI_SIZE - DF_SIZE))
1053 if (u
>= ((UDItype
) 1 << DF_SIZE
))
1055 if ((USItype
) u
& (REP_BIT
- 1))
1059 f
= (USItype
) (u
>> WORD_SIZE
);
1060 f
*= HIGH_HALFWORD_COEFF
;
1061 f
*= HIGH_HALFWORD_COEFF
;
1062 f
+= (USItype
) (u
& (HIGH_WORD_COEFF
- 1));
1064 return (SFtype
) (negate
? -f
: f
);
1068 #if defined(L_fixunsxfsi) && LONG_DOUBLE_TYPE_SIZE == 96
1069 /* Reenable the normal types, in case limits.h needs them. */
1083 if (a
>= - (DFtype
) LONG_MIN
)
1084 return (SItype
) (a
+ LONG_MIN
) - LONG_MIN
;
1090 /* 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. */
1122 __fixunssfsi (SFtype a
)
1124 if (a
>= - (SFtype
) LONG_MIN
)
1125 return (SItype
) (a
+ LONG_MIN
) - LONG_MIN
;
1130 /* From here on down, the routines use normal data types. */
1132 #define SItype bogus_type
1133 #define USItype bogus_type
1134 #define DItype bogus_type
1135 #define UDItype bogus_type
1136 #define SFtype bogus_type
1137 #define DFtype bogus_type
1149 /* Like bcmp except the sign is meaningful.
1150 Result is negative if S1 is less than S2,
1151 positive if S1 is greater, 0 if S1 and S2 are equal. */
1154 __gcc_bcmp (s1
, s2
, size
)
1155 unsigned char *s1
, *s2
;
1160 unsigned char c1
= *s1
++, c2
= *s2
++;
1172 #if defined(__svr4__) || defined(__alliant__)
1176 /* The Alliant needs the added underscore. */
1177 asm (".globl __builtin_saveregs");
1178 asm ("__builtin_saveregs:");
1179 asm (".globl ___builtin_saveregs");
1180 asm ("___builtin_saveregs:");
1182 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
1183 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
1184 area and also for a new va_list
1186 /* Save all argument registers in the arg reg save area. The
1187 arg reg save area must have the following layout (according
1199 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
1200 asm (" fst.q %f12,16(%sp)");
1202 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
1203 asm (" st.l %r17,36(%sp)");
1204 asm (" st.l %r18,40(%sp)");
1205 asm (" st.l %r19,44(%sp)");
1206 asm (" st.l %r20,48(%sp)");
1207 asm (" st.l %r21,52(%sp)");
1208 asm (" st.l %r22,56(%sp)");
1209 asm (" st.l %r23,60(%sp)");
1210 asm (" st.l %r24,64(%sp)");
1211 asm (" st.l %r25,68(%sp)");
1212 asm (" st.l %r26,72(%sp)");
1213 asm (" st.l %r27,76(%sp)");
1215 asm (" adds 80,%sp,%r16"); /* compute the address of the new
1216 va_list structure. Put in into
1217 r16 so that it will be returned
1220 /* Initialize all fields of the new va_list structure. This
1221 structure looks like:
1224 unsigned long ireg_used;
1225 unsigned long freg_used;
1231 asm (" st.l %r0, 0(%r16)"); /* nfixed */
1232 asm (" st.l %r0, 4(%r16)"); /* nfloating */
1233 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
1234 asm (" bri %r1"); /* delayed return */
1235 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
1237 #else /* not __svr4__ */
1238 #if defined(__PARAGON__)
1240 * we'll use SVR4-ish varargs but need SVR3.2 assembler syntax,
1241 * and we stand a better chance of hooking into libraries
1242 * compiled by PGI. [andyp@ssd.intel.com]
1246 asm (".globl __builtin_saveregs");
1247 asm ("__builtin_saveregs:");
1248 asm (".globl ___builtin_saveregs");
1249 asm ("___builtin_saveregs:");
1251 asm (" andnot 0x0f,sp,sp"); /* round down to 16-byte boundary */
1252 asm (" adds -96,sp,sp"); /* allocate stack space for reg save
1253 area and also for a new va_list
1255 /* Save all argument registers in the arg reg save area. The
1256 arg reg save area must have the following layout (according
1268 asm (" fst.q f8, 0(sp)");
1269 asm (" fst.q f12,16(sp)");
1270 asm (" st.l r16,32(sp)");
1271 asm (" st.l r17,36(sp)");
1272 asm (" st.l r18,40(sp)");
1273 asm (" st.l r19,44(sp)");
1274 asm (" st.l r20,48(sp)");
1275 asm (" st.l r21,52(sp)");
1276 asm (" st.l r22,56(sp)");
1277 asm (" st.l r23,60(sp)");
1278 asm (" st.l r24,64(sp)");
1279 asm (" st.l r25,68(sp)");
1280 asm (" st.l r26,72(sp)");
1281 asm (" st.l r27,76(sp)");
1283 asm (" adds 80,sp,r16"); /* compute the address of the new
1284 va_list structure. Put in into
1285 r16 so that it will be returned
1288 /* Initialize all fields of the new va_list structure. This
1289 structure looks like:
1292 unsigned long ireg_used;
1293 unsigned long freg_used;
1299 asm (" st.l r0, 0(r16)"); /* nfixed */
1300 asm (" st.l r0, 4(r16)"); /* nfloating */
1301 asm (" st.l sp, 8(r16)"); /* __va_ctl points to __va_struct. */
1302 asm (" bri r1"); /* delayed return */
1303 asm (" st.l r28,12(r16)"); /* pointer to overflow args */
1304 #else /* not __PARAGON__ */
1308 asm (".globl ___builtin_saveregs");
1309 asm ("___builtin_saveregs:");
1310 asm (" mov sp,r30");
1311 asm (" andnot 0x0f,sp,sp");
1312 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
1314 /* Fill in the __va_struct. */
1315 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
1316 asm (" st.l r17, 4(sp)"); /* int fixed[12] */
1317 asm (" st.l r18, 8(sp)");
1318 asm (" st.l r19,12(sp)");
1319 asm (" st.l r20,16(sp)");
1320 asm (" st.l r21,20(sp)");
1321 asm (" st.l r22,24(sp)");
1322 asm (" st.l r23,28(sp)");
1323 asm (" st.l r24,32(sp)");
1324 asm (" st.l r25,36(sp)");
1325 asm (" st.l r26,40(sp)");
1326 asm (" st.l r27,44(sp)");
1328 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
1329 asm (" fst.q f12,64(sp)"); /* int floating[8] */
1331 /* Fill in the __va_ctl. */
1332 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
1333 asm (" st.l r28,84(sp)"); /* pointer to more args */
1334 asm (" st.l r0, 88(sp)"); /* nfixed */
1335 asm (" st.l r0, 92(sp)"); /* nfloating */
1337 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
1339 asm (" mov r30,sp");
1340 /* recover stack and pass address to start
1342 #endif /* not __PARAGON__ */
1343 #endif /* not __svr4__ */
1344 #else /* not __i860__ */
1346 asm (".global __builtin_saveregs");
1347 asm ("__builtin_saveregs:");
1348 asm (".global ___builtin_saveregs");
1349 asm ("___builtin_saveregs:");
1350 #ifdef NEED_PROC_COMMAND
1353 asm ("st %i0,[%fp+68]");
1354 asm ("st %i1,[%fp+72]");
1355 asm ("st %i2,[%fp+76]");
1356 asm ("st %i3,[%fp+80]");
1357 asm ("st %i4,[%fp+84]");
1359 asm ("st %i5,[%fp+88]");
1360 #ifdef NEED_TYPE_COMMAND
1361 asm (".type __builtin_saveregs,#function");
1362 asm (".size __builtin_saveregs,.-__builtin_saveregs");
1364 #else /* not __sparc__ */
1365 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1368 asm (" .ent __builtin_saveregs");
1369 asm (" .globl __builtin_saveregs");
1370 asm ("__builtin_saveregs:");
1371 asm (" sw $4,0($30)");
1372 asm (" sw $5,4($30)");
1373 asm (" sw $6,8($30)");
1374 asm (" sw $7,12($30)");
1376 asm (" .end __builtin_saveregs");
1377 #else /* not __mips__, etc. */
1380 __builtin_saveregs ()
1385 #endif /* not __mips__ */
1386 #endif /* not __sparc__ */
1387 #endif /* not __i860__ */
1391 #ifndef inhibit_libc
1393 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1395 /* This is used by the `assert' macro. */
1397 __eprintf (string
, expression
, line
, filename
)
1399 const char *expression
;
1401 const char *filename
;
1403 fprintf (stderr
, string
, expression
, line
, filename
);
1413 /* Structure emitted by -a */
1417 const char *filename
;
1421 const unsigned long *addresses
;
1423 /* Older GCC's did not emit these fields. */
1425 const char **functions
;
1426 const long *line_nums
;
1427 const char **filenames
;
1430 #ifdef BLOCK_PROFILER_CODE
1433 #ifndef inhibit_libc
1435 /* Simple minded basic block profiling output dumper for
1436 systems that don't provide tcov support. At present,
1437 it requires atexit and stdio. */
1439 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1445 extern int atexit (void (*) (void));
1447 extern void atexit (void (*) (void));
1449 #define ON_EXIT(FUNC,ARG) atexit ((FUNC))
1452 extern void on_exit (void*, void*);
1453 #define ON_EXIT(FUNC,ARG) on_exit ((FUNC), (ARG))
1457 static struct bb
*bb_head
;
1459 /* Return the number of digits needed to print a value */
1460 /* __inline__ */ static int num_digits (long value
, int base
)
1462 int minus
= (value
< 0 && base
!= 16);
1463 unsigned long v
= (minus
) ? -value
: value
;
1477 __bb_exit_func (void)
1479 FILE *file
= fopen ("bb.out", "a");
1489 /* This is somewhat type incorrect, but it avoids worrying about
1490 exactly where time.h is included from. It should be ok unless
1491 a void * differs from other pointer formats, or if sizeof(long)
1492 is < sizeof (time_t). It would be nice if we could assume the
1493 use of rationale standards here. */
1495 time((void *) &time_value
);
1496 fprintf (file
, "Basic block profiling finished on %s\n", ctime ((void *) &time_value
));
1498 /* We check the length field explicitly in order to allow compatibility
1499 with older GCC's which did not provide it. */
1501 for (ptr
= bb_head
; ptr
!= (struct bb
*)0; ptr
= ptr
->next
)
1504 int func_p
= (ptr
->nwords
>= sizeof (struct bb
) && ptr
->nwords
<= 1000);
1505 int line_p
= (func_p
&& ptr
->line_nums
);
1506 int file_p
= (func_p
&& ptr
->filenames
);
1507 long ncounts
= ptr
->ncounts
;
1513 int blk_len
= num_digits (ncounts
, 10);
1518 fprintf (file
, "File %s, %ld basic blocks \n\n",
1519 ptr
->filename
, ncounts
);
1521 /* Get max values for each field. */
1522 for (i
= 0; i
< ncounts
; i
++)
1527 if (cnt_max
< ptr
->counts
[i
])
1528 cnt_max
= ptr
->counts
[i
];
1530 if (addr_max
< ptr
->addresses
[i
])
1531 addr_max
= ptr
->addresses
[i
];
1533 if (line_p
&& line_max
< ptr
->line_nums
[i
])
1534 line_max
= ptr
->line_nums
[i
];
1538 p
= (ptr
->functions
[i
]) ? (ptr
->functions
[i
]) : "<none>";
1546 p
= (ptr
->filenames
[i
]) ? (ptr
->filenames
[i
]) : "<none>";
1553 addr_len
= num_digits (addr_max
, 16);
1554 cnt_len
= num_digits (cnt_max
, 10);
1555 line_len
= num_digits (line_max
, 10);
1557 /* Now print out the basic block information. */
1558 for (i
= 0; i
< ncounts
; i
++)
1561 " Block #%*d: executed %*ld time(s) address= 0x%.*lx",
1563 cnt_len
, ptr
->counts
[i
],
1564 addr_len
, ptr
->addresses
[i
]);
1567 fprintf (file
, " function= %-*s", func_len
,
1568 (ptr
->functions
[i
]) ? ptr
->functions
[i
] : "<none>");
1571 fprintf (file
, " line= %*ld", line_len
, ptr
->line_nums
[i
]);
1574 fprintf (file
, " file= %s",
1575 (ptr
->filenames
[i
]) ? ptr
->filenames
[i
] : "<none>");
1577 fprintf (file
, "\n");
1580 fprintf (file
, "\n");
1584 fprintf (file
, "\n\n");
1590 __bb_init_func (struct bb
*blocks
)
1592 /* User is supposed to check whether the first word is non-0,
1593 but just in case.... */
1595 if (blocks
->zero_word
)
1599 /* Initialize destructor. */
1601 ON_EXIT (__bb_exit_func
, 0);
1604 /* Set up linked list. */
1605 blocks
->zero_word
= 1;
1606 blocks
->next
= bb_head
;
1610 #endif /* not inhibit_libc */
1611 #endif /* not BLOCK_PROFILER_CODE */
1614 /* Default free-store management functions for C++, per sections 12.5 and
1615 17.3.3 of the Working Paper. */
1618 /* operator new (size_t), described in 17.3.3.5. This function is used by
1619 C++ programs to allocate a block of memory to hold a single object. */
1621 typedef void (*vfp
)(void);
1622 extern vfp __new_handler
;
1623 extern void __default_new_handler (void);
1626 void * __builtin_new (size_t sz
)
1627 __attribute__ ((weak
, alias ("___builtin_new")));
1629 ___builtin_new (size_t sz
)
1632 __builtin_new (size_t sz
)
1636 vfp handler
= (__new_handler
) ? __new_handler
: __default_new_handler
;
1638 /* malloc (0) is unpredictable; avoid it. */
1641 p
= (void *) malloc (sz
);
1645 p
= (void *) malloc (sz
);
1650 #endif /* L_op_new */
1653 /* void * operator new [] (size_t), described in 17.3.3.6. This function
1654 is used by C++ programs to allocate a block of memory for an array. */
1656 extern void * __builtin_new (size_t);
1659 void * __builtin_vec_new (size_t sz
)
1660 __attribute__ ((weak
, alias ("___builtin_vec_new")));
1662 ___builtin_vec_new (size_t sz
)
1665 __builtin_vec_new (size_t sz
)
1668 return __builtin_new (sz
);
1670 #endif /* L_op_vnew */
1672 #ifdef L_new_handler
1673 /* set_new_handler (fvoid_t *) and the default new handler, described in
1674 17.3.3.2 and 17.3.3.5. These functions define the result of a failure
1675 to allocate the amount of memory requested from operator new or new []. */
1677 #ifndef inhibit_libc
1678 /* This gets us __GNU_LIBRARY__. */
1679 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1682 #ifdef __GNU_LIBRARY__
1683 /* Avoid forcing the library's meaning of `write' on the user program
1684 by using the "internal" name (for use within the library) */
1685 #define write(fd, buf, n) __write((fd), (buf), (n))
1687 #endif /* inhibit_libc */
1689 typedef void (*vfp
)(void);
1690 void __default_new_handler (void);
1692 vfp __new_handler
= (vfp
)0;
1695 set_new_handler (vfp handler
)
1699 prev_handler
= __new_handler
;
1700 if (handler
== 0) handler
= __default_new_handler
;
1701 __new_handler
= handler
;
1702 return prev_handler
;
1705 #define MESSAGE "Virtual memory exceeded in `new'\n"
1708 __default_new_handler ()
1710 #ifndef inhibit_libc
1711 /* don't use fprintf (stderr, ...) because it may need to call malloc. */
1712 /* This should really print the name of the program, but that is hard to
1713 do. We need a standard, clean way to get at the name. */
1714 write (2, MESSAGE
, sizeof (MESSAGE
));
1716 /* don't call exit () because that may call global destructors which
1717 may cause a loop. */
1723 /* operator delete (void *), described in 17.3.3.3. This function is used
1724 by C++ programs to return to the free store a block of memory allocated
1725 as a single object. */
1728 void __builtin_delete (void *ptr
)
1729 __attribute__ ((weak
, alias ("___builtin_delete")));
1731 ___builtin_delete (void *ptr
)
1734 __builtin_delete (void *ptr
)
1743 /* operator delete [] (void *), described in 17.3.3.4. This function is
1744 used by C++ programs to return to the free store a block of memory
1745 allocated as an array. */
1747 extern void __builtin_delete (void *);
1750 void __builtin_vec_delete (void *ptr
)
1751 __attribute__ ((weak
, alias ("___builtin_vec_delete")));
1753 ___builtin_vec_delete (void *ptr
)
1756 __builtin_vec_delete (void *ptr
)
1759 __builtin_delete (ptr
);
1763 /* End of C++ free-store management functions */
1766 unsigned int __shtab
[] = {
1767 0x00000001, 0x00000002, 0x00000004, 0x00000008,
1768 0x00000010, 0x00000020, 0x00000040, 0x00000080,
1769 0x00000100, 0x00000200, 0x00000400, 0x00000800,
1770 0x00001000, 0x00002000, 0x00004000, 0x00008000,
1771 0x00010000, 0x00020000, 0x00040000, 0x00080000,
1772 0x00100000, 0x00200000, 0x00400000, 0x00800000,
1773 0x01000000, 0x02000000, 0x04000000, 0x08000000,
1774 0x10000000, 0x20000000, 0x40000000, 0x80000000
1778 #ifdef L_clear_cache
1779 /* Clear part of an instruction cache. */
1781 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1784 __clear_cache (beg
, end
)
1787 #ifdef CLEAR_INSN_CACHE
1788 CLEAR_INSN_CACHE (beg
, end
);
1790 #ifdef INSN_CACHE_SIZE
1791 static char array
[INSN_CACHE_SIZE
+ INSN_CACHE_PLANE_SIZE
+ INSN_CACHE_LINE_WIDTH
];
1792 static int initialized
;
1796 typedef (*function_ptr
) ();
1798 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1799 /* It's cheaper to clear the whole cache.
1800 Put in a series of jump instructions so that calling the beginning
1801 of the cache will clear the whole thing. */
1805 int ptr
= (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
1806 & -INSN_CACHE_LINE_WIDTH
);
1807 int end_ptr
= ptr
+ INSN_CACHE_SIZE
;
1809 while (ptr
< end_ptr
)
1811 *(INSTRUCTION_TYPE
*)ptr
1812 = JUMP_AHEAD_INSTRUCTION
+ INSN_CACHE_LINE_WIDTH
;
1813 ptr
+= INSN_CACHE_LINE_WIDTH
;
1815 *(INSTRUCTION_TYPE
*)(ptr
- INSN_CACHE_LINE_WIDTH
) = RETURN_INSTRUCTION
;
1820 /* Call the beginning of the sequence. */
1821 (((function_ptr
) (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
1822 & -INSN_CACHE_LINE_WIDTH
))
1825 #else /* Cache is large. */
1829 int ptr
= (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
1830 & -INSN_CACHE_LINE_WIDTH
);
1832 while (ptr
< (int) array
+ sizeof array
)
1834 *(INSTRUCTION_TYPE
*)ptr
= RETURN_INSTRUCTION
;
1835 ptr
+= INSN_CACHE_LINE_WIDTH
;
1841 /* Find the location in array that occupies the same cache line as BEG. */
1843 offset
= ((int) beg
& -INSN_CACHE_LINE_WIDTH
) & (INSN_CACHE_PLANE_SIZE
- 1);
1844 start_addr
= (((int) (array
+ INSN_CACHE_PLANE_SIZE
- 1)
1845 & -INSN_CACHE_PLANE_SIZE
)
1848 /* Compute the cache alignment of the place to stop clearing. */
1849 #if 0 /* This is not needed for gcc's purposes. */
1850 /* If the block to clear is bigger than a cache plane,
1851 we clear the entire cache, and OFFSET is already correct. */
1852 if (end
< beg
+ INSN_CACHE_PLANE_SIZE
)
1854 offset
= (((int) (end
+ INSN_CACHE_LINE_WIDTH
- 1)
1855 & -INSN_CACHE_LINE_WIDTH
)
1856 & (INSN_CACHE_PLANE_SIZE
- 1));
1858 #if INSN_CACHE_DEPTH > 1
1859 end_addr
= (start_addr
& -INSN_CACHE_PLANE_SIZE
) + offset
;
1860 if (end_addr
<= start_addr
)
1861 end_addr
+= INSN_CACHE_PLANE_SIZE
;
1863 for (plane
= 0; plane
< INSN_CACHE_DEPTH
; plane
++)
1865 int addr
= start_addr
+ plane
* INSN_CACHE_PLANE_SIZE
;
1866 int stop
= end_addr
+ plane
* INSN_CACHE_PLANE_SIZE
;
1868 while (addr
!= stop
)
1870 /* Call the return instruction at ADDR. */
1871 ((function_ptr
) addr
) ();
1873 addr
+= INSN_CACHE_LINE_WIDTH
;
1876 #else /* just one plane */
1879 /* Call the return instruction at START_ADDR. */
1880 ((function_ptr
) start_addr
) ();
1882 start_addr
+= INSN_CACHE_LINE_WIDTH
;
1884 while ((start_addr
% INSN_CACHE_SIZE
) != offset
);
1885 #endif /* just one plane */
1886 #endif /* Cache is large */
1887 #endif /* Cache exists */
1888 #endif /* CLEAR_INSN_CACHE */
1891 #endif /* L_clear_cache */
1895 /* Jump to a trampoline, loading the static chain address. */
1897 #ifdef TRANSFER_FROM_TRAMPOLINE
1898 TRANSFER_FROM_TRAMPOLINE
1901 #if defined (NeXT) && defined (__MACH__)
1903 /* Make stack executable so we can call trampolines on stack.
1904 This is called from INITIALIZE_TRAMPOLINE in next.h. */
1908 #include <mach/mach.h>
1912 __enable_execute_stack (addr
)
1916 char *eaddr
= addr
+ TRAMPOLINE_SIZE
;
1917 vm_address_t a
= (vm_address_t
) addr
;
1919 /* turn on execute access on stack */
1920 r
= vm_protect (task_self (), a
, TRAMPOLINE_SIZE
, FALSE
, VM_PROT_ALL
);
1921 if (r
!= KERN_SUCCESS
)
1923 mach_error("vm_protect VM_PROT_ALL", r
);
1927 /* We inline the i-cache invalidation for speed */
1929 #ifdef CLEAR_INSN_CACHE
1930 CLEAR_INSN_CACHE (addr
, eaddr
);
1932 __clear_cache ((int) addr
, (int) eaddr
);
1936 #endif /* defined (NeXT) && defined (__MACH__) */
1940 /* Make stack executable so we can call trampolines on stack.
1941 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
1943 #include <sys/mman.h>
1944 #include <sys/vmparam.h>
1945 #include <machine/machparam.h>
1948 __enable_execute_stack ()
1951 static unsigned lowest
= USRSTACK
;
1952 unsigned current
= (unsigned) &fp
& -NBPG
;
1954 if (lowest
> current
)
1956 unsigned len
= lowest
- current
;
1957 mremap (current
, &len
, PROT_READ
| PROT_WRITE
| PROT_EXEC
, MAP_PRIVATE
);
1961 /* Clear instruction cache in case an old trampoline is in it. */
1964 #endif /* __convex__ */
1968 /* Modified from the convex -code above. */
1970 #include <sys/param.h>
1972 #include <sys/m88kbcs.h>
1975 __enable_execute_stack ()
1978 static unsigned long lowest
= USRSTACK
;
1979 unsigned long current
= (unsigned long) &save_errno
& -NBPC
;
1981 /* Ignore errno being set. memctl sets errno to EINVAL whenever the
1982 address is seen as 'negative'. That is the case with the stack. */
1985 if (lowest
> current
)
1987 unsigned len
=lowest
-current
;
1988 memctl(current
,len
,MCT_TEXT
);
1992 memctl(current
,NBPC
,MCT_TEXT
);
1996 #endif /* __DOLPHIN__ */
2000 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2002 #include <sys/mman.h>
2003 #include <sys/types.h>
2004 #include <sys/param.h>
2005 #include <sys/vmmac.h>
2007 /* Modified from the convex -code above.
2008 mremap promises to clear the i-cache. */
2011 __enable_execute_stack ()
2014 if (mprotect (((unsigned int)&fp
/PAGSIZ
)*PAGSIZ
, PAGSIZ
,
2015 PROT_READ
|PROT_WRITE
|PROT_EXEC
))
2017 perror ("mprotect in __enable_execute_stack");
2022 #endif /* __pyr__ */
2023 #endif /* L_trampoline */
2027 #include "gbl-ctors.h"
2028 /* Some systems use __main in a way incompatible with its use in gcc, in these
2029 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2030 give the same symbol without quotes for an alternative entry point. You
2031 must define both, or neither. */
2033 #define NAME__MAIN "__main"
2034 #define SYMBOL__MAIN __main
2037 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2038 /* Run all the global destructors on exit from the program. */
2041 __do_global_dtors ()
2043 #ifdef DO_GLOBAL_DTORS_BODY
2044 DO_GLOBAL_DTORS_BODY
;
2047 for (p
= __DTOR_LIST__
+ 1; *p
; )
2053 #ifndef INIT_SECTION_ASM_OP
2054 /* Run all the global constructors on entry to the program. */
2057 #define ON_EXIT(a, b)
2059 /* Make sure the exit routine is pulled in to define the globals as
2060 bss symbols, just in case the linker does not automatically pull
2061 bss definitions from the library. */
2063 extern int _exit_dummy_decl
;
2064 int *_exit_dummy_ref
= &_exit_dummy_decl
;
2065 #endif /* ON_EXIT */
2068 __do_global_ctors ()
2070 DO_GLOBAL_CTORS_BODY
;
2071 ON_EXIT (__do_global_dtors
, 0);
2073 #endif /* no INIT_SECTION_ASM_OP */
2075 #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
2076 /* Subroutine called automatically by `main'.
2077 Compiling a global function named `main'
2078 produces an automatic call to this function at the beginning.
2080 For many systems, this routine calls __do_global_ctors.
2081 For systems which support a .init section we use the .init section
2082 to run __do_global_ctors, so we need not do anything here. */
2087 /* Support recursive calls to `main': run initializers just once. */
2088 static int initialized
;
2092 __do_global_ctors ();
2095 #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
2097 #endif /* L__main */
2101 #include "gbl-ctors.h"
2103 /* Provide default definitions for the lists of constructors and
2104 destructors, so that we don't get linker errors. These symbols are
2105 intentionally bss symbols, so that gld and/or collect will provide
2106 the right values. */
2108 /* We declare the lists here with two elements each,
2109 so that they are valid empty lists if no other definition is loaded. */
2110 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
2112 /* After 2.3, try this definition on all systems. */
2113 func_ptr __CTOR_LIST__
[2] = {0, 0};
2114 func_ptr __DTOR_LIST__
[2] = {0, 0};
2116 func_ptr __CTOR_LIST__
[2];
2117 func_ptr __DTOR_LIST__
[2];
2119 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
2120 #endif /* L_ctors */
2124 #include "gbl-ctors.h"
2128 /* If we have no known way of registering our own __do_global_dtors
2129 routine so that it will be invoked at program exit time, then we
2130 have to define our own exit routine which will get this to happen. */
2132 extern void __do_global_dtors ();
2133 extern void _cleanup ();
2134 extern void _exit () __attribute__ ((noreturn
));
2140 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2141 __do_global_dtors ();
2152 int _exit_dummy_decl
= 0; /* prevent compiler & linker warnings */
2161 void *exception_handler
;
2164 struct exception_table_node
{
2165 exception_table
*table
;
2168 struct exception_table_node
*next
;
2171 static int except_table_pos
;
2172 static void *except_pc
;
2173 static struct exception_table_node
*exception_table_list
;
2175 static exception_table
*
2176 find_exception_table (pc
)
2179 register struct exception_table_node
*table
= exception_table_list
;
2180 for ( ; table
!= 0; table
= table
->next
)
2182 if (table
->start
<= pc
&& table
->end
> pc
)
2183 return table
->table
;
2188 /* this routine takes a pc, and the address of the exception handler associated
2189 with the closest exception table handler entry associated with that PC,
2190 or 0 if there are no table entries the PC fits in. The algorithm works
2191 something like this:
2193 while(current_entry exists) {
2194 if(current_entry.start < pc )
2195 current_entry = next_entry;
2197 if(prev_entry.start <= pc && prev_entry.end > pc) {
2198 save pointer to prev_entry;
2199 return prev_entry.exception_handler;
2206 Assuming a correctly sorted table (ascending order) this routine should
2207 return the tighest match...
2209 In the advent of a tie, we have to give the last entry, as it represents
2215 __find_first_exception_table_match(pc
)
2218 exception_table
*table
= find_exception_table (pc
);
2224 printf("find_first_exception_table_match(): pc = %x!\n",pc
);
2230 /* We can't do this yet, as we don't know that the table is sorted. */
2233 if (table
[pos
].start
> except_pc
)
2234 /* found the first table[pos].start > except_pc, so the previous
2235 entry better be the one we want! */
2237 } while(table
[pos
].exception_handler
!= (void*)-1);
2240 if (table
[pos
].start
<= except_pc
&& table
[pos
].end
> except_pc
)
2242 except_table_pos
= pos
;
2244 printf("find_first_eh_table_match(): found match: %x\n",table
[pos
].exception_handler
);
2246 return table
[pos
].exception_handler
;
2249 while (table
[++pos
].exception_handler
!= (void*)-1) {
2250 if (table
[pos
].start
<= except_pc
&& table
[pos
].end
> except_pc
)
2252 /* This can apply. Make sure it is better or as good as the previous
2254 /* The best one ends first. */
2255 if (best
== 0 || (table
[pos
].end
<= table
[best
].end
2256 /* The best one starts last. */
2257 && table
[pos
].start
>= table
[best
].start
))
2262 return table
[best
].exception_handler
;
2266 printf("find_first_eh_table_match(): else: returning NULL!\n");
2272 __throw_type_match (void *catch_type
, void *throw_type
, void* obj
)
2275 printf("__throw_type_match (): catch_type = %s, throw_type = %s\n",
2276 catch_type
, throw_type
);
2278 if (strcmp ((const char *)catch_type
, (const char *)throw_type
) == 0)
2284 __register_exceptions (exception_table
*table
)
2286 struct exception_table_node
*node
;
2287 exception_table
*range
= table
+ 1;
2289 if (range
->start
== (void*)-1)
2292 node
= (struct exception_table_node
*)
2293 malloc (sizeof (struct exception_table_node
));
2294 node
->table
= table
;
2296 /* This look can be optimized away either if the table
2297 is sorted, or if we pass in extra parameters. */
2298 node
->start
= range
->start
;
2299 node
->end
= range
->end
;
2300 for (range
++ ; range
->start
!= (void*)(-1); range
++)
2302 if (range
->start
< node
->start
)
2303 node
->start
= range
->start
;
2304 if (range
->end
> node
->end
)
2305 node
->end
= range
->end
;
2308 node
->next
= exception_table_list
;
2309 exception_table_list
= node
;
2314 __unwind_function(void *ptr
)
2316 asm("movl 8(%esp),%ecx");
2317 /* Undo current frame */
2318 asm("movl %ebp,%esp");
2320 /* like ret, but stay here */
2321 asm("addl $4,%esp");
2323 /* Now, undo previous frame. */
2324 /* This is a test routine, as we have to dynamically probe to find out
2325 what to pop for certain, this is just a guess. */
2326 asm("leal -16(%ebp),%esp");
2327 asm("pop %eax"); /* really for popl %ebx */
2328 asm("pop %eax"); /* really for popl %esi */
2329 asm("pop %eax"); /* really for popl %edi */
2330 asm("movl %ebp,%esp");
2333 asm("movl %ecx,0(%esp)");
2338 #if #machine(rs6000)
2339 __unwind_function(void *ptr
)
2348 /* use 31 as a scratch register to restore the link register. */
2349 asm("l 31, 8(1);mtlr 31 # l lr,8(1)");
2352 asm("mtctr 3;bctr # b 3");
2356 #if #machine(powerpc)
2357 __unwind_function(void *ptr
)
2361 asm("lwz 31,-4(1)");
2366 /* use 31 as a scratch register to restore the link register. */
2367 asm("lwz 31, 8(1);mtlr 31 # l lr,8(1)");
2368 asm("lwz 31,-4(1)");
2370 asm("mtctr 3;bctr # b 3");
2372 #endif /* powerpc */
2376 #ifndef inhibit_libc
2377 /* This gets us __GNU_LIBRARY__. */
2378 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2381 #ifdef __GNU_LIBRARY__
2382 /* Avoid forcing the library's meaning of `write' on the user program
2383 by using the "internal" name (for use within the library) */
2384 #define write(fd, buf, n) __write((fd), (buf), (n))
2386 #endif /* inhibit_libc */
2388 #define MESSAGE "pure virtual method called\n"
2393 #ifndef inhibit_libc
2394 write (2, MESSAGE
, sizeof (MESSAGE
) - 1);
This page took 0.140529 seconds and 5 git commands to generate.