b0daa70d9e1507af35dd6c919fadb417b97129ec
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 Free Software Foundation, Inc.
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
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 GNU CC is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 GNU General Public License for more details.
27 You should have received a copy of the GNU General Public License
28 along with GNU CC; see the file COPYING. If not, write to
29 the Free Software Foundation, 59 Temple Place - Suite 330,
30 Boston, MA 02111-1307, USA. */
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
41 /* Don't use `fancy_abort' here even if config.h says to use it. */
48 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
49 #if defined (L_divdi3) || defined (L_moddi3)
61 w
.s
.high
= -uu
.s
.high
- ((UWtype
) w
.s
.low
> 0);
69 __addvsi3 (Wtype a
, Wtype b
)
75 if (b
>= 0 ? w
< a
: w
> a
)
84 __addvdi3 (DWtype a
, DWtype b
)
90 if (b
>= 0 ? w
< a
: w
> a
)
99 __subvsi3 (Wtype a
, Wtype b
)
102 return __addvsi3 (a
, (-b
));
108 if (b
>= 0 ? w
> a
: w
< a
)
118 __subvdi3 (DWtype a
, DWtype b
)
127 if (b
>= 0 ? w
> a
: w
< a
)
137 __mulvsi3 (Wtype a
, Wtype b
)
143 if (((a
>= 0) == (b
>= 0)) ? w
< 0 : w
> 0)
158 if (a
>= 0 ? w
> 0 : w
< 0)
173 if (a
>= 0 ? w
> 0 : w
< 0)
222 __mulvdi3 (DWtype u
, DWtype v
)
228 if (((u
>= 0) == (v
>= 0)) ? w
< 0 : w
> 0)
236 /* Unless shift functions are defined whith full ANSI prototypes,
237 parameter b will be promoted to int if word_type is smaller than an int. */
240 __lshrdi3 (DWtype u
, word_type b
)
251 bm
= (sizeof (Wtype
) * BITS_PER_UNIT
) - b
;
255 w
.s
.low
= (UWtype
) uu
.s
.high
>> -bm
;
259 UWtype carries
= (UWtype
) uu
.s
.high
<< bm
;
261 w
.s
.high
= (UWtype
) uu
.s
.high
>> b
;
262 w
.s
.low
= ((UWtype
) uu
.s
.low
>> b
) | carries
;
271 __ashldi3 (DWtype u
, word_type b
)
282 bm
= (sizeof (Wtype
) * BITS_PER_UNIT
) - b
;
286 w
.s
.high
= (UWtype
) uu
.s
.low
<< -bm
;
290 UWtype carries
= (UWtype
) uu
.s
.low
>> bm
;
292 w
.s
.low
= (UWtype
) uu
.s
.low
<< b
;
293 w
.s
.high
= ((UWtype
) uu
.s
.high
<< b
) | carries
;
302 __ashrdi3 (DWtype u
, word_type b
)
313 bm
= (sizeof (Wtype
) * BITS_PER_UNIT
) - b
;
316 /* w.s.high = 1..1 or 0..0 */
317 w
.s
.high
= uu
.s
.high
>> (sizeof (Wtype
) * BITS_PER_UNIT
- 1);
318 w
.s
.low
= uu
.s
.high
>> -bm
;
322 UWtype carries
= (UWtype
) uu
.s
.high
<< bm
;
324 w
.s
.high
= uu
.s
.high
>> b
;
325 w
.s
.low
= ((UWtype
) uu
.s
.low
>> b
) | carries
;
337 UWtype word
, count
, add
;
341 word
= uu
.s
.low
, add
= 0;
342 else if (uu
.s
.high
!= 0)
343 word
= uu
.s
.high
, add
= BITS_PER_UNIT
* sizeof (Wtype
);
347 count_trailing_zeros (count
, word
);
348 return count
+ add
+ 1;
354 __muldi3 (DWtype u
, DWtype v
)
362 w
.ll
= __umulsidi3 (uu
.s
.low
, vv
.s
.low
);
363 w
.s
.high
+= ((UWtype
) uu
.s
.low
* (UWtype
) vv
.s
.high
364 + (UWtype
) uu
.s
.high
* (UWtype
) vv
.s
.low
);
371 #if defined (sdiv_qrnnd)
373 __udiv_w_sdiv (UWtype
*rp
, UWtype a1
, UWtype a0
, UWtype d
)
380 if (a1
< d
- a1
- (a0
>> (W_TYPE_SIZE
- 1)))
382 /* dividend, divisor, and quotient are nonnegative */
383 sdiv_qrnnd (q
, r
, a1
, a0
, d
);
387 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
388 sub_ddmmss (c1
, c0
, a1
, a0
, d
>> 1, d
<< (W_TYPE_SIZE
- 1));
389 /* Divide (c1*2^32 + c0) by d */
390 sdiv_qrnnd (q
, r
, c1
, c0
, d
);
391 /* Add 2^31 to quotient */
392 q
+= (UWtype
) 1 << (W_TYPE_SIZE
- 1);
397 b1
= d
>> 1; /* d/2, between 2^30 and 2^31 - 1 */
398 c1
= a1
>> 1; /* A/2 */
399 c0
= (a1
<< (W_TYPE_SIZE
- 1)) + (a0
>> 1);
401 if (a1
< b1
) /* A < 2^32*b1, so A/2 < 2^31*b1 */
403 sdiv_qrnnd (q
, r
, c1
, c0
, b1
); /* (A/2) / (d/2) */
405 r
= 2*r
+ (a0
& 1); /* Remainder from A/(2*b1) */
422 else if (c1
< b1
) /* So 2^31 <= (A/2)/b1 < 2^32 */
425 c0
= ~c0
; /* logical NOT */
427 sdiv_qrnnd (q
, r
, c1
, c0
, b1
); /* (A/2) / (d/2) */
429 q
= ~q
; /* (A/2)/b1 */
432 r
= 2*r
+ (a0
& 1); /* A/(2*b1) */
450 else /* Implies c1 = b1 */
451 { /* Hence a1 = d - 1 = 2*b1 - 1 */
469 /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */
471 __udiv_w_sdiv (UWtype
*rp
__attribute__ ((__unused__
)),
472 UWtype a1
__attribute__ ((__unused__
)),
473 UWtype a0
__attribute__ ((__unused__
)),
474 UWtype d
__attribute__ ((__unused__
)))
481 #if (defined (L_udivdi3) || defined (L_divdi3) || \
482 defined (L_umoddi3) || defined (L_moddi3))
487 const UQItype __clz_tab
[] =
489 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,
490 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,
491 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,
492 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,
493 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,
494 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,
495 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,
496 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,
502 #if (defined (L_udivdi3) || defined (L_divdi3) || \
503 defined (L_umoddi3) || defined (L_moddi3))
507 __udivmoddi4 (UDWtype n
, UDWtype d
, UDWtype
*rp
)
512 UWtype d0
, d1
, n0
, n1
, n2
;
524 #if !UDIV_NEEDS_NORMALIZATION
531 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
534 /* Remainder in n0. */
541 d0
= 1 / d0
; /* Divide intentionally by zero. */
543 udiv_qrnnd (q1
, n1
, 0, n1
, d0
);
544 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
546 /* Remainder in n0. */
557 #else /* UDIV_NEEDS_NORMALIZATION */
565 count_leading_zeros (bm
, d0
);
569 /* Normalize, i.e. make the most significant bit of the
573 n1
= (n1
<< bm
) | (n0
>> (W_TYPE_SIZE
- bm
));
577 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
580 /* Remainder in n0 >> bm. */
587 d0
= 1 / d0
; /* Divide intentionally by zero. */
589 count_leading_zeros (bm
, d0
);
593 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
594 conclude (the most significant bit of n1 is set) /\ (the
595 leading quotient digit q1 = 1).
597 This special case is necessary, not an optimization.
598 (Shifts counts of W_TYPE_SIZE are undefined.) */
607 b
= W_TYPE_SIZE
- bm
;
611 n1
= (n1
<< bm
) | (n0
>> b
);
614 udiv_qrnnd (q1
, n1
, n2
, n1
, d0
);
619 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
621 /* Remainder in n0 >> bm. */
631 #endif /* UDIV_NEEDS_NORMALIZATION */
642 /* Remainder in n1n0. */
654 count_leading_zeros (bm
, d1
);
657 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
658 conclude (the most significant bit of n1 is set) /\ (the
659 quotient digit q0 = 0 or 1).
661 This special case is necessary, not an optimization. */
663 /* The condition on the next line takes advantage of that
664 n1 >= d1 (true due to program flow). */
665 if (n1
> d1
|| n0
>= d0
)
668 sub_ddmmss (n1
, n0
, n1
, n0
, d1
, d0
);
687 b
= W_TYPE_SIZE
- bm
;
689 d1
= (d1
<< bm
) | (d0
>> b
);
692 n1
= (n1
<< bm
) | (n0
>> b
);
695 udiv_qrnnd (q0
, n1
, n2
, n1
, d1
);
696 umul_ppmm (m1
, m0
, q0
, d0
);
698 if (m1
> n1
|| (m1
== n1
&& m0
> n0
))
701 sub_ddmmss (m1
, m0
, m1
, m0
, d1
, d0
);
706 /* Remainder in (n1n0 - m1m0) >> bm. */
709 sub_ddmmss (n1
, n0
, n1
, n0
, m1
, m0
);
710 rr
.s
.low
= (n1
<< b
) | (n0
>> bm
);
711 rr
.s
.high
= n1
>> bm
;
726 __divdi3 (DWtype u
, DWtype v
)
737 uu
.ll
= __negdi2 (uu
.ll
);
740 vv
.ll
= __negdi2 (vv
.ll
);
742 w
= __udivmoddi4 (uu
.ll
, vv
.ll
, (UDWtype
*) 0);
752 __moddi3 (DWtype u
, DWtype v
)
763 uu
.ll
= __negdi2 (uu
.ll
);
765 vv
.ll
= __negdi2 (vv
.ll
);
767 (void) __udivmoddi4 (uu
.ll
, vv
.ll
, &w
);
777 __umoddi3 (UDWtype u
, UDWtype v
)
781 (void) __udivmoddi4 (u
, v
, &w
);
789 __udivdi3 (UDWtype n
, UDWtype d
)
791 return __udivmoddi4 (n
, d
, (UDWtype
*) 0);
797 __cmpdi2 (DWtype a
, DWtype b
)
801 au
.ll
= a
, bu
.ll
= b
;
803 if (au
.s
.high
< bu
.s
.high
)
805 else if (au
.s
.high
> bu
.s
.high
)
807 if ((UWtype
) au
.s
.low
< (UWtype
) bu
.s
.low
)
809 else if ((UWtype
) au
.s
.low
> (UWtype
) bu
.s
.low
)
817 __ucmpdi2 (DWtype a
, DWtype b
)
821 au
.ll
= a
, bu
.ll
= b
;
823 if ((UWtype
) au
.s
.high
< (UWtype
) bu
.s
.high
)
825 else if ((UWtype
) au
.s
.high
> (UWtype
) bu
.s
.high
)
827 if ((UWtype
) au
.s
.low
< (UWtype
) bu
.s
.low
)
829 else if ((UWtype
) au
.s
.low
> (UWtype
) bu
.s
.low
)
835 #if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
836 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
837 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
840 __fixunstfDI (TFtype a
)
848 /* Compute high word of result, as a flonum. */
849 b
= (a
/ HIGH_WORD_COEFF
);
850 /* Convert that to fixed (but not to DWtype!),
851 and shift it into the high word. */
854 /* Remove high part from the TFtype, leaving the low part as flonum. */
856 /* Convert that to fixed (but not to DWtype!) and add it in.
857 Sometimes A comes out negative. This is significant, since
858 A has more bits than a long int does. */
867 #if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
872 return - __fixunstfDI (-a
);
873 return __fixunstfDI (a
);
877 #if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
878 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
879 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
882 __fixunsxfDI (XFtype a
)
890 /* Compute high word of result, as a flonum. */
891 b
= (a
/ HIGH_WORD_COEFF
);
892 /* Convert that to fixed (but not to DWtype!),
893 and shift it into the high word. */
896 /* Remove high part from the XFtype, leaving the low part as flonum. */
898 /* Convert that to fixed (but not to DWtype!) and add it in.
899 Sometimes A comes out negative. This is significant, since
900 A has more bits than a long int does. */
909 #if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
914 return - __fixunsxfDI (-a
);
915 return __fixunsxfDI (a
);
920 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
921 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
924 __fixunsdfDI (DFtype a
)
932 /* Compute high word of result, as a flonum. */
933 b
= (a
/ HIGH_WORD_COEFF
);
934 /* Convert that to fixed (but not to DWtype!),
935 and shift it into the high word. */
938 /* Remove high part from the DFtype, leaving the low part as flonum. */
940 /* Convert that to fixed (but not to DWtype!) and add it in.
941 Sometimes A comes out negative. This is significant, since
942 A has more bits than a long int does. */
956 return - __fixunsdfDI (-a
);
957 return __fixunsdfDI (a
);
962 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
963 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
966 __fixunssfDI (SFtype original_a
)
968 /* Convert the SFtype to a DFtype, because that is surely not going
969 to lose any bits. Some day someone else can write a faster version
970 that avoids converting to DFtype, and verify it really works right. */
971 DFtype a
= original_a
;
978 /* Compute high word of result, as a flonum. */
979 b
= (a
/ HIGH_WORD_COEFF
);
980 /* Convert that to fixed (but not to DWtype!),
981 and shift it into the high word. */
984 /* Remove high part from the DFtype, leaving the low part as flonum. */
986 /* Convert that to fixed (but not to DWtype!) and add it in.
987 Sometimes A comes out negative. This is significant, since
988 A has more bits than a long int does. */
1002 return - __fixunssfDI (-a
);
1003 return __fixunssfDI (a
);
1007 #if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
1008 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1009 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1010 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1013 __floatdixf (DWtype u
)
1017 d
= (Wtype
) (u
>> WORD_SIZE
);
1018 d
*= HIGH_HALFWORD_COEFF
;
1019 d
*= HIGH_HALFWORD_COEFF
;
1020 d
+= (UWtype
) (u
& (HIGH_WORD_COEFF
- 1));
1026 #if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
1027 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1028 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1029 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1032 __floatditf (DWtype u
)
1036 d
= (Wtype
) (u
>> WORD_SIZE
);
1037 d
*= HIGH_HALFWORD_COEFF
;
1038 d
*= HIGH_HALFWORD_COEFF
;
1039 d
+= (UWtype
) (u
& (HIGH_WORD_COEFF
- 1));
1046 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1047 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1048 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1051 __floatdidf (DWtype u
)
1055 d
= (Wtype
) (u
>> WORD_SIZE
);
1056 d
*= HIGH_HALFWORD_COEFF
;
1057 d
*= HIGH_HALFWORD_COEFF
;
1058 d
+= (UWtype
) (u
& (HIGH_WORD_COEFF
- 1));
1065 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1066 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1067 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1068 #define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT)
1070 /* Define codes for all the float formats that we know of. Note
1071 that this is copied from real.h. */
1073 #define UNKNOWN_FLOAT_FORMAT 0
1074 #define IEEE_FLOAT_FORMAT 1
1075 #define VAX_FLOAT_FORMAT 2
1076 #define IBM_FLOAT_FORMAT 3
1078 /* Default to IEEE float if not specified. Nearly all machines use it. */
1079 #ifndef HOST_FLOAT_FORMAT
1080 #define HOST_FLOAT_FORMAT IEEE_FLOAT_FORMAT
1083 #if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1088 #if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
1093 #if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
1099 __floatdisf (DWtype u
)
1101 /* Do the calculation in DFmode
1102 so that we don't lose any of the precision of the high word
1103 while multiplying it. */
1106 /* Protect against double-rounding error.
1107 Represent any low-order bits, that might be truncated in DFmode,
1108 by a bit that won't be lost. The bit can go in anywhere below the
1109 rounding position of the SFmode. A fixed mask and bit position
1110 handles all usual configurations. It doesn't handle the case
1111 of 128-bit DImode, however. */
1112 if (DF_SIZE
< DI_SIZE
1113 && DF_SIZE
> (DI_SIZE
- DF_SIZE
+ SF_SIZE
))
1115 #define REP_BIT ((UDWtype) 1 << (DI_SIZE - DF_SIZE))
1116 if (! (- ((DWtype
) 1 << DF_SIZE
) < u
1117 && u
< ((DWtype
) 1 << DF_SIZE
)))
1119 if ((UDWtype
) u
& (REP_BIT
- 1))
1123 f
= (Wtype
) (u
>> WORD_SIZE
);
1124 f
*= HIGH_HALFWORD_COEFF
;
1125 f
*= HIGH_HALFWORD_COEFF
;
1126 f
+= (UWtype
) (u
& (HIGH_WORD_COEFF
- 1));
1132 #if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
1133 /* Reenable the normal types, in case limits.h needs them. */
1146 __fixunsxfSI (XFtype a
)
1148 if (a
>= - (DFtype
) Wtype_MIN
)
1149 return (Wtype
) (a
+ Wtype_MIN
) - Wtype_MIN
;
1155 /* Reenable the normal types, in case limits.h needs them. */
1168 __fixunsdfSI (DFtype a
)
1170 if (a
>= - (DFtype
) Wtype_MIN
)
1171 return (Wtype
) (a
+ Wtype_MIN
) - Wtype_MIN
;
1177 /* Reenable the normal types, in case limits.h needs them. */
1190 __fixunssfSI (SFtype a
)
1192 if (a
>= - (SFtype
) Wtype_MIN
)
1193 return (Wtype
) (a
+ Wtype_MIN
) - Wtype_MIN
;
1198 /* From here on down, the routines use normal data types. */
1200 #define SItype bogus_type
1201 #define USItype bogus_type
1202 #define DItype bogus_type
1203 #define UDItype bogus_type
1204 #define SFtype bogus_type
1205 #define DFtype bogus_type
1223 /* Like bcmp except the sign is meaningful.
1224 Result is negative if S1 is less than S2,
1225 positive if S1 is greater, 0 if S1 and S2 are equal. */
1228 __gcc_bcmp (const unsigned char *s1
, const unsigned char *s2
, size_t size
)
1232 unsigned char c1
= *s1
++, c2
= *s2
++;
1244 /* Structure emitted by -a */
1248 const char *filename
;
1252 const unsigned long *addresses
;
1254 /* Older GCC's did not emit these fields. */
1256 const char **functions
;
1257 const long *line_nums
;
1258 const char **filenames
;
1262 #ifdef BLOCK_PROFILER_CODE
1265 #ifndef inhibit_libc
1267 /* Simple minded basic block profiling output dumper for
1268 systems that don't provide tcov support. At present,
1269 it requires atexit and stdio. */
1271 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1273 char *ctime
PARAMS ((const time_t *));
1275 #include "gbl-ctors.h"
1276 #include "gcov-io.h"
1278 #ifdef TARGET_HAS_F_SETLKW
1283 static struct bb
*bb_head
;
1285 static int num_digits (long value
, int base
) __attribute__ ((const));
1287 /* Return the number of digits needed to print a value */
1288 /* __inline__ */ static int num_digits (long value
, int base
)
1290 int minus
= (value
< 0 && base
!= 16);
1291 unsigned long v
= (minus
) ? -value
: value
;
1305 __bb_exit_func (void)
1307 FILE *da_file
, *file
;
1314 i
= strlen (bb_head
->filename
) - 3;
1316 if (!strcmp (bb_head
->filename
+i
, ".da"))
1318 /* Must be -fprofile-arcs not -a.
1319 Dump data in a form that gcov expects. */
1323 for (ptr
= bb_head
; ptr
!= (struct bb
*) 0; ptr
= ptr
->next
)
1327 /* Make sure the output file exists -
1328 but don't clobber exiting data. */
1329 if ((da_file
= fopen (ptr
->filename
, "a")) != 0)
1332 /* Need to re-open in order to be able to write from the start. */
1333 da_file
= fopen (ptr
->filename
, "r+b");
1334 /* Some old systems might not allow the 'b' mode modifier.
1335 Therefore, try to open without it. This can lead to a race
1336 condition so that when you delete and re-create the file, the
1337 file might be opened in text mode, but then, you shouldn't
1338 delete the file in the first place. */
1340 da_file
= fopen (ptr
->filename
, "r+");
1343 fprintf (stderr
, "arc profiling: Can't open output file %s.\n",
1348 /* After a fork, another process might try to read and/or write
1349 the same file simultanously. So if we can, lock the file to
1350 avoid race conditions. */
1351 #if defined (TARGET_HAS_F_SETLKW)
1353 struct flock s_flock
;
1355 s_flock
.l_type
= F_WRLCK
;
1356 s_flock
.l_whence
= SEEK_SET
;
1357 s_flock
.l_start
= 0;
1359 s_flock
.l_pid
= getpid ();
1361 while (fcntl (fileno (da_file
), F_SETLKW
, &s_flock
)
1366 /* If the file is not empty, and the number of counts in it is the
1367 same, then merge them in. */
1368 firstchar
= fgetc (da_file
);
1369 if (firstchar
== EOF
)
1371 if (ferror (da_file
))
1373 fprintf (stderr
, "arc profiling: Can't read output file ");
1374 perror (ptr
->filename
);
1381 if (ungetc (firstchar
, da_file
) == EOF
)
1383 if (__read_long (&n_counts
, da_file
, 8) != 0)
1385 fprintf (stderr
, "arc profiling: Can't read output file %s.\n",
1390 if (n_counts
== ptr
->ncounts
)
1394 for (i
= 0; i
< n_counts
; i
++)
1398 if (__read_long (&v
, da_file
, 8) != 0)
1400 fprintf (stderr
, "arc profiling: Can't read output file %s.\n",
1404 ptr
->counts
[i
] += v
;
1412 /* ??? Should first write a header to the file. Preferably, a 4 byte
1413 magic number, 4 bytes containing the time the program was
1414 compiled, 4 bytes containing the last modification time of the
1415 source file, and 4 bytes indicating the compiler options used.
1417 That way we can easily verify that the proper source/executable/
1418 data file combination is being used from gcov. */
1420 if (__write_long (ptr
->ncounts
, da_file
, 8) != 0)
1423 fprintf (stderr
, "arc profiling: Error writing output file %s.\n",
1429 long *count_ptr
= ptr
->counts
;
1431 for (j
= ptr
->ncounts
; j
> 0; j
--)
1433 if (__write_long (*count_ptr
, da_file
, 8) != 0)
1441 fprintf (stderr
, "arc profiling: Error writing output file %s.\n",
1445 if (fclose (da_file
) == EOF
)
1446 fprintf (stderr
, "arc profiling: Error closing output file %s.\n",
1453 /* Must be basic block profiling. Emit a human readable output file. */
1455 file
= fopen ("bb.out", "a");
1464 /* This is somewhat type incorrect, but it avoids worrying about
1465 exactly where time.h is included from. It should be ok unless
1466 a void * differs from other pointer formats, or if sizeof (long)
1467 is < sizeof (time_t). It would be nice if we could assume the
1468 use of rationale standards here. */
1470 time ((void *) &time_value
);
1471 fprintf (file
, "Basic block profiling finished on %s\n", ctime ((void *) &time_value
));
1473 /* We check the length field explicitly in order to allow compatibility
1474 with older GCC's which did not provide it. */
1476 for (ptr
= bb_head
; ptr
!= (struct bb
*) 0; ptr
= ptr
->next
)
1479 int func_p
= (ptr
->nwords
>= (long) sizeof (struct bb
)
1480 && ptr
->nwords
<= 1000
1482 int line_p
= (func_p
&& ptr
->line_nums
);
1483 int file_p
= (func_p
&& ptr
->filenames
);
1484 int addr_p
= (ptr
->addresses
!= 0);
1485 long ncounts
= ptr
->ncounts
;
1491 int blk_len
= num_digits (ncounts
, 10);
1496 fprintf (file
, "File %s, %ld basic blocks \n\n",
1497 ptr
->filename
, ncounts
);
1499 /* Get max values for each field. */
1500 for (i
= 0; i
< ncounts
; i
++)
1505 if (cnt_max
< ptr
->counts
[i
])
1506 cnt_max
= ptr
->counts
[i
];
1508 if (addr_p
&& (unsigned long) addr_max
< ptr
->addresses
[i
])
1509 addr_max
= ptr
->addresses
[i
];
1511 if (line_p
&& line_max
< ptr
->line_nums
[i
])
1512 line_max
= ptr
->line_nums
[i
];
1516 p
= (ptr
->functions
[i
]) ? (ptr
->functions
[i
]) : "<none>";
1524 p
= (ptr
->filenames
[i
]) ? (ptr
->filenames
[i
]) : "<none>";
1531 addr_len
= num_digits (addr_max
, 16);
1532 cnt_len
= num_digits (cnt_max
, 10);
1533 line_len
= num_digits (line_max
, 10);
1535 /* Now print out the basic block information. */
1536 for (i
= 0; i
< ncounts
; i
++)
1539 " Block #%*d: executed %*ld time(s)",
1541 cnt_len
, ptr
->counts
[i
]);
1544 fprintf (file
, " address= 0x%.*lx", addr_len
,
1548 fprintf (file
, " function= %-*s", func_len
,
1549 (ptr
->functions
[i
]) ? ptr
->functions
[i
] : "<none>");
1552 fprintf (file
, " line= %*ld", line_len
, ptr
->line_nums
[i
]);
1555 fprintf (file
, " file= %s",
1556 (ptr
->filenames
[i
]) ? ptr
->filenames
[i
] : "<none>");
1558 fprintf (file
, "\n");
1561 fprintf (file
, "\n");
1565 fprintf (file
, "\n\n");
1571 __bb_init_func (struct bb
*blocks
)
1573 /* User is supposed to check whether the first word is non-0,
1574 but just in case.... */
1576 if (blocks
->zero_word
)
1579 /* Initialize destructor. */
1581 atexit (__bb_exit_func
);
1583 /* Set up linked list. */
1584 blocks
->zero_word
= 1;
1585 blocks
->next
= bb_head
;
1589 /* Called before fork or exec - write out profile information gathered so
1590 far and reset it to zero. This avoids duplication or loss of the
1591 profile information gathered so far. */
1593 __bb_fork_func (void)
1598 for (ptr
= bb_head
; ptr
!= (struct bb
*) 0; ptr
= ptr
->next
)
1601 for (i
= ptr
->ncounts
- 1; i
>= 0; i
--)
1606 #ifndef MACHINE_STATE_SAVE
1607 #define MACHINE_STATE_SAVE(ID)
1609 #ifndef MACHINE_STATE_RESTORE
1610 #define MACHINE_STATE_RESTORE(ID)
1613 /* Number of buckets in hashtable of basic block addresses. */
1615 #define BB_BUCKETS 311
1617 /* Maximum length of string in file bb.in. */
1619 #define BBINBUFSIZE 500
1623 struct bb_edge
*next
;
1624 unsigned long src_addr
;
1625 unsigned long dst_addr
;
1626 unsigned long count
;
1631 TRACE_KEEP
= 0, TRACE_ON
= 1, TRACE_OFF
= 2
1636 struct bb_func
*next
;
1639 enum bb_func_mode mode
;
1642 /* This is the connection to the outside world.
1643 The BLOCK_PROFILER macro must set __bb.blocks
1644 and __bb.blockno. */
1647 unsigned long blockno
;
1651 /* Vars to store addrs of source and destination basic blocks
1654 static unsigned long bb_src
= 0;
1655 static unsigned long bb_dst
= 0;
1657 static FILE *bb_tracefile
= (FILE *) 0;
1658 static struct bb_edge
**bb_hashbuckets
= (struct bb_edge
**) 0;
1659 static struct bb_func
*bb_func_head
= (struct bb_func
*) 0;
1660 static unsigned long bb_callcount
= 0;
1661 static int bb_mode
= 0;
1663 static unsigned long *bb_stack
= (unsigned long *) 0;
1664 static size_t bb_stacksize
= 0;
1666 static int reported
= 0;
1669 Always : Print execution frequencies of basic blocks
1671 bb_mode & 1 != 0 : Dump trace of basic blocks to file bbtrace[.gz]
1672 bb_mode & 2 != 0 : Print jump frequencies to file bb.out.
1673 bb_mode & 4 != 0 : Cut call instructions from basic block flow.
1674 bb_mode & 8 != 0 : Insert return instructions in basic block flow.
1679 /*#include <sys/types.h>*/
1680 #include <sys/stat.h>
1681 /*#include <malloc.h>*/
1683 /* Commands executed by gopen. */
1685 #define GOPENDECOMPRESS "gzip -cd "
1686 #define GOPENCOMPRESS "gzip -c >"
1688 /* Like fopen but pipes through gzip. mode may only be "r" or "w".
1689 If it does not compile, simply replace gopen by fopen and delete
1690 '.gz' from any first parameter to gopen. */
1693 gopen (char *fn
, char *mode
)
1701 if (mode
[0] != 'r' && mode
[0] != 'w')
1704 p
= fn
+ strlen (fn
)-1;
1705 use_gzip
= ((p
[-1] == '.' && (p
[0] == 'Z' || p
[0] == 'z'))
1706 || (p
[-2] == '.' && p
[-1] == 'g' && p
[0] == 'z'));
1713 char *s
= (char *) malloc (sizeof (char) * strlen (fn
)
1714 + sizeof (GOPENDECOMPRESS
));
1715 strcpy (s
, GOPENDECOMPRESS
);
1716 strcpy (s
+ (sizeof (GOPENDECOMPRESS
)-1), fn
);
1717 f
= popen (s
, mode
);
1725 char *s
= (char *) malloc (sizeof (char) * strlen (fn
)
1726 + sizeof (GOPENCOMPRESS
));
1727 strcpy (s
, GOPENCOMPRESS
);
1728 strcpy (s
+ (sizeof (GOPENCOMPRESS
)-1), fn
);
1729 if (!(f
= popen (s
, mode
)))
1730 f
= fopen (s
, mode
);
1737 return fopen (fn
, mode
);
1747 if (!fstat (fileno (f
), &buf
) && S_ISFIFO (buf
.st_mode
))
1755 #endif /* HAVE_POPEN */
1757 /* Called once per program. */
1760 __bb_exit_trace_func (void)
1762 FILE *file
= fopen ("bb.out", "a");
1775 gclose (bb_tracefile
);
1777 fclose (bb_tracefile
);
1778 #endif /* HAVE_POPEN */
1781 /* Check functions in `bb.in'. */
1786 const struct bb_func
*p
;
1787 int printed_something
= 0;
1791 /* This is somewhat type incorrect. */
1792 time ((void *) &time_value
);
1794 for (p
= bb_func_head
; p
!= (struct bb_func
*) 0; p
= p
->next
)
1796 for (ptr
= bb_head
; ptr
!= (struct bb
*) 0; ptr
= ptr
->next
)
1798 if (!ptr
->filename
|| (p
->filename
!= (char *) 0 && strcmp (p
->filename
, ptr
->filename
)))
1800 for (blk
= 0; blk
< ptr
->ncounts
; blk
++)
1802 if (!strcmp (p
->funcname
, ptr
->functions
[blk
]))
1807 if (!printed_something
)
1809 fprintf (file
, "Functions in `bb.in' not executed during basic block profiling on %s\n", ctime ((void *) &time_value
));
1810 printed_something
= 1;
1813 fprintf (file
, "\tFunction %s", p
->funcname
);
1815 fprintf (file
, " of file %s", p
->filename
);
1816 fprintf (file
, "\n" );
1821 if (printed_something
)
1822 fprintf (file
, "\n");
1828 if (!bb_hashbuckets
)
1832 fprintf (stderr
, "Profiler: out of memory\n");
1842 unsigned long addr_max
= 0;
1843 unsigned long cnt_max
= 0;
1847 /* This is somewhat type incorrect, but it avoids worrying about
1848 exactly where time.h is included from. It should be ok unless
1849 a void * differs from other pointer formats, or if sizeof (long)
1850 is < sizeof (time_t). It would be nice if we could assume the
1851 use of rationale standards here. */
1853 time ((void *) &time_value
);
1854 fprintf (file
, "Basic block jump tracing");
1856 switch (bb_mode
& 12)
1859 fprintf (file
, " (with call)");
1863 /* Print nothing. */
1867 fprintf (file
, " (with call & ret)");
1871 fprintf (file
, " (with ret)");
1875 fprintf (file
, " finished on %s\n", ctime ((void *) &time_value
));
1877 for (i
= 0; i
< BB_BUCKETS
; i
++)
1879 struct bb_edge
*bucket
= bb_hashbuckets
[i
];
1880 for ( ; bucket
; bucket
= bucket
->next
)
1882 if (addr_max
< bucket
->src_addr
)
1883 addr_max
= bucket
->src_addr
;
1884 if (addr_max
< bucket
->dst_addr
)
1885 addr_max
= bucket
->dst_addr
;
1886 if (cnt_max
< bucket
->count
)
1887 cnt_max
= bucket
->count
;
1890 addr_len
= num_digits (addr_max
, 16);
1891 cnt_len
= num_digits (cnt_max
, 10);
1893 for ( i
= 0; i
< BB_BUCKETS
; i
++)
1895 struct bb_edge
*bucket
= bb_hashbuckets
[i
];
1896 for ( ; bucket
; bucket
= bucket
->next
)
1899 "Jump from block 0x%.*lx to block 0x%.*lx executed %*lu time(s)\n",
1900 addr_len
, bucket
->src_addr
,
1901 addr_len
, bucket
->dst_addr
,
1902 cnt_len
, bucket
->count
);
1906 fprintf (file
, "\n");
1914 /* Free allocated memory. */
1919 struct bb_func
*old
= f
;
1922 if (old
->funcname
) free (old
->funcname
);
1923 if (old
->filename
) free (old
->filename
);
1934 for (i
= 0; i
< BB_BUCKETS
; i
++)
1936 struct bb_edge
*old
, *bucket
= bb_hashbuckets
[i
];
1941 bucket
= bucket
->next
;
1945 free (bb_hashbuckets
);
1948 for (b
= bb_head
; b
; b
= b
->next
)
1949 if (b
->flags
) free (b
->flags
);
1952 /* Called once per program. */
1955 __bb_init_prg (void)
1958 char buf
[BBINBUFSIZE
];
1961 enum bb_func_mode m
;
1964 /* Initialize destructor. */
1965 atexit (__bb_exit_func
);
1967 if (!(file
= fopen ("bb.in", "r")))
1970 while(fgets (buf
, BBINBUFSIZE
, file
) != 0)
1986 if (!strcmp (p
, "__bb_trace__"))
1988 else if (!strcmp (p
, "__bb_jumps__"))
1990 else if (!strcmp (p
, "__bb_hidecall__"))
1992 else if (!strcmp (p
, "__bb_showret__"))
1996 struct bb_func
*f
= (struct bb_func
*) malloc (sizeof (struct bb_func
));
2000 f
->next
= bb_func_head
;
2001 if ((pos
= strchr (p
, ':')))
2003 if (!(f
->funcname
= (char *) malloc (strlen (pos
+1)+1)))
2005 strcpy (f
->funcname
, pos
+1);
2007 if ((f
->filename
= (char *) malloc (l
+1)))
2009 strncpy (f
->filename
, p
, l
);
2010 f
->filename
[l
] = '\0';
2013 f
->filename
= (char *) 0;
2017 if (!(f
->funcname
= (char *) malloc (strlen (p
)+1)))
2019 strcpy (f
->funcname
, p
);
2020 f
->filename
= (char *) 0;
2032 bb_tracefile
= gopen ("bbtrace.gz", "w");
2037 bb_tracefile
= fopen ("bbtrace", "w");
2039 #endif /* HAVE_POPEN */
2043 bb_hashbuckets
= (struct bb_edge
**)
2044 malloc (BB_BUCKETS
* sizeof (struct bb_edge
*));
2046 /* Use a loop here rather than calling bzero to avoid having to
2047 conditionalize its existance. */
2048 for (i
= 0; i
< BB_BUCKETS
; i
++)
2049 bb_hashbuckets
[i
] = 0;
2055 bb_stack
= (unsigned long *) malloc (bb_stacksize
* sizeof (*bb_stack
));
2058 /* Initialize destructor. */
2059 atexit (__bb_exit_trace_func
);
2062 /* Called upon entering a basic block. */
2065 __bb_trace_func (void)
2067 struct bb_edge
*bucket
;
2069 MACHINE_STATE_SAVE("1")
2071 if (!bb_callcount
|| (__bb
.blocks
->flags
&& (__bb
.blocks
->flags
[__bb
.blockno
] & TRACE_OFF
)))
2074 bb_dst
= __bb
.blocks
->addresses
[__bb
.blockno
];
2075 __bb
.blocks
->counts
[__bb
.blockno
]++;
2079 fwrite (&bb_dst
, sizeof (unsigned long), 1, bb_tracefile
);
2084 struct bb_edge
**startbucket
, **oldnext
;
2086 oldnext
= startbucket
2087 = & bb_hashbuckets
[ (((int) bb_src
*8) ^ (int) bb_dst
) % BB_BUCKETS
];
2088 bucket
= *startbucket
;
2090 for (bucket
= *startbucket
; bucket
;
2091 oldnext
= &(bucket
->next
), bucket
= *oldnext
)
2093 if (bucket
->src_addr
== bb_src
2094 && bucket
->dst_addr
== bb_dst
)
2097 *oldnext
= bucket
->next
;
2098 bucket
->next
= *startbucket
;
2099 *startbucket
= bucket
;
2104 bucket
= (struct bb_edge
*) malloc (sizeof (struct bb_edge
));
2110 fprintf (stderr
, "Profiler: out of memory\n");
2117 bucket
->src_addr
= bb_src
;
2118 bucket
->dst_addr
= bb_dst
;
2119 bucket
->next
= *startbucket
;
2120 *startbucket
= bucket
;
2131 MACHINE_STATE_RESTORE("1")
2135 /* Called when returning from a function and `__bb_showret__' is set. */
2138 __bb_trace_func_ret (void)
2140 struct bb_edge
*bucket
;
2142 if (!bb_callcount
|| (__bb
.blocks
->flags
&& (__bb
.blocks
->flags
[__bb
.blockno
] & TRACE_OFF
)))
2147 struct bb_edge
**startbucket
, **oldnext
;
2149 oldnext
= startbucket
2150 = & bb_hashbuckets
[ (((int) bb_dst
* 8) ^ (int) bb_src
) % BB_BUCKETS
];
2151 bucket
= *startbucket
;
2153 for (bucket
= *startbucket
; bucket
;
2154 oldnext
= &(bucket
->next
), bucket
= *oldnext
)
2156 if (bucket
->src_addr
== bb_dst
2157 && bucket
->dst_addr
== bb_src
)
2160 *oldnext
= bucket
->next
;
2161 bucket
->next
= *startbucket
;
2162 *startbucket
= bucket
;
2167 bucket
= (struct bb_edge
*) malloc (sizeof (struct bb_edge
));
2173 fprintf (stderr
, "Profiler: out of memory\n");
2180 bucket
->src_addr
= bb_dst
;
2181 bucket
->dst_addr
= bb_src
;
2182 bucket
->next
= *startbucket
;
2183 *startbucket
= bucket
;
2196 /* Called upon entering the first function of a file. */
2199 __bb_init_file (struct bb
*blocks
)
2202 const struct bb_func
*p
;
2203 long blk
, ncounts
= blocks
->ncounts
;
2204 const char **functions
= blocks
->functions
;
2206 /* Set up linked list. */
2207 blocks
->zero_word
= 1;
2208 blocks
->next
= bb_head
;
2213 || !(blocks
->flags
= (char *) malloc (sizeof (char) * blocks
->ncounts
)))
2216 for (blk
= 0; blk
< ncounts
; blk
++)
2217 blocks
->flags
[blk
] = 0;
2219 for (blk
= 0; blk
< ncounts
; blk
++)
2221 for (p
= bb_func_head
; p
; p
= p
->next
)
2223 if (!strcmp (p
->funcname
, functions
[blk
])
2224 && (!p
->filename
|| !strcmp (p
->filename
, blocks
->filename
)))
2226 blocks
->flags
[blk
] |= p
->mode
;
2233 /* Called when exiting from a function. */
2236 __bb_trace_ret (void)
2239 MACHINE_STATE_SAVE("2")
2243 if ((bb_mode
& 12) && bb_stacksize
> bb_callcount
)
2245 bb_src
= bb_stack
[bb_callcount
];
2247 __bb_trace_func_ret ();
2253 MACHINE_STATE_RESTORE("2")
2257 /* Called when entering a function. */
2260 __bb_init_trace_func (struct bb
*blocks
, unsigned long blockno
)
2262 static int trace_init
= 0;
2264 MACHINE_STATE_SAVE("3")
2266 if (!blocks
->zero_word
)
2273 __bb_init_file (blocks
);
2283 if (bb_callcount
>= bb_stacksize
)
2285 size_t newsize
= bb_callcount
+ 100;
2287 bb_stack
= (unsigned long *) realloc (bb_stack
, newsize
);
2292 fprintf (stderr
, "Profiler: out of memory\n");
2296 goto stack_overflow
;
2298 bb_stacksize
= newsize
;
2300 bb_stack
[bb_callcount
] = bb_src
;
2311 else if (blocks
->flags
&& (blocks
->flags
[blockno
] & TRACE_ON
))
2317 bb_stack
[bb_callcount
] = bb_src
;
2320 MACHINE_STATE_RESTORE("3")
2323 #endif /* not inhibit_libc */
2324 #endif /* not BLOCK_PROFILER_CODE */
2327 #ifdef L_clear_cache
2328 /* Clear part of an instruction cache. */
2330 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
2333 __clear_cache (char *beg
__attribute__((__unused__
)),
2334 char *end
__attribute__((__unused__
)))
2336 #ifdef CLEAR_INSN_CACHE
2337 CLEAR_INSN_CACHE (beg
, end
);
2339 #ifdef INSN_CACHE_SIZE
2340 static char array
[INSN_CACHE_SIZE
+ INSN_CACHE_PLANE_SIZE
+ INSN_CACHE_LINE_WIDTH
];
2341 static int initialized
;
2345 typedef (*function_ptr
) (void);
2347 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
2348 /* It's cheaper to clear the whole cache.
2349 Put in a series of jump instructions so that calling the beginning
2350 of the cache will clear the whole thing. */
2354 int ptr
= (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
2355 & -INSN_CACHE_LINE_WIDTH
);
2356 int end_ptr
= ptr
+ INSN_CACHE_SIZE
;
2358 while (ptr
< end_ptr
)
2360 *(INSTRUCTION_TYPE
*)ptr
2361 = JUMP_AHEAD_INSTRUCTION
+ INSN_CACHE_LINE_WIDTH
;
2362 ptr
+= INSN_CACHE_LINE_WIDTH
;
2364 *(INSTRUCTION_TYPE
*) (ptr
- INSN_CACHE_LINE_WIDTH
) = RETURN_INSTRUCTION
;
2369 /* Call the beginning of the sequence. */
2370 (((function_ptr
) (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
2371 & -INSN_CACHE_LINE_WIDTH
))
2374 #else /* Cache is large. */
2378 int ptr
= (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
2379 & -INSN_CACHE_LINE_WIDTH
);
2381 while (ptr
< (int) array
+ sizeof array
)
2383 *(INSTRUCTION_TYPE
*)ptr
= RETURN_INSTRUCTION
;
2384 ptr
+= INSN_CACHE_LINE_WIDTH
;
2390 /* Find the location in array that occupies the same cache line as BEG. */
2392 offset
= ((int) beg
& -INSN_CACHE_LINE_WIDTH
) & (INSN_CACHE_PLANE_SIZE
- 1);
2393 start_addr
= (((int) (array
+ INSN_CACHE_PLANE_SIZE
- 1)
2394 & -INSN_CACHE_PLANE_SIZE
)
2397 /* Compute the cache alignment of the place to stop clearing. */
2398 #if 0 /* This is not needed for gcc's purposes. */
2399 /* If the block to clear is bigger than a cache plane,
2400 we clear the entire cache, and OFFSET is already correct. */
2401 if (end
< beg
+ INSN_CACHE_PLANE_SIZE
)
2403 offset
= (((int) (end
+ INSN_CACHE_LINE_WIDTH
- 1)
2404 & -INSN_CACHE_LINE_WIDTH
)
2405 & (INSN_CACHE_PLANE_SIZE
- 1));
2407 #if INSN_CACHE_DEPTH > 1
2408 end_addr
= (start_addr
& -INSN_CACHE_PLANE_SIZE
) + offset
;
2409 if (end_addr
<= start_addr
)
2410 end_addr
+= INSN_CACHE_PLANE_SIZE
;
2412 for (plane
= 0; plane
< INSN_CACHE_DEPTH
; plane
++)
2414 int addr
= start_addr
+ plane
* INSN_CACHE_PLANE_SIZE
;
2415 int stop
= end_addr
+ plane
* INSN_CACHE_PLANE_SIZE
;
2417 while (addr
!= stop
)
2419 /* Call the return instruction at ADDR. */
2420 ((function_ptr
) addr
) ();
2422 addr
+= INSN_CACHE_LINE_WIDTH
;
2425 #else /* just one plane */
2428 /* Call the return instruction at START_ADDR. */
2429 ((function_ptr
) start_addr
) ();
2431 start_addr
+= INSN_CACHE_LINE_WIDTH
;
2433 while ((start_addr
% INSN_CACHE_SIZE
) != offset
);
2434 #endif /* just one plane */
2435 #endif /* Cache is large */
2436 #endif /* Cache exists */
2437 #endif /* CLEAR_INSN_CACHE */
2440 #endif /* L_clear_cache */
2444 /* Jump to a trampoline, loading the static chain address. */
2446 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
2459 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
2463 mprotect (char *addr
, int len
, int prot
)
2480 if (VirtualProtect (addr
, len
, np
, &op
))
2486 #endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
2488 #ifdef TRANSFER_FROM_TRAMPOLINE
2489 TRANSFER_FROM_TRAMPOLINE
2492 #if defined (NeXT) && defined (__MACH__)
2494 /* Make stack executable so we can call trampolines on stack.
2495 This is called from INITIALIZE_TRAMPOLINE in next.h. */
2499 #include <mach/mach.h>
2503 __enable_execute_stack (char *addr
)
2506 char *eaddr
= addr
+ TRAMPOLINE_SIZE
;
2507 vm_address_t a
= (vm_address_t
) addr
;
2509 /* turn on execute access on stack */
2510 r
= vm_protect (task_self (), a
, TRAMPOLINE_SIZE
, FALSE
, VM_PROT_ALL
);
2511 if (r
!= KERN_SUCCESS
)
2513 mach_error("vm_protect VM_PROT_ALL", r
);
2517 /* We inline the i-cache invalidation for speed */
2519 #ifdef CLEAR_INSN_CACHE
2520 CLEAR_INSN_CACHE (addr
, eaddr
);
2522 __clear_cache ((int) addr
, (int) eaddr
);
2526 #endif /* defined (NeXT) && defined (__MACH__) */
2530 /* Make stack executable so we can call trampolines on stack.
2531 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
2533 #include <sys/mman.h>
2534 #include <sys/vmparam.h>
2535 #include <machine/machparam.h>
2538 __enable_execute_stack (void)
2541 static unsigned lowest
= USRSTACK
;
2542 unsigned current
= (unsigned) &fp
& -NBPG
;
2544 if (lowest
> current
)
2546 unsigned len
= lowest
- current
;
2547 mremap (current
, &len
, PROT_READ
| PROT_WRITE
| PROT_EXEC
, MAP_PRIVATE
);
2551 /* Clear instruction cache in case an old trampoline is in it. */
2554 #endif /* __convex__ */
2558 /* Modified from the convex -code above. */
2560 #include <sys/param.h>
2562 #include <sys/m88kbcs.h>
2565 __enable_execute_stack (void)
2568 static unsigned long lowest
= USRSTACK
;
2569 unsigned long current
= (unsigned long) &save_errno
& -NBPC
;
2571 /* Ignore errno being set. memctl sets errno to EINVAL whenever the
2572 address is seen as 'negative'. That is the case with the stack. */
2575 if (lowest
> current
)
2577 unsigned len
=lowest
-current
;
2578 memctl(current
,len
,MCT_TEXT
);
2582 memctl(current
,NBPC
,MCT_TEXT
);
2586 #endif /* __sysV88__ */
2590 #include <sys/signal.h>
2593 /* Motorola forgot to put memctl.o in the libp version of libc881.a,
2594 so define it here, because we need it in __clear_insn_cache below */
2595 /* On older versions of this OS, no memctl or MCT_TEXT are defined;
2596 hence we enable this stuff only if MCT_TEXT is #define'd. */
2611 /* Clear instruction cache so we can call trampolines on stack.
2612 This is called from FINALIZE_TRAMPOLINE in mot3300.h. */
2615 __clear_insn_cache (void)
2620 /* Preserve errno, because users would be surprised to have
2621 errno changing without explicitly calling any system-call. */
2624 /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache.
2625 No need to use an address derived from _start or %sp, as 0 works also. */
2626 memctl(0, 4096, MCT_TEXT
);
2631 #endif /* __sysV68__ */
2635 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2637 #include <sys/mman.h>
2638 #include <sys/types.h>
2639 #include <sys/param.h>
2640 #include <sys/vmmac.h>
2642 /* Modified from the convex -code above.
2643 mremap promises to clear the i-cache. */
2646 __enable_execute_stack (void)
2649 if (mprotect (((unsigned int)&fp
/PAGSIZ
)*PAGSIZ
, PAGSIZ
,
2650 PROT_READ
|PROT_WRITE
|PROT_EXEC
))
2652 perror ("mprotect in __enable_execute_stack");
2657 #endif /* __pyr__ */
2659 #if defined (sony_news) && defined (SYSTYPE_BSD)
2662 #include <sys/types.h>
2663 #include <sys/param.h>
2664 #include <syscall.h>
2665 #include <machine/sysnews.h>
2667 /* cacheflush function for NEWS-OS 4.2.
2668 This function is called from trampoline-initialize code
2669 defined in config/mips/mips.h. */
2672 cacheflush (char *beg
, int size
, int flag
)
2674 if (syscall (SYS_sysnews
, NEWS_CACHEFLUSH
, beg
, size
, FLUSH_BCACHE
))
2676 perror ("cache_flush");
2682 #endif /* sony_news */
2683 #endif /* L_trampoline */
2688 #include "gbl-ctors.h"
2689 /* Some systems use __main in a way incompatible with its use in gcc, in these
2690 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2691 give the same symbol without quotes for an alternative entry point. You
2692 must define both, or neither. */
2694 #define NAME__MAIN "__main"
2695 #define SYMBOL__MAIN __main
2698 #ifdef INIT_SECTION_ASM_OP
2699 #undef HAS_INIT_SECTION
2700 #define HAS_INIT_SECTION
2703 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
2705 /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
2706 code to run constructors. In that case, we need to handle EH here, too. */
2708 #ifdef EH_FRAME_SECTION
2709 #include "unwind-dw2-fde.h"
2710 extern unsigned char __EH_FRAME_BEGIN__
[];
2713 /* Run all the global destructors on exit from the program. */
2716 __do_global_dtors (void)
2718 #ifdef DO_GLOBAL_DTORS_BODY
2719 DO_GLOBAL_DTORS_BODY
;
2721 static func_ptr
*p
= __DTOR_LIST__
+ 1;
2728 #if defined (EH_FRAME_SECTION) && !defined (HAS_INIT_SECTION)
2730 static int completed
= 0;
2734 __deregister_frame_info (__EH_FRAME_BEGIN__
);
2741 #ifndef HAS_INIT_SECTION
2742 /* Run all the global constructors on entry to the program. */
2745 __do_global_ctors (void)
2747 #ifdef EH_FRAME_SECTION
2749 static struct object object
;
2750 __register_frame_info (__EH_FRAME_BEGIN__
, &object
);
2753 DO_GLOBAL_CTORS_BODY
;
2754 atexit (__do_global_dtors
);
2756 #endif /* no HAS_INIT_SECTION */
2758 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
2759 /* Subroutine called automatically by `main'.
2760 Compiling a global function named `main'
2761 produces an automatic call to this function at the beginning.
2763 For many systems, this routine calls __do_global_ctors.
2764 For systems which support a .init section we use the .init section
2765 to run __do_global_ctors, so we need not do anything here. */
2770 /* Support recursive calls to `main': run initializers just once. */
2771 static int initialized
;
2775 __do_global_ctors ();
2778 #endif /* no HAS_INIT_SECTION or INVOKE__main */
2780 #endif /* L__main */
2781 #endif /* __CYGWIN__ */
2785 #include "gbl-ctors.h"
2787 /* Provide default definitions for the lists of constructors and
2788 destructors, so that we don't get linker errors. These symbols are
2789 intentionally bss symbols, so that gld and/or collect will provide
2790 the right values. */
2792 /* We declare the lists here with two elements each,
2793 so that they are valid empty lists if no other definition is loaded.
2795 If we are using the old "set" extensions to have the gnu linker
2796 collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
2797 must be in the bss/common section.
2799 Long term no port should use those extensions. But many still do. */
2800 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
2801 #if defined (ASM_OUTPUT_CONSTRUCTOR) || defined (USE_COLLECT2)
2802 func_ptr __CTOR_LIST__
[2] = {0, 0};
2803 func_ptr __DTOR_LIST__
[2] = {0, 0};
2805 func_ptr __CTOR_LIST__
[2];
2806 func_ptr __DTOR_LIST__
[2];
2808 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
2809 #endif /* L_ctors */
2813 #include "gbl-ctors.h"
2821 static func_ptr
*atexit_chain
= 0;
2822 static long atexit_chain_length
= 0;
2823 static volatile long last_atexit_chain_slot
= -1;
2826 atexit (func_ptr func
)
2828 if (++last_atexit_chain_slot
== atexit_chain_length
)
2830 atexit_chain_length
+= 32;
2832 atexit_chain
= (func_ptr
*) realloc (atexit_chain
, atexit_chain_length
2833 * sizeof (func_ptr
));
2835 atexit_chain
= (func_ptr
*) malloc (atexit_chain_length
2836 * sizeof (func_ptr
));
2839 atexit_chain_length
= 0;
2840 last_atexit_chain_slot
= -1;
2845 atexit_chain
[last_atexit_chain_slot
] = func
;
2849 extern void _cleanup (void);
2850 extern void _exit (int) __attribute__ ((__noreturn__
));
2857 for ( ; last_atexit_chain_slot
-- >= 0; )
2859 (*atexit_chain
[last_atexit_chain_slot
+ 1]) ();
2860 atexit_chain
[last_atexit_chain_slot
+ 1] = 0;
2862 free (atexit_chain
);
2875 /* Simple; we just need a wrapper for ON_EXIT. */
2877 atexit (func_ptr func
)
2879 return ON_EXIT (func
);
2882 #endif /* ON_EXIT */
2883 #endif /* NEED_ATEXIT */