]>
gcc.gnu.org Git - gcc.git/blob - gcc/libgcc2.c
8c70133dd895e69fadaa2d72cac6daa227255612
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
)));
57 typedef float XFtype
__attribute__ ((mode (XF
)));
58 typedef float TFtype
__attribute__ ((mode (TF
)));
60 /* Make sure that we don't accidentaly use any normal C language built-in
61 type names in the first part of this file. Instead we want to use *only*
62 the type names defined above. The following macro definitions insure
63 that if we *do* accidently use soem normal C language built-in type name,
64 we will get a syntax error. */
66 #define char bogus_type
67 #define short bogus_type
68 #define int bogus_type
69 #define long bogus_type
70 #define unsigned bogus_type
71 #define float bogus_type
72 #define double bogus_type
74 #define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
76 /* DIstructs are pairs of SItype values in the order determined by
80 struct DIstruct
{SItype high
, low
;};
82 struct DIstruct
{SItype low
, high
;};
85 /* We need this union to unpack/pack DImode values, since we don't have
86 any arithmetic yet. Incoming DImode parameters are stored into the
87 `ll' field, and the unpacked result is read from the struct `s'. */
95 #if defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_using_sdiv)
99 #endif /* udiv or mul */
101 extern DItype
__fixunssfdi (SFtype a
);
102 extern DItype
__fixunsdfdi (DFtype a
);
104 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
105 #if defined (L_divdi3) || defined (L_moddi3)
118 w
.s
.high
= -uu
.s
.high
- ((USItype
) w
.s
.low
> 0);
139 bm
= (sizeof (SItype
) * BITS_PER_UNIT
) - b
;
143 w
.s
.high
= (USItype
)uu
.s
.low
<< -bm
;
147 USItype carries
= (USItype
)uu
.s
.low
>> bm
;
148 w
.s
.low
= (USItype
)uu
.s
.low
<< b
;
149 w
.s
.high
= ((USItype
)uu
.s
.high
<< b
) | carries
;
171 bm
= (sizeof (SItype
) * BITS_PER_UNIT
) - b
;
175 w
.s
.low
= (USItype
)uu
.s
.high
>> -bm
;
179 USItype carries
= (USItype
)uu
.s
.high
<< bm
;
180 w
.s
.high
= (USItype
)uu
.s
.high
>> b
;
181 w
.s
.low
= ((USItype
)uu
.s
.low
>> b
) | carries
;
203 bm
= (sizeof (SItype
) * BITS_PER_UNIT
) - b
;
207 w
.s
.high
= (USItype
)uu
.s
.low
<< -bm
;
211 USItype carries
= (USItype
)uu
.s
.low
>> bm
;
212 w
.s
.low
= (USItype
)uu
.s
.low
<< b
;
213 w
.s
.high
= ((USItype
)uu
.s
.high
<< b
) | carries
;
235 bm
= (sizeof (SItype
) * BITS_PER_UNIT
) - b
;
238 /* w.s.high = 1..1 or 0..0 */
239 w
.s
.high
= uu
.s
.high
>> (sizeof (SItype
) * BITS_PER_UNIT
- 1);
240 w
.s
.low
= uu
.s
.high
>> -bm
;
244 USItype carries
= (USItype
)uu
.s
.high
<< bm
;
245 w
.s
.high
= uu
.s
.high
>> b
;
246 w
.s
.low
= ((USItype
)uu
.s
.low
>> b
) | carries
;
264 w
.ll
= __umulsidi3 (uu
.s
.low
, vv
.s
.low
);
265 w
.s
.high
+= ((USItype
) uu
.s
.low
* (USItype
) vv
.s
.high
266 + (USItype
) uu
.s
.high
* (USItype
) vv
.s
.low
);
272 #ifdef L_udiv_using_sdiv
274 __udiv_using_sdiv (rp
, a1
, a0
, d
)
275 USItype
*rp
, a1
, a0
, d
;
282 if (a1
< d
- a1
- (a0
>> 31))
284 /* dividend, divisor, and quotient are nonnegative */
285 sdiv_qrnnd (q
, r
, a1
, a0
, d
);
289 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
290 sub_ddmmss (c1
, c0
, a1
, a0
, d
>> 1, d
<< 31);
291 /* Divide (c1*2^32 + c0) by d */
292 sdiv_qrnnd (q
, r
, c1
, c0
, d
);
293 /* Add 2^31 to quotient */
299 b1
= d
>> 1; /* d/2, between 2^30 and 2^31 - 1 */
300 c1
= a1
>> 1; /* A/2 */
301 c0
= (a1
<< 31) + (a0
>> 1);
303 if (a1
< b1
) /* A < 2^32*b1, so A/2 < 2^31*b1 */
305 sdiv_qrnnd (q
, r
, c1
, c0
, b1
); /* (A/2) / (d/2) */
307 r
= 2*r
+ (a0
& 1); /* Remainder from A/(2*b1) */
324 else if (c1
< b1
) /* So 2^31 <= (A/2)/b1 < 2^32 */
327 c0
= ~c0
; /* logical NOT */
329 sdiv_qrnnd (q
, r
, c1
, c0
, b1
); /* (A/2) / (d/2) */
331 q
= ~q
; /* (A/2)/b1 */
334 r
= 2*r
+ (a0
& 1); /* A/(2*b1) */
352 else /* Implies c1 = b1 */
353 { /* Hence a1 = d - 1 = 2*b1 - 1 */
373 static const UQItype __clz_tab
[] =
375 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,
376 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,
377 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,
378 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,
379 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,
380 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,
381 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,
382 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 __udivmoddi4 (n
, d
, rp
)
393 USItype d0
, d1
, n0
, n1
, n2
;
405 #if !UDIV_NEEDS_NORMALIZATION
412 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
415 /* Remainder in n0. */
422 d0
= 1 / d0
; /* Divide intentionally by zero. */
424 udiv_qrnnd (q1
, n1
, 0, n1
, d0
);
425 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
427 /* Remainder in n0. */
438 #else /* UDIV_NEEDS_NORMALIZATION */
446 count_leading_zeros (bm
, d0
);
450 /* Normalize, i.e. make the most significant bit of the
454 n1
= (n1
<< bm
) | (n0
>> (SI_TYPE_SIZE
- bm
));
458 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
461 /* Remainder in n0 >> bm. */
468 d0
= 1 / d0
; /* Divide intentionally by zero. */
470 count_leading_zeros (bm
, d0
);
474 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
475 conclude (the most significant bit of n1 is set) /\ (the
476 leading quotient digit q1 = 1).
478 This special case is necessary, not an optimization.
479 (Shifts counts of SI_TYPE_SIZE are undefined.) */
488 b
= SI_TYPE_SIZE
- bm
;
492 n1
= (n1
<< bm
) | (n0
>> b
);
495 udiv_qrnnd (q1
, n1
, n2
, n1
, d0
);
500 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
502 /* Remainder in n0 >> bm. */
512 #endif /* UDIV_NEEDS_NORMALIZATION */
523 /* Remainder in n1n0. */
535 count_leading_zeros (bm
, d1
);
538 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
539 conclude (the most significant bit of n1 is set) /\ (the
540 quotient digit q0 = 0 or 1).
542 This special case is necessary, not an optimization. */
544 /* The condition on the next line takes advantage of that
545 n1 >= d1 (true due to program flow). */
546 if (n1
> d1
|| n0
>= d0
)
549 sub_ddmmss (n1
, n0
, n1
, n0
, d1
, d0
);
568 b
= SI_TYPE_SIZE
- bm
;
570 d1
= (d1
<< bm
) | (d0
>> b
);
573 n1
= (n1
<< bm
) | (n0
>> b
);
576 udiv_qrnnd (q0
, n1
, n2
, n1
, d1
);
577 umul_ppmm (m1
, m0
, q0
, d0
);
579 if (m1
> n1
|| (m1
== n1
&& m0
> n0
))
582 sub_ddmmss (m1
, m0
, m1
, m0
, d1
, d0
);
587 /* Remainder in (n1n0 - m1m0) >> bm. */
590 sub_ddmmss (n1
, n0
, n1
, n0
, m1
, m0
);
591 rr
.s
.low
= (n1
<< b
) | (n0
>> bm
);
592 rr
.s
.high
= n1
>> bm
;
606 UDItype
__udivmoddi4 ();
620 uu
.ll
= __negdi2 (uu
.ll
);
623 vv
.ll
= __negdi2 (vv
.ll
);
625 w
= __udivmoddi4 (uu
.ll
, vv
.ll
, (UDItype
*) 0);
634 UDItype
__udivmoddi4 ();
648 uu
.ll
= __negdi2 (uu
.ll
);
650 vv
.ll
= __negdi2 (vv
.ll
);
652 (void) __udivmoddi4 (uu
.ll
, vv
.ll
, &w
);
661 UDItype
__udivmoddi4 ();
668 (void) __udivmoddi4 (u
, v
, &w
);
675 UDItype
__udivmoddi4 ();
680 return __udivmoddi4 (n
, d
, (UDItype
*) 0);
691 au
.ll
= a
, bu
.ll
= b
;
693 if (au
.s
.high
< bu
.s
.high
)
695 else if (au
.s
.high
> bu
.s
.high
)
697 if ((USItype
) au
.s
.low
< (USItype
) bu
.s
.low
)
699 else if ((USItype
) au
.s
.low
> (USItype
) bu
.s
.low
)
712 au
.ll
= a
, bu
.ll
= b
;
714 if ((USItype
) au
.s
.high
< (USItype
) bu
.s
.high
)
716 else if ((USItype
) au
.s
.high
> (USItype
) bu
.s
.high
)
718 if ((USItype
) au
.s
.low
< (USItype
) bu
.s
.low
)
720 else if ((USItype
) au
.s
.low
> (USItype
) bu
.s
.low
)
726 #if defined(L_fixunstfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
727 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
728 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
740 /* Compute high word of result, as a flonum. */
741 b
= (a
/ HIGH_WORD_COEFF
);
742 /* Convert that to fixed (but not to DItype!),
743 and shift it into the high word. */
746 /* Remove high part from the TFtype, leaving the low part as flonum. */
748 /* Convert that to fixed (but not to DItype!) and add it in.
749 Sometimes A comes out negative. This is significant, since
750 A has more bits than a long int does. */
752 v
-= (USItype
) (- a
);
759 #if defined(L_fixtfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
765 return - __fixunstfdi (-a
);
766 return __fixunstfdi (a
);
771 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
772 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
784 /* Compute high word of result, as a flonum. */
785 b
= (a
/ HIGH_WORD_COEFF
);
786 /* Convert that to fixed (but not to DItype!),
787 and shift it into the high word. */
790 /* Remove high part from the DFtype, leaving the low part as flonum. */
792 /* Convert that to fixed (but not to DItype!) and add it in.
793 Sometimes A comes out negative. This is significant, since
794 A has more bits than a long int does. */
796 v
-= (USItype
) (- a
);
809 return - __fixunsdfdi (-a
);
810 return __fixunsdfdi (a
);
815 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
816 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
819 __fixunssfdi (SFtype original_a
)
821 /* Convert the SFtype to a DFtype, because that is surely not going
822 to lose any bits. Some day someone else can write a faster version
823 that avoids converting to DFtype, and verify it really works right. */
824 DFtype a
= original_a
;
831 /* Compute high word of result, as a flonum. */
832 b
= (a
/ HIGH_WORD_COEFF
);
833 /* Convert that to fixed (but not to DItype!),
834 and shift it into the high word. */
837 /* Remove high part from the DFtype, leaving the low part as flonum. */
839 /* Convert that to fixed (but not to DItype!) and add it in.
840 Sometimes A comes out negative. This is significant, since
841 A has more bits than a long int does. */
843 v
-= (USItype
) (- a
);
855 return - __fixunssfdi (-a
);
856 return __fixunssfdi (a
);
860 #if defined(L_floatditf) && (LONG_DOUBLE_TYPE_SIZE == 128)
861 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
862 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
863 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
875 d
= (USItype
) (u
>> WORD_SIZE
);
876 d
*= HIGH_HALFWORD_COEFF
;
877 d
*= HIGH_HALFWORD_COEFF
;
878 d
+= (USItype
) (u
& (HIGH_WORD_COEFF
- 1));
880 return (negate
? -d
: d
);
885 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
886 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
887 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
899 d
= (USItype
) (u
>> WORD_SIZE
);
900 d
*= HIGH_HALFWORD_COEFF
;
901 d
*= HIGH_HALFWORD_COEFF
;
902 d
+= (USItype
) (u
& (HIGH_WORD_COEFF
- 1));
904 return (negate
? -d
: d
);
909 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
910 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
911 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
923 f
= (USItype
) (u
>> WORD_SIZE
);
924 f
*= HIGH_HALFWORD_COEFF
;
925 f
*= HIGH_HALFWORD_COEFF
;
926 f
+= (USItype
) (u
& (HIGH_WORD_COEFF
- 1));
928 return (negate
? -f
: f
);
939 if (a
>= - (DFtype
) LONG_MIN
)
940 return (SItype
) (a
+ LONG_MIN
) - LONG_MIN
;
949 __fixunssfsi (SFtype a
)
951 if (a
>= - (SFtype
) LONG_MIN
)
952 return (SItype
) (a
+ LONG_MIN
) - LONG_MIN
;
957 /* From here on down, the routines use normal data types. */
959 #define SItype bogus_type
960 #define USItype bogus_type
961 #define DItype bogus_type
962 #define UDItype bogus_type
963 #define SFtype bogus_type
964 #define DFtype bogus_type
976 #if defined(__svr4__) || defined(__alliant__)
980 /* The Alliant needs the added underscore. */
981 asm (".globl __builtin_saveregs");
982 asm ("__builtin_saveregs:");
983 asm (".globl ___builtin_saveregs");
984 asm ("___builtin_saveregs:");
986 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
987 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
988 area and also for a new va_list
990 /* Save all argument registers in the arg reg save area. The
991 arg reg save area must have the following layout (according
1003 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
1004 asm (" fst.q %f12,16(%sp)");
1006 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
1007 asm (" st.l %r17,36(%sp)");
1008 asm (" st.l %r18,40(%sp)");
1009 asm (" st.l %r19,44(%sp)");
1010 asm (" st.l %r20,48(%sp)");
1011 asm (" st.l %r21,52(%sp)");
1012 asm (" st.l %r22,56(%sp)");
1013 asm (" st.l %r23,60(%sp)");
1014 asm (" st.l %r24,64(%sp)");
1015 asm (" st.l %r25,68(%sp)");
1016 asm (" st.l %r26,72(%sp)");
1017 asm (" st.l %r27,76(%sp)");
1019 asm (" adds 80,%sp,%r16"); /* compute the address of the new
1020 va_list structure. Put in into
1021 r16 so that it will be returned
1024 /* Initialize all fields of the new va_list structure. This
1025 structure looks like:
1028 unsigned long ireg_used;
1029 unsigned long freg_used;
1035 asm (" st.l %r0, 0(%r16)"); /* nfixed */
1036 asm (" st.l %r0, 4(%r16)"); /* nfloating */
1037 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
1038 asm (" bri %r1"); /* delayed return */
1039 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
1041 #else /* not __SVR4__ */
1045 asm (".globl ___builtin_saveregs");
1046 asm ("___builtin_saveregs:");
1047 asm (" mov sp,r30");
1048 asm (" andnot 0x0f,sp,sp");
1049 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
1051 /* Fill in the __va_struct. */
1052 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
1053 asm (" st.l r17, 4(sp)"); /* int fixed[12] */
1054 asm (" st.l r18, 8(sp)");
1055 asm (" st.l r19,12(sp)");
1056 asm (" st.l r20,16(sp)");
1057 asm (" st.l r21,20(sp)");
1058 asm (" st.l r22,24(sp)");
1059 asm (" st.l r23,28(sp)");
1060 asm (" st.l r24,32(sp)");
1061 asm (" st.l r25,36(sp)");
1062 asm (" st.l r26,40(sp)");
1063 asm (" st.l r27,44(sp)");
1065 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
1066 asm (" fst.q f12,64(sp)"); /* int floating[8] */
1068 /* Fill in the __va_ctl. */
1069 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
1070 asm (" st.l r28,84(sp)"); /* pointer to more args */
1071 asm (" st.l r0, 88(sp)"); /* nfixed */
1072 asm (" st.l r0, 92(sp)"); /* nfloating */
1074 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
1076 asm (" mov r30,sp");
1077 /* recover stack and pass address to start
1079 #endif /* not __SVR4__ */
1080 #else /* not __i860__ */
1082 asm (".global __builtin_saveregs");
1083 asm ("__builtin_saveregs:");
1084 asm (".global ___builtin_saveregs");
1085 asm ("___builtin_saveregs:");
1086 #ifdef NEED_PROC_COMMAND
1089 asm ("st %i0,[%fp+68]");
1090 asm ("st %i1,[%fp+72]");
1091 asm ("st %i2,[%fp+76]");
1092 asm ("st %i3,[%fp+80]");
1093 asm ("st %i4,[%fp+84]");
1095 asm ("st %i5,[%fp+88]");
1096 #ifdef NEED_TYPE_COMMAND
1097 asm (".type __builtin_saveregs,#function");
1098 asm (".size __builtin_saveregs,.-__builtin_saveregs");
1100 #else /* not __sparc__ */
1101 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1104 asm (" .ent __builtin_saveregs");
1105 asm (" .globl __builtin_saveregs");
1106 asm ("__builtin_saveregs:");
1107 asm (" sw $4,0($30)");
1108 asm (" sw $5,4($30)");
1109 asm (" sw $6,8($30)");
1110 asm (" sw $7,12($30)");
1112 asm (" .end __builtin_saveregs");
1113 #else /* not __mips__, etc. */
1114 __builtin_saveregs ()
1118 #endif /* not __mips__ */
1119 #endif /* not __sparc__ */
1120 #endif /* not __i860__ */
1124 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1126 /* This is used by the `assert' macro. */
1128 __eprintf (string
, expression
, line
, filename
)
1130 const char *expression
;
1132 const char *filename
;
1134 fprintf (stderr
, string
, expression
, line
, filename
);
1141 /* Avoid warning from ranlib about empty object file. */
1143 __bb_avoid_warning ()
1146 #if defined (__sun__) && defined (__mc68000__)
1157 extern int ___tcov_init
;
1159 __bb_init_func (blocks
)
1163 ___tcov_init_func ();
1165 ___bb_link (blocks
->filename
, blocks
->counts
, blocks
->ncounts
);
1171 /* frills for C++ */
1173 #ifdef L_builtin_new
1174 typedef void (*vfp
)(void);
1176 extern vfp __new_handler
;
1177 extern void *malloc ();
1187 (*__new_handler
) ();
1193 typedef void (*vfp
)(void);
1195 extern void *__builtin_new (size_t);
1196 static void default_new_handler (void);
1198 vfp __new_handler
= default_new_handler
;
1201 __builtin_vec_new (p
, maxindex
, size
, ctor
)
1205 void (*ctor
)(void *);
1208 size_t nelts
= maxindex
+ 1;
1212 p
= __builtin_new (nelts
* size
);
1216 for (i
= 0; i
< nelts
; i
++)
1226 __set_new_handler (handler
)
1231 prev_handler
= __new_handler
;
1232 if (handler
== 0) handler
= default_new_handler
;
1233 __new_handler
= handler
;
1234 return prev_handler
;
1238 set_new_handler (handler
)
1241 return __set_new_handler (handler
);
1244 #define MESSAGE "Virtual memory exceeded in `new'\n"
1247 default_new_handler ()
1249 /* don't use fprintf (stderr, ...) because it may need to call malloc. */
1250 /* This should really print the name of the program, but that is hard to
1251 do. We need a standard, clean way to get at the name. */
1252 write (2, MESSAGE
, sizeof (MESSAGE
));
1253 /* don't call exit () because that may call global destructors which
1254 may cause a loop. */
1259 #ifdef L_builtin_del
1260 typedef void (*vfp
)(void);
1263 __builtin_delete (ptr
)
1271 __builtin_vec_delete (ptr
, maxindex
, size
, dtor
, auto_delete_vec
, auto_delete
)
1275 void (*dtor
)(void *, int);
1279 size_t nelts
= maxindex
+ 1;
1282 ptr
+= nelts
* size
;
1284 for (i
= 0; i
< nelts
; i
++)
1287 (*dtor
) (ptr
, auto_delete
);
1290 if (auto_delete_vec
)
1291 __builtin_delete (p
);
1297 unsigned int __shtab
[] = {
1298 0x00000001, 0x00000002, 0x00000004, 0x00000008,
1299 0x00000010, 0x00000020, 0x00000040, 0x00000080,
1300 0x00000100, 0x00000200, 0x00000400, 0x00000800,
1301 0x00001000, 0x00002000, 0x00004000, 0x00008000,
1302 0x00010000, 0x00020000, 0x00040000, 0x00080000,
1303 0x00100000, 0x00200000, 0x00400000, 0x00800000,
1304 0x01000000, 0x02000000, 0x04000000, 0x08000000,
1305 0x10000000, 0x20000000, 0x40000000, 0x80000000
1309 #ifdef L_clear_cache
1310 /* Clear part of an instruction cache. */
1312 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1315 __clear_cache (beg
, end
)
1318 #ifdef INSN_CACHE_SIZE
1319 static char array
[INSN_CACHE_SIZE
+ INSN_CACHE_PLANE_SIZE
+ INSN_CACHE_LINE_WIDTH
];
1320 static int initialized
= 0;
1324 typedef (*function_ptr
) ();
1326 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1327 /* It's cheaper to clear the whole cache.
1328 Put in a series of jump instructions so that calling the beginning
1329 of the cache will clear the whole thing. */
1333 int ptr
= (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
1334 & -INSN_CACHE_LINE_WIDTH
);
1335 int end_ptr
= ptr
+ INSN_CACHE_SIZE
;
1337 while (ptr
< end_ptr
)
1339 *(INSTRUCTION_TYPE
*)ptr
1340 = JUMP_AHEAD_INSTRUCTION
+ INSN_CACHE_LINE_WIDTH
;
1341 ptr
+= INSN_CACHE_LINE_WIDTH
;
1343 *(INSTRUCTION_TYPE
*)(ptr
- INSN_CACHE_LINE_WIDTH
) = RETURN_INSTRUCTION
;
1348 /* Call the beginning of the sequence. */
1349 (((function_ptr
) (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
1350 & -INSN_CACHE_LINE_WIDTH
))
1353 #else /* Cache is large. */
1357 int ptr
= (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
1358 & -INSN_CACHE_LINE_WIDTH
);
1360 while (ptr
< (int) array
+ sizeof array
)
1362 *(INSTRUCTION_TYPE
*)ptr
= RETURN_INSTRUCTION
;
1363 ptr
+= INSN_CACHE_LINE_WIDTH
;
1369 /* Find the location in array that occupies the same cache line as BEG. */
1371 offset
= ((int) beg
& -INSN_CACHE_LINE_WIDTH
) & (INSN_CACHE_PLANE_SIZE
- 1);
1372 start_addr
= (((int) (array
+ INSN_CACHE_PLANE_SIZE
- 1)
1373 & -INSN_CACHE_PLANE_SIZE
)
1376 /* Compute the cache alignment of the place to stop clearing. */
1377 #if 0 /* This is not needed for gcc's purposes. */
1378 /* If the block to clear is bigger than a cache plane,
1379 we clear the entire cache, and OFFSET is already correct. */
1380 if (end
< beg
+ INSN_CACHE_PLANE_SIZE
)
1382 offset
= (((int) (end
+ INSN_CACHE_LINE_WIDTH
- 1)
1383 & -INSN_CACHE_LINE_WIDTH
)
1384 & (INSN_CACHE_PLANE_SIZE
- 1));
1386 #if INSN_CACHE_DEPTH > 1
1387 end_addr
= (start_addr
& -INSN_CACHE_PLANE_SIZE
) + offset
;
1388 if (end_addr
<= start_addr
)
1389 end_addr
+= INSN_CACHE_PLANE_SIZE
;
1391 for (plane
= 0; plane
< INSN_CACHE_DEPTH
; plane
++)
1393 int addr
= start_addr
+ plane
* INSN_CACHE_PLANE_SIZE
;
1394 int stop
= end_addr
+ plane
* INSN_CACHE_PLANE_SIZE
;
1396 while (addr
!= stop
)
1398 /* Call the return instruction at ADDR. */
1399 ((function_ptr
) addr
) ();
1401 addr
+= INSN_CACHE_LINE_WIDTH
;
1404 #else /* just one plane */
1407 /* Call the return instruction at START_ADDR. */
1408 ((function_ptr
) start_addr
) ();
1410 start_addr
+= INSN_CACHE_LINE_WIDTH
;
1412 while ((start_addr
% INSN_CACHE_SIZE
) != offset
);
1413 #endif /* just one plane */
1414 #endif /* Cache is large */
1415 #endif /* Cache exists */
1418 #endif /* L_clear_cache */
1422 /* Jump to a trampoline, loading the static chain address. */
1424 #ifdef TRANSFER_FROM_TRAMPOLINE
1425 TRANSFER_FROM_TRAMPOLINE
1430 /* Make stack executable so we can call trampolines on stack.
1431 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
1433 #include <sys/mman.h>
1434 #include <sys/vmparam.h>
1435 #include <machine/machparam.h>
1438 __enable_execute_stack ()
1441 static unsigned lowest
= USRSTACK
;
1442 unsigned current
= (unsigned) &fp
& -NBPG
;
1444 if (lowest
> current
)
1446 unsigned len
= lowest
- current
;
1447 mremap (current
, &len
, PROT_READ
| PROT_WRITE
| PROT_EXEC
, MAP_PRIVATE
);
1451 /* Clear instruction cache in case an old trampoline is in it. */
1454 #endif /* __convex__ */
1459 #include <sys/mman.h>
1460 #include <sys/types.h>
1461 #include <sys/param.h>
1462 #include <sys/vmmac.h>
1464 /* Modified from the convex -code above.
1465 mremap promises to clear the i-cache. */
1468 __enable_execute_stack ()
1471 if (mprotect (((unsigned int)&fp
/PAGSIZ
)*PAGSIZ
, PAGSIZ
,
1472 PROT_READ
|PROT_WRITE
|PROT_EXEC
))
1474 perror ("mprotect in __enable_execute_stack");
1479 #endif /* __pyr__ */
1480 #endif /* L_trampoline */
1484 #include "gbl-ctors.h"
1486 /* Run all the global destructors on exit from the program. */
1489 __do_global_dtors ()
1491 #ifdef DO_GLOBAL_DTORS_BODY
1492 DO_GLOBAL_DTORS_BODY
;
1494 unsigned nptrs
= (unsigned) __DTOR_LIST__
[0];
1497 /* Some systems place the number of pointers
1498 in the first word of the table.
1499 On other systems, that word is -1.
1500 In all cases, the table is null-terminated. */
1502 /* If the length is not recorded, count up to the null. */
1504 for (nptrs
= 0; __DTOR_LIST__
[nptrs
+ 1] != 0; nptrs
++);
1506 /* GNU LD format. */
1507 for (i
= nptrs
; i
>= 1; i
--)
1508 __DTOR_LIST__
[i
] ();
1512 #ifndef INIT_SECTION_ASM_OP
1513 /* Run all the global constructors on entry to the program. */
1516 #define ON_EXIT(a, b)
1518 /* Make sure the exit routine is pulled in to define the globals as
1519 bss symbols, just in case the linker does not automatically pull
1520 bss definitions from the library. */
1522 extern int _exit_dummy_decl
;
1523 int *_exit_dummy_ref
= &_exit_dummy_decl
;
1524 #endif /* ON_EXIT */
1527 __do_global_ctors ()
1529 DO_GLOBAL_CTORS_BODY
;
1530 ON_EXIT (__do_global_dtors
, 0);
1532 #endif /* no INIT_SECTION_ASM_OP */
1534 #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
1535 /* Subroutine called automatically by `main'.
1536 Compiling a global function named `main'
1537 produces an automatic call to this function at the beginning.
1539 For many systems, this routine calls __do_global_ctors.
1540 For systems which support a .init section we use the .init section
1541 to run __do_global_ctors, so we need not do anything here. */
1546 /* Support recursive calls to `main': run initializers just once. */
1547 static int initialized
= 0;
1551 __do_global_ctors ();
1554 #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
1556 #endif /* L__main */
1560 #include "gbl-ctors.h"
1562 /* Provide default definitions for the lists of constructors and
1563 destructors, so that we don't get linker errors. These symbols are
1564 intentionally bss symbols, so that gld and/or collect will provide
1565 the right values. */
1567 /* We declare the lists here with two elements each,
1568 so that they are valid empty lists if no other definition is loaded. */
1569 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
1570 func_ptr __CTOR_LIST__
[2];
1571 func_ptr __DTOR_LIST__
[2];
1572 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1576 /* If we have no known way of registering our own __do_global_dtors
1577 routine so that it will be invoked at program exit time, then we
1578 have to define our own exit routine which will get this to happen. */
1580 extern void __do_global_dtors ();
1581 extern void _cleanup ();
1582 extern void _exit ();
1588 __do_global_dtors ();
1598 int _exit_dummy_decl
= 0; /* prevent compiler & linker warnings */
1603 /* In a.out systems, we need to have these dummy constructor and destructor
1604 lists in the library.
1606 When using `collect', the first link will resolve __CTOR_LIST__
1607 and __DTOR_LIST__ to these symbols. We will then run "nm" on the
1608 result, build the correct __CTOR_LIST__ and __DTOR_LIST__, and relink.
1609 Since we don't do the second link if no constructors existed, these
1610 dummies must be fully functional empty lists.
1612 When using `gnu ld', these symbols will be used if there are no
1613 constructors. If there are constructors, the N_SETV symbol defined
1614 by the linker from the N_SETT's in input files will define __CTOR_LIST__
1615 and __DTOR_LIST__ rather than its being allocated as common storage
1616 by the definitions below.
1618 When using a linker that supports constructor and destructor segments,
1619 these definitions will not be used, since crtbegin.o and crtend.o
1620 (from crtstuff.c) will have already defined __CTOR_LIST__ and
1621 __DTOR_LIST__. The crt*.o files are passed directly to the linker
1622 on its command line, by gcc. */
1624 /* The list needs two elements: one is ignored (the old count); the
1625 second is the terminating zero. Since both values are zero, this
1626 declaration is not initialized, and it becomes `common'. */
1629 #include "gbl-ctors.h"
1630 func_ptr __CTOR_LIST__
[2];
1634 #include "gbl-ctors.h"
1635 func_ptr __DTOR_LIST__
[2];
This page took 0.105438 seconds and 5 git commands to generate.