]>
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 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
21 /* As a special exception, if you link this library with files
22 compiled with GCC to produce an executable, this does not cause
23 the resulting executable to be covered by the GNU General Public License.
24 This exception does not however invalidate any other reasons why
25 the executable file might be covered by the GNU General Public License. */
27 /* It is incorrect to include config.h here, because this file is being
28 compiled for the target, and hence definitions concerning only the host
36 /* Don't use `fancy_abort' here even if config.h says to use it. */
41 /* In the first part of this file, we are interfacing to calls generated
42 by the compiler itself. These calls pass values into these routines
43 which have very specific modes (rather than very specific types), and
44 these compiler-generated calls also expect any return values to have
45 very specific modes (rather than very specific types). Thus, we need
46 to avoid using regular C language type names in this part of the file
47 because the sizes for those types can be configured to be anything.
48 Instead we use the following special type names. */
50 typedef unsigned int UQItype
__attribute__ ((mode (QI
)));
51 typedef int SItype
__attribute__ ((mode (SI
)));
52 typedef unsigned int USItype
__attribute__ ((mode (SI
)));
53 typedef int DItype
__attribute__ ((mode (DI
)));
54 typedef unsigned int UDItype
__attribute__ ((mode (DI
)));
55 typedef float SFtype
__attribute__ ((mode (SF
)));
56 typedef float DFtype
__attribute__ ((mode (DF
)));
58 typedef float XFtype
__attribute__ ((mode (XF
)));
60 #if LONG_DOUBLE_TYPE_SIZE == 128
61 typedef float TFtype
__attribute__ ((mode (TF
)));
64 /* Make sure that we don't accidentaly use any normal C language built-in
65 type names in the first part of this file. Instead we want to use *only*
66 the type names defined above. The following macro definitions insure
67 that if we *do* accidently use soem normal C language built-in type name,
68 we will get a syntax error. */
70 #define char bogus_type
71 #define short bogus_type
72 #define int bogus_type
73 #define long bogus_type
74 #define unsigned bogus_type
75 #define float bogus_type
76 #define double bogus_type
78 #define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
80 /* DIstructs are pairs of SItype values in the order determined by
84 struct DIstruct
{SItype high
, low
;};
86 struct DIstruct
{SItype low
, high
;};
89 /* We need this union to unpack/pack DImode values, since we don't have
90 any arithmetic yet. Incoming DImode parameters are stored into the
91 `ll' field, and the unpacked result is read from the struct `s'. */
99 #if defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_using_sdiv)
101 #include "longlong.h"
103 #endif /* udiv or mul */
105 extern DItype
__fixunssfdi (SFtype a
);
106 extern DItype
__fixunsdfdi (DFtype a
);
108 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
109 #if defined (L_divdi3) || defined (L_moddi3)
122 w
.s
.high
= -uu
.s
.high
- ((USItype
) w
.s
.low
> 0);
143 bm
= (sizeof (SItype
) * BITS_PER_UNIT
) - b
;
147 w
.s
.high
= (USItype
)uu
.s
.low
<< -bm
;
151 USItype carries
= (USItype
)uu
.s
.low
>> bm
;
152 w
.s
.low
= (USItype
)uu
.s
.low
<< b
;
153 w
.s
.high
= ((USItype
)uu
.s
.high
<< b
) | carries
;
175 bm
= (sizeof (SItype
) * BITS_PER_UNIT
) - b
;
179 w
.s
.low
= (USItype
)uu
.s
.high
>> -bm
;
183 USItype carries
= (USItype
)uu
.s
.high
<< bm
;
184 w
.s
.high
= (USItype
)uu
.s
.high
>> b
;
185 w
.s
.low
= ((USItype
)uu
.s
.low
>> b
) | carries
;
207 bm
= (sizeof (SItype
) * BITS_PER_UNIT
) - b
;
211 w
.s
.high
= (USItype
)uu
.s
.low
<< -bm
;
215 USItype carries
= (USItype
)uu
.s
.low
>> bm
;
216 w
.s
.low
= (USItype
)uu
.s
.low
<< b
;
217 w
.s
.high
= ((USItype
)uu
.s
.high
<< b
) | carries
;
239 bm
= (sizeof (SItype
) * BITS_PER_UNIT
) - b
;
242 /* w.s.high = 1..1 or 0..0 */
243 w
.s
.high
= uu
.s
.high
>> (sizeof (SItype
) * BITS_PER_UNIT
- 1);
244 w
.s
.low
= uu
.s
.high
>> -bm
;
248 USItype carries
= (USItype
)uu
.s
.high
<< bm
;
249 w
.s
.high
= uu
.s
.high
>> b
;
250 w
.s
.low
= ((USItype
)uu
.s
.low
>> b
) | carries
;
268 w
.ll
= __umulsidi3 (uu
.s
.low
, vv
.s
.low
);
269 w
.s
.high
+= ((USItype
) uu
.s
.low
* (USItype
) vv
.s
.high
270 + (USItype
) uu
.s
.high
* (USItype
) vv
.s
.low
);
276 #ifdef L_udiv_using_sdiv
278 __udiv_using_sdiv (rp
, a1
, a0
, d
)
279 USItype
*rp
, a1
, a0
, d
;
286 if (a1
< d
- a1
- (a0
>> 31))
288 /* dividend, divisor, and quotient are nonnegative */
289 sdiv_qrnnd (q
, r
, a1
, a0
, d
);
293 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
294 sub_ddmmss (c1
, c0
, a1
, a0
, d
>> 1, d
<< 31);
295 /* Divide (c1*2^32 + c0) by d */
296 sdiv_qrnnd (q
, r
, c1
, c0
, d
);
297 /* Add 2^31 to quotient */
303 b1
= d
>> 1; /* d/2, between 2^30 and 2^31 - 1 */
304 c1
= a1
>> 1; /* A/2 */
305 c0
= (a1
<< 31) + (a0
>> 1);
307 if (a1
< b1
) /* A < 2^32*b1, so A/2 < 2^31*b1 */
309 sdiv_qrnnd (q
, r
, c1
, c0
, b1
); /* (A/2) / (d/2) */
311 r
= 2*r
+ (a0
& 1); /* Remainder from A/(2*b1) */
328 else if (c1
< b1
) /* So 2^31 <= (A/2)/b1 < 2^32 */
331 c0
= ~c0
; /* logical NOT */
333 sdiv_qrnnd (q
, r
, c1
, c0
, b1
); /* (A/2) / (d/2) */
335 q
= ~q
; /* (A/2)/b1 */
338 r
= 2*r
+ (a0
& 1); /* A/(2*b1) */
356 else /* Implies c1 = b1 */
357 { /* Hence a1 = d - 1 = 2*b1 - 1 */
377 static const UQItype __clz_tab
[] =
379 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,
380 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,
381 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,
382 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,
383 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,
384 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,
385 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,
386 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,
390 __udivmoddi4 (n
, d
, rp
)
397 USItype d0
, d1
, n0
, n1
, n2
;
409 #if !UDIV_NEEDS_NORMALIZATION
416 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
419 /* Remainder in n0. */
426 d0
= 1 / d0
; /* Divide intentionally by zero. */
428 udiv_qrnnd (q1
, n1
, 0, n1
, d0
);
429 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
431 /* Remainder in n0. */
442 #else /* UDIV_NEEDS_NORMALIZATION */
450 count_leading_zeros (bm
, d0
);
454 /* Normalize, i.e. make the most significant bit of the
458 n1
= (n1
<< bm
) | (n0
>> (SI_TYPE_SIZE
- bm
));
462 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
465 /* Remainder in n0 >> bm. */
472 d0
= 1 / d0
; /* Divide intentionally by zero. */
474 count_leading_zeros (bm
, d0
);
478 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
479 conclude (the most significant bit of n1 is set) /\ (the
480 leading quotient digit q1 = 1).
482 This special case is necessary, not an optimization.
483 (Shifts counts of SI_TYPE_SIZE are undefined.) */
492 b
= SI_TYPE_SIZE
- bm
;
496 n1
= (n1
<< bm
) | (n0
>> b
);
499 udiv_qrnnd (q1
, n1
, n2
, n1
, d0
);
504 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
506 /* Remainder in n0 >> bm. */
516 #endif /* UDIV_NEEDS_NORMALIZATION */
527 /* Remainder in n1n0. */
539 count_leading_zeros (bm
, d1
);
542 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
543 conclude (the most significant bit of n1 is set) /\ (the
544 quotient digit q0 = 0 or 1).
546 This special case is necessary, not an optimization. */
548 /* The condition on the next line takes advantage of that
549 n1 >= d1 (true due to program flow). */
550 if (n1
> d1
|| n0
>= d0
)
553 sub_ddmmss (n1
, n0
, n1
, n0
, d1
, d0
);
572 b
= SI_TYPE_SIZE
- bm
;
574 d1
= (d1
<< bm
) | (d0
>> b
);
577 n1
= (n1
<< bm
) | (n0
>> b
);
580 udiv_qrnnd (q0
, n1
, n2
, n1
, d1
);
581 umul_ppmm (m1
, m0
, q0
, d0
);
583 if (m1
> n1
|| (m1
== n1
&& m0
> n0
))
586 sub_ddmmss (m1
, m0
, m1
, m0
, d1
, d0
);
591 /* Remainder in (n1n0 - m1m0) >> bm. */
594 sub_ddmmss (n1
, n0
, n1
, n0
, m1
, m0
);
595 rr
.s
.low
= (n1
<< b
) | (n0
>> bm
);
596 rr
.s
.high
= n1
>> bm
;
610 UDItype
__udivmoddi4 ();
624 uu
.ll
= __negdi2 (uu
.ll
);
627 vv
.ll
= __negdi2 (vv
.ll
);
629 w
= __udivmoddi4 (uu
.ll
, vv
.ll
, (UDItype
*) 0);
638 UDItype
__udivmoddi4 ();
652 uu
.ll
= __negdi2 (uu
.ll
);
654 vv
.ll
= __negdi2 (vv
.ll
);
656 (void) __udivmoddi4 (uu
.ll
, vv
.ll
, &w
);
665 UDItype
__udivmoddi4 ();
672 (void) __udivmoddi4 (u
, v
, &w
);
679 UDItype
__udivmoddi4 ();
684 return __udivmoddi4 (n
, d
, (UDItype
*) 0);
695 au
.ll
= a
, bu
.ll
= b
;
697 if (au
.s
.high
< bu
.s
.high
)
699 else if (au
.s
.high
> bu
.s
.high
)
701 if ((USItype
) au
.s
.low
< (USItype
) bu
.s
.low
)
703 else if ((USItype
) au
.s
.low
> (USItype
) bu
.s
.low
)
716 au
.ll
= a
, bu
.ll
= b
;
718 if ((USItype
) au
.s
.high
< (USItype
) bu
.s
.high
)
720 else if ((USItype
) au
.s
.high
> (USItype
) bu
.s
.high
)
722 if ((USItype
) au
.s
.low
< (USItype
) bu
.s
.low
)
724 else if ((USItype
) au
.s
.low
> (USItype
) bu
.s
.low
)
730 #if defined(L_fixunstfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
731 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
732 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
744 /* Compute high word of result, as a flonum. */
745 b
= (a
/ HIGH_WORD_COEFF
);
746 /* Convert that to fixed (but not to DItype!),
747 and shift it into the high word. */
750 /* Remove high part from the TFtype, leaving the low part as flonum. */
752 /* Convert that to fixed (but not to DItype!) and add it in.
753 Sometimes A comes out negative. This is significant, since
754 A has more bits than a long int does. */
756 v
-= (USItype
) (- a
);
763 #if defined(L_fixtfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
769 return - __fixunstfdi (-a
);
770 return __fixunstfdi (a
);
775 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
776 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
788 /* Compute high word of result, as a flonum. */
789 b
= (a
/ HIGH_WORD_COEFF
);
790 /* Convert that to fixed (but not to DItype!),
791 and shift it into the high word. */
794 /* Remove high part from the DFtype, leaving the low part as flonum. */
796 /* Convert that to fixed (but not to DItype!) and add it in.
797 Sometimes A comes out negative. This is significant, since
798 A has more bits than a long int does. */
800 v
-= (USItype
) (- a
);
813 return - __fixunsdfdi (-a
);
814 return __fixunsdfdi (a
);
819 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
820 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
823 __fixunssfdi (SFtype original_a
)
825 /* Convert the SFtype to a DFtype, because that is surely not going
826 to lose any bits. Some day someone else can write a faster version
827 that avoids converting to DFtype, and verify it really works right. */
828 DFtype a
= original_a
;
835 /* Compute high word of result, as a flonum. */
836 b
= (a
/ HIGH_WORD_COEFF
);
837 /* Convert that to fixed (but not to DItype!),
838 and shift it into the high word. */
841 /* Remove high part from the DFtype, leaving the low part as flonum. */
843 /* Convert that to fixed (but not to DItype!) and add it in.
844 Sometimes A comes out negative. This is significant, since
845 A has more bits than a long int does. */
847 v
-= (USItype
) (- a
);
859 return - __fixunssfdi (-a
);
860 return __fixunssfdi (a
);
864 #if defined(L_floatditf) && (LONG_DOUBLE_TYPE_SIZE == 128)
865 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
866 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
867 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
879 d
= (USItype
) (u
>> WORD_SIZE
);
880 d
*= HIGH_HALFWORD_COEFF
;
881 d
*= HIGH_HALFWORD_COEFF
;
882 d
+= (USItype
) (u
& (HIGH_WORD_COEFF
- 1));
884 return (negate
? -d
: d
);
889 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
890 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
891 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
903 d
= (USItype
) (u
>> WORD_SIZE
);
904 d
*= HIGH_HALFWORD_COEFF
;
905 d
*= HIGH_HALFWORD_COEFF
;
906 d
+= (USItype
) (u
& (HIGH_WORD_COEFF
- 1));
908 return (negate
? -d
: d
);
913 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
914 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
915 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
927 f
= (USItype
) (u
>> WORD_SIZE
);
928 f
*= HIGH_HALFWORD_COEFF
;
929 f
*= HIGH_HALFWORD_COEFF
;
930 f
+= (USItype
) (u
& (HIGH_WORD_COEFF
- 1));
932 return (negate
? -f
: f
);
943 if (a
>= - (DFtype
) LONG_MIN
)
944 return (SItype
) (a
+ LONG_MIN
) - LONG_MIN
;
953 __fixunssfsi (SFtype a
)
955 if (a
>= - (SFtype
) LONG_MIN
)
956 return (SItype
) (a
+ LONG_MIN
) - LONG_MIN
;
961 /* From here on down, the routines use normal data types. */
963 #define SItype bogus_type
964 #define USItype bogus_type
965 #define DItype bogus_type
966 #define UDItype bogus_type
967 #define SFtype bogus_type
968 #define DFtype bogus_type
980 #if defined(__svr4__) || defined(__alliant__)
984 /* The Alliant needs the added underscore. */
985 asm (".globl __builtin_saveregs");
986 asm ("__builtin_saveregs:");
987 asm (".globl ___builtin_saveregs");
988 asm ("___builtin_saveregs:");
990 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
991 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
992 area and also for a new va_list
994 /* Save all argument registers in the arg reg save area. The
995 arg reg save area must have the following layout (according
1007 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
1008 asm (" fst.q %f12,16(%sp)");
1010 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
1011 asm (" st.l %r17,36(%sp)");
1012 asm (" st.l %r18,40(%sp)");
1013 asm (" st.l %r19,44(%sp)");
1014 asm (" st.l %r20,48(%sp)");
1015 asm (" st.l %r21,52(%sp)");
1016 asm (" st.l %r22,56(%sp)");
1017 asm (" st.l %r23,60(%sp)");
1018 asm (" st.l %r24,64(%sp)");
1019 asm (" st.l %r25,68(%sp)");
1020 asm (" st.l %r26,72(%sp)");
1021 asm (" st.l %r27,76(%sp)");
1023 asm (" adds 80,%sp,%r16"); /* compute the address of the new
1024 va_list structure. Put in into
1025 r16 so that it will be returned
1028 /* Initialize all fields of the new va_list structure. This
1029 structure looks like:
1032 unsigned long ireg_used;
1033 unsigned long freg_used;
1039 asm (" st.l %r0, 0(%r16)"); /* nfixed */
1040 asm (" st.l %r0, 4(%r16)"); /* nfloating */
1041 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
1042 asm (" bri %r1"); /* delayed return */
1043 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
1045 #else /* not __SVR4__ */
1049 asm (".globl ___builtin_saveregs");
1050 asm ("___builtin_saveregs:");
1051 asm (" mov sp,r30");
1052 asm (" andnot 0x0f,sp,sp");
1053 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
1055 /* Fill in the __va_struct. */
1056 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
1057 asm (" st.l r17, 4(sp)"); /* int fixed[12] */
1058 asm (" st.l r18, 8(sp)");
1059 asm (" st.l r19,12(sp)");
1060 asm (" st.l r20,16(sp)");
1061 asm (" st.l r21,20(sp)");
1062 asm (" st.l r22,24(sp)");
1063 asm (" st.l r23,28(sp)");
1064 asm (" st.l r24,32(sp)");
1065 asm (" st.l r25,36(sp)");
1066 asm (" st.l r26,40(sp)");
1067 asm (" st.l r27,44(sp)");
1069 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
1070 asm (" fst.q f12,64(sp)"); /* int floating[8] */
1072 /* Fill in the __va_ctl. */
1073 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
1074 asm (" st.l r28,84(sp)"); /* pointer to more args */
1075 asm (" st.l r0, 88(sp)"); /* nfixed */
1076 asm (" st.l r0, 92(sp)"); /* nfloating */
1078 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
1080 asm (" mov r30,sp");
1081 /* recover stack and pass address to start
1083 #endif /* not __SVR4__ */
1084 #else /* not __i860__ */
1086 asm (".global __builtin_saveregs");
1087 asm ("__builtin_saveregs:");
1088 asm (".global ___builtin_saveregs");
1089 asm ("___builtin_saveregs:");
1090 #ifdef NEED_PROC_COMMAND
1093 asm ("st %i0,[%fp+68]");
1094 asm ("st %i1,[%fp+72]");
1095 asm ("st %i2,[%fp+76]");
1096 asm ("st %i3,[%fp+80]");
1097 asm ("st %i4,[%fp+84]");
1099 asm ("st %i5,[%fp+88]");
1100 #ifdef NEED_TYPE_COMMAND
1101 asm (".type __builtin_saveregs,#function");
1102 asm (".size __builtin_saveregs,.-__builtin_saveregs");
1104 #else /* not __sparc__ */
1105 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1108 asm (" .ent __builtin_saveregs");
1109 asm (" .globl __builtin_saveregs");
1110 asm ("__builtin_saveregs:");
1111 asm (" sw $4,0($30)");
1112 asm (" sw $5,4($30)");
1113 asm (" sw $6,8($30)");
1114 asm (" sw $7,12($30)");
1116 asm (" .end __builtin_saveregs");
1117 #else /* not __mips__, etc. */
1118 __builtin_saveregs ()
1122 #endif /* not __mips__ */
1123 #endif /* not __sparc__ */
1124 #endif /* not __i860__ */
1128 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1130 /* This is used by the `assert' macro. */
1132 __eprintf (string
, expression
, line
, filename
)
1134 const char *expression
;
1136 const char *filename
;
1138 fprintf (stderr
, string
, expression
, line
, filename
);
1145 /* Avoid warning from ranlib about empty object file. */
1147 __bb_avoid_warning ()
1150 #if defined (__sun__) && defined (__mc68000__)
1161 extern int ___tcov_init
;
1163 __bb_init_func (blocks
)
1167 ___tcov_init_func ();
1169 ___bb_link (blocks
->filename
, blocks
->counts
, blocks
->ncounts
);
1175 /* frills for C++ */
1177 #ifdef L_builtin_new
1178 typedef void (*vfp
)(void);
1180 extern vfp __new_handler
;
1181 extern void *malloc ();
1191 (*__new_handler
) ();
1197 typedef void (*vfp
)(void);
1199 extern void *__builtin_new (size_t);
1200 static void default_new_handler (void);
1202 vfp __new_handler
= default_new_handler
;
1205 __builtin_vec_new (p
, maxindex
, size
, ctor
)
1209 void (*ctor
)(void *);
1212 size_t nelts
= maxindex
+ 1;
1216 p
= __builtin_new (nelts
* size
);
1220 for (i
= 0; i
< nelts
; i
++)
1230 __set_new_handler (handler
)
1235 prev_handler
= __new_handler
;
1236 if (handler
== 0) handler
= default_new_handler
;
1237 __new_handler
= handler
;
1238 return prev_handler
;
1242 set_new_handler (handler
)
1245 return __set_new_handler (handler
);
1248 #define MESSAGE "Virtual memory exceeded in `new'\n"
1251 default_new_handler ()
1253 /* don't use fprintf (stderr, ...) because it may need to call malloc. */
1254 /* This should really print the name of the program, but that is hard to
1255 do. We need a standard, clean way to get at the name. */
1256 write (2, MESSAGE
, sizeof (MESSAGE
));
1257 /* don't call exit () because that may call global destructors which
1258 may cause a loop. */
1263 #ifdef L_builtin_del
1264 typedef void (*vfp
)(void);
1267 __builtin_delete (ptr
)
1275 __builtin_vec_delete (ptr
, maxindex
, size
, dtor
, auto_delete_vec
, auto_delete
)
1279 void (*dtor
)(void *, int);
1283 size_t nelts
= maxindex
+ 1;
1286 ptr
+= nelts
* size
;
1288 for (i
= 0; i
< nelts
; i
++)
1291 (*dtor
) (ptr
, auto_delete
);
1294 if (auto_delete_vec
)
1295 __builtin_delete (p
);
1301 unsigned int __shtab
[] = {
1302 0x00000001, 0x00000002, 0x00000004, 0x00000008,
1303 0x00000010, 0x00000020, 0x00000040, 0x00000080,
1304 0x00000100, 0x00000200, 0x00000400, 0x00000800,
1305 0x00001000, 0x00002000, 0x00004000, 0x00008000,
1306 0x00010000, 0x00020000, 0x00040000, 0x00080000,
1307 0x00100000, 0x00200000, 0x00400000, 0x00800000,
1308 0x01000000, 0x02000000, 0x04000000, 0x08000000,
1309 0x10000000, 0x20000000, 0x40000000, 0x80000000
1313 #ifdef L_clear_cache
1314 /* Clear part of an instruction cache. */
1316 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1319 __clear_cache (beg
, end
)
1322 #ifdef INSN_CACHE_SIZE
1323 static char array
[INSN_CACHE_SIZE
+ INSN_CACHE_PLANE_SIZE
+ INSN_CACHE_LINE_WIDTH
];
1324 static int initialized
= 0;
1328 typedef (*function_ptr
) ();
1330 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1331 /* It's cheaper to clear the whole cache.
1332 Put in a series of jump instructions so that calling the beginning
1333 of the cache will clear the whole thing. */
1337 int ptr
= (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
1338 & -INSN_CACHE_LINE_WIDTH
);
1339 int end_ptr
= ptr
+ INSN_CACHE_SIZE
;
1341 while (ptr
< end_ptr
)
1343 *(INSTRUCTION_TYPE
*)ptr
1344 = JUMP_AHEAD_INSTRUCTION
+ INSN_CACHE_LINE_WIDTH
;
1345 ptr
+= INSN_CACHE_LINE_WIDTH
;
1347 *(INSTRUCTION_TYPE
*)(ptr
- INSN_CACHE_LINE_WIDTH
) = RETURN_INSTRUCTION
;
1352 /* Call the beginning of the sequence. */
1353 (((function_ptr
) (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
1354 & -INSN_CACHE_LINE_WIDTH
))
1357 #else /* Cache is large. */
1361 int ptr
= (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
1362 & -INSN_CACHE_LINE_WIDTH
);
1364 while (ptr
< (int) array
+ sizeof array
)
1366 *(INSTRUCTION_TYPE
*)ptr
= RETURN_INSTRUCTION
;
1367 ptr
+= INSN_CACHE_LINE_WIDTH
;
1373 /* Find the location in array that occupies the same cache line as BEG. */
1375 offset
= ((int) beg
& -INSN_CACHE_LINE_WIDTH
) & (INSN_CACHE_PLANE_SIZE
- 1);
1376 start_addr
= (((int) (array
+ INSN_CACHE_PLANE_SIZE
- 1)
1377 & -INSN_CACHE_PLANE_SIZE
)
1380 /* Compute the cache alignment of the place to stop clearing. */
1381 #if 0 /* This is not needed for gcc's purposes. */
1382 /* If the block to clear is bigger than a cache plane,
1383 we clear the entire cache, and OFFSET is already correct. */
1384 if (end
< beg
+ INSN_CACHE_PLANE_SIZE
)
1386 offset
= (((int) (end
+ INSN_CACHE_LINE_WIDTH
- 1)
1387 & -INSN_CACHE_LINE_WIDTH
)
1388 & (INSN_CACHE_PLANE_SIZE
- 1));
1390 #if INSN_CACHE_DEPTH > 1
1391 end_addr
= (start_addr
& -INSN_CACHE_PLANE_SIZE
) + offset
;
1392 if (end_addr
<= start_addr
)
1393 end_addr
+= INSN_CACHE_PLANE_SIZE
;
1395 for (plane
= 0; plane
< INSN_CACHE_DEPTH
; plane
++)
1397 int addr
= start_addr
+ plane
* INSN_CACHE_PLANE_SIZE
;
1398 int stop
= end_addr
+ plane
* INSN_CACHE_PLANE_SIZE
;
1400 while (addr
!= stop
)
1402 /* Call the return instruction at ADDR. */
1403 ((function_ptr
) addr
) ();
1405 addr
+= INSN_CACHE_LINE_WIDTH
;
1408 #else /* just one plane */
1411 /* Call the return instruction at START_ADDR. */
1412 ((function_ptr
) start_addr
) ();
1414 start_addr
+= INSN_CACHE_LINE_WIDTH
;
1416 while ((start_addr
% INSN_CACHE_SIZE
) != offset
);
1417 #endif /* just one plane */
1418 #endif /* Cache is large */
1419 #endif /* Cache exists */
1422 #endif /* L_clear_cache */
1426 /* Jump to a trampoline, loading the static chain address. */
1428 #ifdef TRANSFER_FROM_TRAMPOLINE
1429 TRANSFER_FROM_TRAMPOLINE
1434 /* Make stack executable so we can call trampolines on stack.
1435 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
1437 #include <sys/mman.h>
1438 #include <sys/vmparam.h>
1439 #include <machine/machparam.h>
1442 __enable_execute_stack ()
1445 static unsigned lowest
= USRSTACK
;
1446 unsigned current
= (unsigned) &fp
& -NBPG
;
1448 if (lowest
> current
)
1450 unsigned len
= lowest
- current
;
1451 mremap (current
, &len
, PROT_READ
| PROT_WRITE
| PROT_EXEC
, MAP_PRIVATE
);
1455 /* Clear instruction cache in case an old trampoline is in it. */
1458 #endif /* __convex__ */
1463 #include <sys/mman.h>
1464 #include <sys/types.h>
1465 #include <sys/param.h>
1466 #include <sys/vmmac.h>
1468 /* Modified from the convex -code above.
1469 mremap promises to clear the i-cache. */
1472 __enable_execute_stack ()
1475 if (mprotect (((unsigned int)&fp
/PAGSIZ
)*PAGSIZ
, PAGSIZ
,
1476 PROT_READ
|PROT_WRITE
|PROT_EXEC
))
1478 perror ("mprotect in __enable_execute_stack");
1483 #endif /* __pyr__ */
1484 #endif /* L_trampoline */
1488 #include "gbl-ctors.h"
1490 /* Run all the global destructors on exit from the program. */
1493 __do_global_dtors ()
1495 #ifdef DO_GLOBAL_DTORS_BODY
1496 DO_GLOBAL_DTORS_BODY
;
1498 unsigned nptrs
= (unsigned) __DTOR_LIST__
[0];
1501 /* Some systems place the number of pointers
1502 in the first word of the table.
1503 On other systems, that word is -1.
1504 In all cases, the table is null-terminated. */
1506 /* If the length is not recorded, count up to the null. */
1508 for (nptrs
= 0; __DTOR_LIST__
[nptrs
+ 1] != 0; nptrs
++);
1510 /* GNU LD format. */
1511 for (i
= nptrs
; i
>= 1; i
--)
1512 __DTOR_LIST__
[i
] ();
1516 #ifndef INIT_SECTION_ASM_OP
1517 /* Run all the global constructors on entry to the program. */
1520 #define ON_EXIT(a, b)
1522 /* Make sure the exit routine is pulled in to define the globals as
1523 bss symbols, just in case the linker does not automatically pull
1524 bss definitions from the library. */
1526 extern int _exit_dummy_decl
;
1527 int *_exit_dummy_ref
= &_exit_dummy_decl
;
1528 #endif /* ON_EXIT */
1531 __do_global_ctors ()
1533 DO_GLOBAL_CTORS_BODY
;
1534 ON_EXIT (__do_global_dtors
, 0);
1536 #endif /* no INIT_SECTION_ASM_OP */
1538 #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
1539 /* Subroutine called automatically by `main'.
1540 Compiling a global function named `main'
1541 produces an automatic call to this function at the beginning.
1543 For many systems, this routine calls __do_global_ctors.
1544 For systems which support a .init section we use the .init section
1545 to run __do_global_ctors, so we need not do anything here. */
1550 /* Support recursive calls to `main': run initializers just once. */
1551 static int initialized
= 0;
1555 __do_global_ctors ();
1558 #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
1560 #endif /* L__main */
1564 #include "gbl-ctors.h"
1566 /* Provide default definitions for the lists of constructors and
1567 destructors, so that we don't get linker errors. These symbols are
1568 intentionally bss symbols, so that gld and/or collect will provide
1569 the right values. */
1571 /* We declare the lists here with two elements each,
1572 so that they are valid empty lists if no other definition is loaded. */
1573 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
1574 func_ptr __CTOR_LIST__
[2];
1575 func_ptr __DTOR_LIST__
[2];
1576 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1580 /* If we have no known way of registering our own __do_global_dtors
1581 routine so that it will be invoked at program exit time, then we
1582 have to define our own exit routine which will get this to happen. */
1584 extern void __do_global_dtors ();
1585 extern void _cleanup ();
1586 extern void _exit ();
1592 __do_global_dtors ();
1602 int _exit_dummy_decl
= 0; /* prevent compiler & linker warnings */
1607 /* In a.out systems, we need to have these dummy constructor and destructor
1608 lists in the library.
1610 When using `collect', the first link will resolve __CTOR_LIST__
1611 and __DTOR_LIST__ to these symbols. We will then run "nm" on the
1612 result, build the correct __CTOR_LIST__ and __DTOR_LIST__, and relink.
1613 Since we don't do the second link if no constructors existed, these
1614 dummies must be fully functional empty lists.
1616 When using `gnu ld', these symbols will be used if there are no
1617 constructors. If there are constructors, the N_SETV symbol defined
1618 by the linker from the N_SETT's in input files will define __CTOR_LIST__
1619 and __DTOR_LIST__ rather than its being allocated as common storage
1620 by the definitions below.
1622 When using a linker that supports constructor and destructor segments,
1623 these definitions will not be used, since crtbegin.o and crtend.o
1624 (from crtstuff.c) will have already defined __CTOR_LIST__ and
1625 __DTOR_LIST__. The crt*.o files are passed directly to the linker
1626 on its command line, by gcc. */
1628 /* The list needs two elements: one is ignored (the old count); the
1629 second is the terminating zero. Since both values are zero, this
1630 declaration is not initialized, and it becomes `common'. */
1633 #include "gbl-ctors.h"
1634 func_ptr __CTOR_LIST__
[2];
1638 #include "gbl-ctors.h"
1639 func_ptr __DTOR_LIST__
[2];
This page took 0.115048 seconds and 6 git commands to generate.