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, 1996, 1997, 1998, 1999,
4 2000, 2001, 2002 Free Software Foundation, Inc.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
13 In addition to the permissions in the GNU General Public License, the
14 Free Software Foundation gives you unlimited permission to link the
15 compiled version of this file into combinations with other programs,
16 and to distribute those combinations without any restriction coming
17 from the use of this file. (The General Public License restrictions
18 do apply in other respects; for example, they cover modification of
19 the file, and distribution when not linked into a combine
22 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
23 WARRANTY; without even the implied warranty of MERCHANTABILITY or
24 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27 You should have received a copy of the GNU General Public License
28 along with GCC; see the file COPYING. If not, write to the Free
29 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
32 /* It is incorrect to include config.h here, because this file is being
33 compiled for the target, and hence definitions concerning only the host
38 #include "coretypes.h"
41 /* Don't use `fancy_abort' here even if config.h says to use it. */
48 #ifdef DECLARE_LIBRARY_RENAMES
49 DECLARE_LIBRARY_RENAMES
52 #if defined (L_negdi2)
62 w
.s
.high
= -uu
.s
.high
- ((UWtype
) w
.s
.low
> 0);
70 __addvsi3 (Wtype a
, Wtype b
)
76 if (b
>= 0 ? w
< a
: w
> a
)
85 __addvdi3 (DWtype a
, DWtype b
)
91 if (b
>= 0 ? w
< a
: w
> a
)
100 __subvsi3 (Wtype a
, Wtype b
)
103 return __addvsi3 (a
, (-b
));
109 if (b
>= 0 ? w
> a
: w
< a
)
119 __subvdi3 (DWtype a
, DWtype b
)
128 if (b
>= 0 ? w
> a
: w
< a
)
138 __mulvsi3 (Wtype a
, Wtype b
)
144 if (((a
>= 0) == (b
>= 0)) ? w
< 0 : w
> 0)
159 if (a
>= 0 ? w
> 0 : w
< 0)
174 if (a
>= 0 ? w
> 0 : w
< 0)
223 __mulvdi3 (DWtype u
, DWtype v
)
229 if (((u
>= 0) == (v
>= 0)) ? w
< 0 : w
> 0)
237 /* Unless shift functions are defined with full ANSI prototypes,
238 parameter b will be promoted to int if word_type is smaller than an int. */
241 __lshrdi3 (DWtype u
, word_type b
)
252 bm
= (sizeof (Wtype
) * BITS_PER_UNIT
) - b
;
256 w
.s
.low
= (UWtype
) uu
.s
.high
>> -bm
;
260 UWtype carries
= (UWtype
) uu
.s
.high
<< bm
;
262 w
.s
.high
= (UWtype
) uu
.s
.high
>> b
;
263 w
.s
.low
= ((UWtype
) uu
.s
.low
>> b
) | carries
;
272 __ashldi3 (DWtype u
, word_type b
)
283 bm
= (sizeof (Wtype
) * BITS_PER_UNIT
) - b
;
287 w
.s
.high
= (UWtype
) uu
.s
.low
<< -bm
;
291 UWtype carries
= (UWtype
) uu
.s
.low
>> bm
;
293 w
.s
.low
= (UWtype
) uu
.s
.low
<< b
;
294 w
.s
.high
= ((UWtype
) uu
.s
.high
<< b
) | carries
;
303 __ashrdi3 (DWtype u
, word_type b
)
314 bm
= (sizeof (Wtype
) * BITS_PER_UNIT
) - b
;
317 /* w.s.high = 1..1 or 0..0 */
318 w
.s
.high
= uu
.s
.high
>> (sizeof (Wtype
) * BITS_PER_UNIT
- 1);
319 w
.s
.low
= uu
.s
.high
>> -bm
;
323 UWtype carries
= (UWtype
) uu
.s
.high
<< bm
;
325 w
.s
.high
= uu
.s
.high
>> b
;
326 w
.s
.low
= ((UWtype
) uu
.s
.low
>> b
) | carries
;
338 UWtype word
, count
, add
;
342 word
= uu
.s
.low
, add
= 0;
343 else if (uu
.s
.high
!= 0)
344 word
= uu
.s
.high
, add
= BITS_PER_UNIT
* sizeof (Wtype
);
348 count_trailing_zeros (count
, word
);
349 return count
+ add
+ 1;
355 __muldi3 (DWtype u
, DWtype v
)
363 w
.ll
= __umulsidi3 (uu
.s
.low
, vv
.s
.low
);
364 w
.s
.high
+= ((UWtype
) uu
.s
.low
* (UWtype
) vv
.s
.high
365 + (UWtype
) uu
.s
.high
* (UWtype
) vv
.s
.low
);
371 #if (defined (L_udivdi3) || defined (L_divdi3) || \
372 defined (L_umoddi3) || defined (L_moddi3))
373 #if defined (sdiv_qrnnd)
374 #define L_udiv_w_sdiv
379 #if defined (sdiv_qrnnd)
380 #if (defined (L_udivdi3) || defined (L_divdi3) || \
381 defined (L_umoddi3) || defined (L_moddi3))
382 static inline __attribute__ ((__always_inline__
))
385 __udiv_w_sdiv (UWtype
*rp
, UWtype a1
, UWtype a0
, UWtype d
)
392 if (a1
< d
- a1
- (a0
>> (W_TYPE_SIZE
- 1)))
394 /* dividend, divisor, and quotient are nonnegative */
395 sdiv_qrnnd (q
, r
, a1
, a0
, d
);
399 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
400 sub_ddmmss (c1
, c0
, a1
, a0
, d
>> 1, d
<< (W_TYPE_SIZE
- 1));
401 /* Divide (c1*2^32 + c0) by d */
402 sdiv_qrnnd (q
, r
, c1
, c0
, d
);
403 /* Add 2^31 to quotient */
404 q
+= (UWtype
) 1 << (W_TYPE_SIZE
- 1);
409 b1
= d
>> 1; /* d/2, between 2^30 and 2^31 - 1 */
410 c1
= a1
>> 1; /* A/2 */
411 c0
= (a1
<< (W_TYPE_SIZE
- 1)) + (a0
>> 1);
413 if (a1
< b1
) /* A < 2^32*b1, so A/2 < 2^31*b1 */
415 sdiv_qrnnd (q
, r
, c1
, c0
, b1
); /* (A/2) / (d/2) */
417 r
= 2*r
+ (a0
& 1); /* Remainder from A/(2*b1) */
434 else if (c1
< b1
) /* So 2^31 <= (A/2)/b1 < 2^32 */
437 c0
= ~c0
; /* logical NOT */
439 sdiv_qrnnd (q
, r
, c1
, c0
, b1
); /* (A/2) / (d/2) */
441 q
= ~q
; /* (A/2)/b1 */
444 r
= 2*r
+ (a0
& 1); /* A/(2*b1) */
462 else /* Implies c1 = b1 */
463 { /* Hence a1 = d - 1 = 2*b1 - 1 */
481 /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */
483 __udiv_w_sdiv (UWtype
*rp
__attribute__ ((__unused__
)),
484 UWtype a1
__attribute__ ((__unused__
)),
485 UWtype a0
__attribute__ ((__unused__
)),
486 UWtype d
__attribute__ ((__unused__
)))
493 #if (defined (L_udivdi3) || defined (L_divdi3) || \
494 defined (L_umoddi3) || defined (L_moddi3))
499 const UQItype __clz_tab
[] =
501 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,
502 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,
503 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,
504 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,
505 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,
506 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,
507 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,
508 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,
514 #if (defined (L_udivdi3) || defined (L_divdi3) || \
515 defined (L_umoddi3) || defined (L_moddi3))
516 static inline __attribute__ ((__always_inline__
))
519 __udivmoddi4 (UDWtype n
, UDWtype d
, UDWtype
*rp
)
524 UWtype d0
, d1
, n0
, n1
, n2
;
536 #if !UDIV_NEEDS_NORMALIZATION
543 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
546 /* Remainder in n0. */
553 d0
= 1 / d0
; /* Divide intentionally by zero. */
555 udiv_qrnnd (q1
, n1
, 0, n1
, d0
);
556 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
558 /* Remainder in n0. */
569 #else /* UDIV_NEEDS_NORMALIZATION */
577 count_leading_zeros (bm
, d0
);
581 /* Normalize, i.e. make the most significant bit of the
585 n1
= (n1
<< bm
) | (n0
>> (W_TYPE_SIZE
- bm
));
589 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
592 /* Remainder in n0 >> bm. */
599 d0
= 1 / d0
; /* Divide intentionally by zero. */
601 count_leading_zeros (bm
, d0
);
605 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
606 conclude (the most significant bit of n1 is set) /\ (the
607 leading quotient digit q1 = 1).
609 This special case is necessary, not an optimization.
610 (Shifts counts of W_TYPE_SIZE are undefined.) */
619 b
= W_TYPE_SIZE
- bm
;
623 n1
= (n1
<< bm
) | (n0
>> b
);
626 udiv_qrnnd (q1
, n1
, n2
, n1
, d0
);
631 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
633 /* Remainder in n0 >> bm. */
643 #endif /* UDIV_NEEDS_NORMALIZATION */
654 /* Remainder in n1n0. */
666 count_leading_zeros (bm
, d1
);
669 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
670 conclude (the most significant bit of n1 is set) /\ (the
671 quotient digit q0 = 0 or 1).
673 This special case is necessary, not an optimization. */
675 /* The condition on the next line takes advantage of that
676 n1 >= d1 (true due to program flow). */
677 if (n1
> d1
|| n0
>= d0
)
680 sub_ddmmss (n1
, n0
, n1
, n0
, d1
, d0
);
699 b
= W_TYPE_SIZE
- bm
;
701 d1
= (d1
<< bm
) | (d0
>> b
);
704 n1
= (n1
<< bm
) | (n0
>> b
);
707 udiv_qrnnd (q0
, n1
, n2
, n1
, d1
);
708 umul_ppmm (m1
, m0
, q0
, d0
);
710 if (m1
> n1
|| (m1
== n1
&& m0
> n0
))
713 sub_ddmmss (m1
, m0
, m1
, m0
, d1
, d0
);
718 /* Remainder in (n1n0 - m1m0) >> bm. */
721 sub_ddmmss (n1
, n0
, n1
, n0
, m1
, m0
);
722 rr
.s
.low
= (n1
<< b
) | (n0
>> bm
);
723 rr
.s
.high
= n1
>> bm
;
738 __divdi3 (DWtype u
, DWtype v
)
754 w
= __udivmoddi4 (uu
.ll
, vv
.ll
, (UDWtype
*) 0);
764 __moddi3 (DWtype u
, DWtype v
)
779 (void) __udivmoddi4 (uu
.ll
, vv
.ll
, &w
);
789 __umoddi3 (UDWtype u
, UDWtype v
)
793 (void) __udivmoddi4 (u
, v
, &w
);
801 __udivdi3 (UDWtype n
, UDWtype d
)
803 return __udivmoddi4 (n
, d
, (UDWtype
*) 0);
809 __cmpdi2 (DWtype a
, DWtype b
)
813 au
.ll
= a
, bu
.ll
= b
;
815 if (au
.s
.high
< bu
.s
.high
)
817 else if (au
.s
.high
> bu
.s
.high
)
819 if ((UWtype
) au
.s
.low
< (UWtype
) bu
.s
.low
)
821 else if ((UWtype
) au
.s
.low
> (UWtype
) bu
.s
.low
)
829 __ucmpdi2 (DWtype a
, DWtype b
)
833 au
.ll
= a
, bu
.ll
= b
;
835 if ((UWtype
) au
.s
.high
< (UWtype
) bu
.s
.high
)
837 else if ((UWtype
) au
.s
.high
> (UWtype
) bu
.s
.high
)
839 if ((UWtype
) au
.s
.low
< (UWtype
) bu
.s
.low
)
841 else if ((UWtype
) au
.s
.low
> (UWtype
) bu
.s
.low
)
847 #if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
848 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
849 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
852 __fixunstfDI (TFtype a
)
860 /* Compute high word of result, as a flonum. */
861 b
= (a
/ HIGH_WORD_COEFF
);
862 /* Convert that to fixed (but not to DWtype!),
863 and shift it into the high word. */
866 /* Remove high part from the TFtype, leaving the low part as flonum. */
868 /* Convert that to fixed (but not to DWtype!) and add it in.
869 Sometimes A comes out negative. This is significant, since
870 A has more bits than a long int does. */
879 #if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
884 return - __fixunstfDI (-a
);
885 return __fixunstfDI (a
);
889 #if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
890 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
891 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
894 __fixunsxfDI (XFtype a
)
902 /* Compute high word of result, as a flonum. */
903 b
= (a
/ HIGH_WORD_COEFF
);
904 /* Convert that to fixed (but not to DWtype!),
905 and shift it into the high word. */
908 /* Remove high part from the XFtype, leaving the low part as flonum. */
910 /* Convert that to fixed (but not to DWtype!) and add it in.
911 Sometimes A comes out negative. This is significant, since
912 A has more bits than a long int does. */
921 #if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
926 return - __fixunsxfDI (-a
);
927 return __fixunsxfDI (a
);
932 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
933 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
936 __fixunsdfDI (DFtype a
)
940 /* Get high part of result. The division here will just moves the radix
941 point and will not cause any rounding. Then the conversion to integral
942 type chops result as desired. */
943 hi
= a
/ HIGH_WORD_COEFF
;
945 /* Get low part of result. Convert `hi' to floating type and scale it back,
946 then subtract this from the number being converted. This leaves the low
947 part. Convert that to integral type. */
948 lo
= (a
- ((DFtype
) hi
) * HIGH_WORD_COEFF
);
950 /* Assemble result from the two parts. */
951 return ((UDWtype
) hi
<< WORD_SIZE
) | lo
;
960 return - __fixunsdfDI (-a
);
961 return __fixunsdfDI (a
);
966 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
967 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
970 __fixunssfDI (SFtype original_a
)
972 /* Convert the SFtype to a DFtype, because that is surely not going
973 to lose any bits. Some day someone else can write a faster version
974 that avoids converting to DFtype, and verify it really works right. */
975 DFtype a
= original_a
;
978 /* Get high part of result. The division here will just moves the radix
979 point and will not cause any rounding. Then the conversion to integral
980 type chops result as desired. */
981 hi
= a
/ HIGH_WORD_COEFF
;
983 /* Get low part of result. Convert `hi' to floating type and scale it back,
984 then subtract this from the number being converted. This leaves the low
985 part. Convert that to integral type. */
986 lo
= (a
- ((DFtype
) hi
) * HIGH_WORD_COEFF
);
988 /* Assemble result from the two parts. */
989 return ((UDWtype
) hi
<< WORD_SIZE
) | lo
;
998 return - __fixunssfDI (-a
);
999 return __fixunssfDI (a
);
1003 #if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
1004 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1005 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1006 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1009 __floatdixf (DWtype u
)
1013 d
= (Wtype
) (u
>> WORD_SIZE
);
1014 d
*= HIGH_HALFWORD_COEFF
;
1015 d
*= HIGH_HALFWORD_COEFF
;
1016 d
+= (UWtype
) (u
& (HIGH_WORD_COEFF
- 1));
1022 #if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
1023 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1024 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1025 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1028 __floatditf (DWtype u
)
1032 d
= (Wtype
) (u
>> WORD_SIZE
);
1033 d
*= HIGH_HALFWORD_COEFF
;
1034 d
*= HIGH_HALFWORD_COEFF
;
1035 d
+= (UWtype
) (u
& (HIGH_WORD_COEFF
- 1));
1042 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1043 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1044 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1047 __floatdidf (DWtype u
)
1051 d
= (Wtype
) (u
>> WORD_SIZE
);
1052 d
*= HIGH_HALFWORD_COEFF
;
1053 d
*= HIGH_HALFWORD_COEFF
;
1054 d
+= (UWtype
) (u
& (HIGH_WORD_COEFF
- 1));
1061 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1062 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1063 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1065 #define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT)
1066 #define DF_SIZE DBL_MANT_DIG
1067 #define SF_SIZE FLT_MANT_DIG
1070 __floatdisf (DWtype u
)
1072 /* Do the calculation in DFmode
1073 so that we don't lose any of the precision of the high word
1074 while multiplying it. */
1077 /* Protect against double-rounding error.
1078 Represent any low-order bits, that might be truncated in DFmode,
1079 by a bit that won't be lost. The bit can go in anywhere below the
1080 rounding position of the SFmode. A fixed mask and bit position
1081 handles all usual configurations. It doesn't handle the case
1082 of 128-bit DImode, however. */
1083 if (DF_SIZE
< DI_SIZE
1084 && DF_SIZE
> (DI_SIZE
- DF_SIZE
+ SF_SIZE
))
1086 #define REP_BIT ((UDWtype) 1 << (DI_SIZE - DF_SIZE))
1087 if (! (- ((DWtype
) 1 << DF_SIZE
) < u
1088 && u
< ((DWtype
) 1 << DF_SIZE
)))
1090 if ((UDWtype
) u
& (REP_BIT
- 1))
1092 u
&= ~ (REP_BIT
- 1);
1097 f
= (Wtype
) (u
>> WORD_SIZE
);
1098 f
*= HIGH_HALFWORD_COEFF
;
1099 f
*= HIGH_HALFWORD_COEFF
;
1100 f
+= (UWtype
) (u
& (HIGH_WORD_COEFF
- 1));
1106 #if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
1107 /* Reenable the normal types, in case limits.h needs them. */
1120 __fixunsxfSI (XFtype a
)
1122 if (a
>= - (DFtype
) Wtype_MIN
)
1123 return (Wtype
) (a
+ Wtype_MIN
) - Wtype_MIN
;
1129 /* Reenable the normal types, in case limits.h needs them. */
1142 __fixunsdfSI (DFtype a
)
1144 if (a
>= - (DFtype
) Wtype_MIN
)
1145 return (Wtype
) (a
+ Wtype_MIN
) - Wtype_MIN
;
1151 /* Reenable the normal types, in case limits.h needs them. */
1164 __fixunssfSI (SFtype a
)
1166 if (a
>= - (SFtype
) Wtype_MIN
)
1167 return (Wtype
) (a
+ Wtype_MIN
) - Wtype_MIN
;
1172 /* From here on down, the routines use normal data types. */
1174 #define SItype bogus_type
1175 #define USItype bogus_type
1176 #define DItype bogus_type
1177 #define UDItype bogus_type
1178 #define SFtype bogus_type
1179 #define DFtype bogus_type
1197 /* Like bcmp except the sign is meaningful.
1198 Result is negative if S1 is less than S2,
1199 positive if S1 is greater, 0 if S1 and S2 are equal. */
1202 __gcc_bcmp (const unsigned char *s1
, const unsigned char *s2
, size_t size
)
1206 unsigned char c1
= *s1
++, c2
= *s2
++;
1216 /* __eprintf used to be used by GCC's private version of <assert.h>.
1217 We no longer provide that header, but this routine remains in libgcc.a
1218 for binary backward compatibility. Note that it is not included in
1219 the shared version of libgcc. */
1221 #ifndef inhibit_libc
1223 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1227 __eprintf (const char *string
, const char *expression
,
1228 unsigned int line
, const char *filename
)
1230 fprintf (stderr
, string
, expression
, line
, filename
);
1239 #ifdef L_clear_cache
1240 /* Clear part of an instruction cache. */
1242 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1245 __clear_cache (char *beg
__attribute__((__unused__
)),
1246 char *end
__attribute__((__unused__
)))
1248 #ifdef CLEAR_INSN_CACHE
1249 CLEAR_INSN_CACHE (beg
, end
);
1251 #ifdef INSN_CACHE_SIZE
1252 static char array
[INSN_CACHE_SIZE
+ INSN_CACHE_PLANE_SIZE
+ INSN_CACHE_LINE_WIDTH
];
1253 static int initialized
;
1257 typedef (*function_ptr
) (void);
1259 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1260 /* It's cheaper to clear the whole cache.
1261 Put in a series of jump instructions so that calling the beginning
1262 of the cache will clear the whole thing. */
1266 int ptr
= (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
1267 & -INSN_CACHE_LINE_WIDTH
);
1268 int end_ptr
= ptr
+ INSN_CACHE_SIZE
;
1270 while (ptr
< end_ptr
)
1272 *(INSTRUCTION_TYPE
*)ptr
1273 = JUMP_AHEAD_INSTRUCTION
+ INSN_CACHE_LINE_WIDTH
;
1274 ptr
+= INSN_CACHE_LINE_WIDTH
;
1276 *(INSTRUCTION_TYPE
*) (ptr
- INSN_CACHE_LINE_WIDTH
) = RETURN_INSTRUCTION
;
1281 /* Call the beginning of the sequence. */
1282 (((function_ptr
) (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
1283 & -INSN_CACHE_LINE_WIDTH
))
1286 #else /* Cache is large. */
1290 int ptr
= (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
1291 & -INSN_CACHE_LINE_WIDTH
);
1293 while (ptr
< (int) array
+ sizeof array
)
1295 *(INSTRUCTION_TYPE
*)ptr
= RETURN_INSTRUCTION
;
1296 ptr
+= INSN_CACHE_LINE_WIDTH
;
1302 /* Find the location in array that occupies the same cache line as BEG. */
1304 offset
= ((int) beg
& -INSN_CACHE_LINE_WIDTH
) & (INSN_CACHE_PLANE_SIZE
- 1);
1305 start_addr
= (((int) (array
+ INSN_CACHE_PLANE_SIZE
- 1)
1306 & -INSN_CACHE_PLANE_SIZE
)
1309 /* Compute the cache alignment of the place to stop clearing. */
1310 #if 0 /* This is not needed for gcc's purposes. */
1311 /* If the block to clear is bigger than a cache plane,
1312 we clear the entire cache, and OFFSET is already correct. */
1313 if (end
< beg
+ INSN_CACHE_PLANE_SIZE
)
1315 offset
= (((int) (end
+ INSN_CACHE_LINE_WIDTH
- 1)
1316 & -INSN_CACHE_LINE_WIDTH
)
1317 & (INSN_CACHE_PLANE_SIZE
- 1));
1319 #if INSN_CACHE_DEPTH > 1
1320 end_addr
= (start_addr
& -INSN_CACHE_PLANE_SIZE
) + offset
;
1321 if (end_addr
<= start_addr
)
1322 end_addr
+= INSN_CACHE_PLANE_SIZE
;
1324 for (plane
= 0; plane
< INSN_CACHE_DEPTH
; plane
++)
1326 int addr
= start_addr
+ plane
* INSN_CACHE_PLANE_SIZE
;
1327 int stop
= end_addr
+ plane
* INSN_CACHE_PLANE_SIZE
;
1329 while (addr
!= stop
)
1331 /* Call the return instruction at ADDR. */
1332 ((function_ptr
) addr
) ();
1334 addr
+= INSN_CACHE_LINE_WIDTH
;
1337 #else /* just one plane */
1340 /* Call the return instruction at START_ADDR. */
1341 ((function_ptr
) start_addr
) ();
1343 start_addr
+= INSN_CACHE_LINE_WIDTH
;
1345 while ((start_addr
% INSN_CACHE_SIZE
) != offset
);
1346 #endif /* just one plane */
1347 #endif /* Cache is large */
1348 #endif /* Cache exists */
1349 #endif /* CLEAR_INSN_CACHE */
1352 #endif /* L_clear_cache */
1356 /* Jump to a trampoline, loading the static chain address. */
1358 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
1371 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
1375 mprotect (char *addr
, int len
, int prot
)
1392 if (VirtualProtect (addr
, len
, np
, &op
))
1398 #endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
1400 #ifdef TRANSFER_FROM_TRAMPOLINE
1401 TRANSFER_FROM_TRAMPOLINE
1406 #include <sys/signal.h>
1409 /* Motorola forgot to put memctl.o in the libp version of libc881.a,
1410 so define it here, because we need it in __clear_insn_cache below */
1411 /* On older versions of this OS, no memctl or MCT_TEXT are defined;
1412 hence we enable this stuff only if MCT_TEXT is #define'd. */
1427 /* Clear instruction cache so we can call trampolines on stack.
1428 This is called from FINALIZE_TRAMPOLINE in mot3300.h. */
1431 __clear_insn_cache (void)
1436 /* Preserve errno, because users would be surprised to have
1437 errno changing without explicitly calling any system-call. */
1440 /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache.
1441 No need to use an address derived from _start or %sp, as 0 works also. */
1442 memctl(0, 4096, MCT_TEXT
);
1447 #endif /* __sysV68__ */
1448 #endif /* L_trampoline */
1453 #include "gbl-ctors.h"
1454 /* Some systems use __main in a way incompatible with its use in gcc, in these
1455 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
1456 give the same symbol without quotes for an alternative entry point. You
1457 must define both, or neither. */
1459 #define NAME__MAIN "__main"
1460 #define SYMBOL__MAIN __main
1463 #ifdef INIT_SECTION_ASM_OP
1464 #undef HAS_INIT_SECTION
1465 #define HAS_INIT_SECTION
1468 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
1470 /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
1471 code to run constructors. In that case, we need to handle EH here, too. */
1473 #ifdef EH_FRAME_SECTION_NAME
1474 #include "unwind-dw2-fde.h"
1475 extern unsigned char __EH_FRAME_BEGIN__
[];
1478 /* Run all the global destructors on exit from the program. */
1481 __do_global_dtors (void)
1483 #ifdef DO_GLOBAL_DTORS_BODY
1484 DO_GLOBAL_DTORS_BODY
;
1486 static func_ptr
*p
= __DTOR_LIST__
+ 1;
1493 #if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION)
1495 static int completed
= 0;
1499 __deregister_frame_info (__EH_FRAME_BEGIN__
);
1506 #ifndef HAS_INIT_SECTION
1507 /* Run all the global constructors on entry to the program. */
1510 __do_global_ctors (void)
1512 #ifdef EH_FRAME_SECTION_NAME
1514 static struct object object
;
1515 __register_frame_info (__EH_FRAME_BEGIN__
, &object
);
1518 DO_GLOBAL_CTORS_BODY
;
1519 atexit (__do_global_dtors
);
1521 #endif /* no HAS_INIT_SECTION */
1523 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
1524 /* Subroutine called automatically by `main'.
1525 Compiling a global function named `main'
1526 produces an automatic call to this function at the beginning.
1528 For many systems, this routine calls __do_global_ctors.
1529 For systems which support a .init section we use the .init section
1530 to run __do_global_ctors, so we need not do anything here. */
1535 /* Support recursive calls to `main': run initializers just once. */
1536 static int initialized
;
1540 __do_global_ctors ();
1543 #endif /* no HAS_INIT_SECTION or INVOKE__main */
1545 #endif /* L__main */
1546 #endif /* __CYGWIN__ */
1550 #include "gbl-ctors.h"
1552 /* Provide default definitions for the lists of constructors and
1553 destructors, so that we don't get linker errors. These symbols are
1554 intentionally bss symbols, so that gld and/or collect will provide
1555 the right values. */
1557 /* We declare the lists here with two elements each,
1558 so that they are valid empty lists if no other definition is loaded.
1560 If we are using the old "set" extensions to have the gnu linker
1561 collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
1562 must be in the bss/common section.
1564 Long term no port should use those extensions. But many still do. */
1565 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
1566 #if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2)
1567 func_ptr __CTOR_LIST__
[2] = {0, 0};
1568 func_ptr __DTOR_LIST__
[2] = {0, 0};
1570 func_ptr __CTOR_LIST__
[2];
1571 func_ptr __DTOR_LIST__
[2];
1573 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1574 #endif /* L_ctors */
1578 #include "gbl-ctors.h"
1586 static func_ptr
*atexit_chain
= 0;
1587 static long atexit_chain_length
= 0;
1588 static volatile long last_atexit_chain_slot
= -1;
1591 atexit (func_ptr func
)
1593 if (++last_atexit_chain_slot
== atexit_chain_length
)
1595 atexit_chain_length
+= 32;
1597 atexit_chain
= (func_ptr
*) realloc (atexit_chain
, atexit_chain_length
1598 * sizeof (func_ptr
));
1600 atexit_chain
= (func_ptr
*) malloc (atexit_chain_length
1601 * sizeof (func_ptr
));
1604 atexit_chain_length
= 0;
1605 last_atexit_chain_slot
= -1;
1610 atexit_chain
[last_atexit_chain_slot
] = func
;
1614 extern void _cleanup (void);
1615 extern void _exit (int) __attribute__ ((__noreturn__
));
1622 for ( ; last_atexit_chain_slot
-- >= 0; )
1624 (*atexit_chain
[last_atexit_chain_slot
+ 1]) ();
1625 atexit_chain
[last_atexit_chain_slot
+ 1] = 0;
1627 free (atexit_chain
);
1640 /* Simple; we just need a wrapper for ON_EXIT. */
1642 atexit (func_ptr func
)
1644 return ON_EXIT (func
);
1647 #endif /* ON_EXIT */
1648 #endif /* NEED_ATEXIT */