]>
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
)));
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)
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
);
273 static const UQItype __clz_tab
[] =
275 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,
276 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,
277 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,
278 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,
279 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,
280 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,
281 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,
282 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,
286 __udivmoddi4 (n
, d
, rp
)
293 USItype d0
, d1
, n0
, n1
, n2
;
305 #if !UDIV_NEEDS_NORMALIZATION
312 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
315 /* Remainder in n0. */
322 d0
= 1 / d0
; /* Divide intentionally by zero. */
324 udiv_qrnnd (q1
, n1
, 0, n1
, d0
);
325 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
327 /* Remainder in n0. */
338 #else /* UDIV_NEEDS_NORMALIZATION */
346 count_leading_zeros (bm
, d0
);
350 /* Normalize, i.e. make the most significant bit of the
354 n1
= (n1
<< bm
) | (n0
>> (SI_TYPE_SIZE
- bm
));
358 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
361 /* Remainder in n0 >> bm. */
368 d0
= 1 / d0
; /* Divide intentionally by zero. */
370 count_leading_zeros (bm
, d0
);
374 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
375 conclude (the most significant bit of n1 is set) /\ (the
376 leading quotient digit q1 = 1).
378 This special case is necessary, not an optimization.
379 (Shifts counts of SI_TYPE_SIZE are undefined.) */
388 b
= SI_TYPE_SIZE
- bm
;
392 n1
= (n1
<< bm
) | (n0
>> b
);
395 udiv_qrnnd (q1
, n1
, n2
, n1
, d0
);
400 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
402 /* Remainder in n0 >> bm. */
412 #endif /* UDIV_NEEDS_NORMALIZATION */
423 /* Remainder in n1n0. */
435 count_leading_zeros (bm
, d1
);
438 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
439 conclude (the most significant bit of n1 is set) /\ (the
440 quotient digit q0 = 0 or 1).
442 This special case is necessary, not an optimization. */
444 /* The condition on the next line takes advantage of that
445 n1 >= d1 (true due to program flow). */
446 if (n1
> d1
|| n0
>= d0
)
449 sub_ddmmss (n1
, n0
, n1
, n0
, d1
, d0
);
468 b
= SI_TYPE_SIZE
- bm
;
470 d1
= (d1
<< bm
) | (d0
>> b
);
473 n1
= (n1
<< bm
) | (n0
>> b
);
476 udiv_qrnnd (q0
, n1
, n2
, n1
, d1
);
477 umul_ppmm (m1
, m0
, q0
, d0
);
479 if (m1
> n1
|| (m1
== n1
&& m0
> n0
))
482 sub_ddmmss (m1
, m0
, m1
, m0
, d1
, d0
);
487 /* Remainder in (n1n0 - m1m0) >> bm. */
490 sub_ddmmss (n1
, n0
, n1
, n0
, m1
, m0
);
491 rr
.s
.low
= (n1
<< b
) | (n0
>> bm
);
492 rr
.s
.high
= n1
>> bm
;
506 UDItype
__udivmoddi4 ();
520 uu
.ll
= __negdi2 (uu
.ll
);
523 vv
.ll
= __negdi2 (vv
.ll
);
525 w
= __udivmoddi4 (uu
.ll
, vv
.ll
, (UDItype
*) 0);
534 UDItype
__udivmoddi4 ();
548 uu
.ll
= __negdi2 (uu
.ll
);
550 vv
.ll
= __negdi2 (vv
.ll
);
552 (void) __udivmoddi4 (uu
.ll
, vv
.ll
, &w
);
561 UDItype
__udivmoddi4 ();
568 (void) __udivmoddi4 (u
, v
, &w
);
575 UDItype
__udivmoddi4 ();
580 return __udivmoddi4 (n
, d
, (UDItype
*) 0);
591 au
.ll
= a
, bu
.ll
= b
;
593 if (au
.s
.high
< bu
.s
.high
)
595 else if (au
.s
.high
> bu
.s
.high
)
597 if ((USItype
) au
.s
.low
< (USItype
) bu
.s
.low
)
599 else if ((USItype
) au
.s
.low
> (USItype
) bu
.s
.low
)
612 au
.ll
= a
, bu
.ll
= b
;
614 if ((USItype
) au
.s
.high
< (USItype
) bu
.s
.high
)
616 else if ((USItype
) au
.s
.high
> (USItype
) bu
.s
.high
)
618 if ((USItype
) au
.s
.low
< (USItype
) bu
.s
.low
)
620 else if ((USItype
) au
.s
.low
> (USItype
) bu
.s
.low
)
626 #if defined(L_fixunstfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
627 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
628 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
640 /* Compute high word of result, as a flonum. */
641 b
= (a
/ HIGH_WORD_COEFF
);
642 /* Convert that to fixed (but not to DItype!),
643 and shift it into the high word. */
646 /* Remove high part from the TFtype, leaving the low part as flonum. */
648 /* Convert that to fixed (but not to DItype!) and add it in.
649 Sometimes A comes out negative. This is significant, since
650 A has more bits than a long int does. */
652 v
-= (USItype
) (- a
);
659 #if defined(L_fixtfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
665 return - __fixunstfdi (-a
);
666 return __fixunstfdi (a
);
671 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
672 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
684 /* Compute high word of result, as a flonum. */
685 b
= (a
/ HIGH_WORD_COEFF
);
686 /* Convert that to fixed (but not to DItype!),
687 and shift it into the high word. */
690 /* Remove high part from the DFtype, leaving the low part as flonum. */
692 /* Convert that to fixed (but not to DItype!) and add it in.
693 Sometimes A comes out negative. This is significant, since
694 A has more bits than a long int does. */
696 v
-= (USItype
) (- a
);
709 return - __fixunsdfdi (-a
);
710 return __fixunsdfdi (a
);
715 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
716 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
719 __fixunssfdi (SFtype original_a
)
721 /* Convert the SFtype to a DFtype, because that is surely not going
722 to lose any bits. Some day someone else can write a faster version
723 that avoids converting to DFtype, and verify it really works right. */
724 DFtype a
= original_a
;
731 /* Compute high word of result, as a flonum. */
732 b
= (a
/ HIGH_WORD_COEFF
);
733 /* Convert that to fixed (but not to DItype!),
734 and shift it into the high word. */
737 /* Remove high part from the DFtype, leaving the low part as flonum. */
739 /* Convert that to fixed (but not to DItype!) and add it in.
740 Sometimes A comes out negative. This is significant, since
741 A has more bits than a long int does. */
743 v
-= (USItype
) (- a
);
755 return - __fixunssfdi (-a
);
756 return __fixunssfdi (a
);
760 #if defined(L_floatditf) && (LONG_DOUBLE_TYPE_SIZE == 128)
761 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
762 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
763 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
775 d
= (USItype
) (u
>> WORD_SIZE
);
776 d
*= HIGH_HALFWORD_COEFF
;
777 d
*= HIGH_HALFWORD_COEFF
;
778 d
+= (USItype
) (u
& (HIGH_WORD_COEFF
- 1));
780 return (negate
? -d
: d
);
785 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
786 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
787 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
799 d
= (USItype
) (u
>> WORD_SIZE
);
800 d
*= HIGH_HALFWORD_COEFF
;
801 d
*= HIGH_HALFWORD_COEFF
;
802 d
+= (USItype
) (u
& (HIGH_WORD_COEFF
- 1));
804 return (negate
? -d
: d
);
809 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
810 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
811 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
823 f
= (USItype
) (u
>> WORD_SIZE
);
824 f
*= HIGH_HALFWORD_COEFF
;
825 f
*= HIGH_HALFWORD_COEFF
;
826 f
+= (USItype
) (u
& (HIGH_WORD_COEFF
- 1));
828 return (negate
? -f
: f
);
839 if (a
>= - (DFtype
) LONG_MIN
)
840 return (SItype
) (a
+ LONG_MIN
) - LONG_MIN
;
849 __fixunssfsi (SFtype a
)
851 if (a
>= - (SFtype
) LONG_MIN
)
852 return (SItype
) (a
+ LONG_MIN
) - LONG_MIN
;
857 /* From here on down, the routines use normal data types. */
859 #define SItype bogus_type
860 #define USItype bogus_type
861 #define DItype bogus_type
862 #define UDItype bogus_type
863 #define SFtype bogus_type
864 #define DFtype bogus_type
876 #if defined(__svr4__) || defined(__alliant__)
880 /* The Alliant needs the added underscore. */
881 asm (".globl __builtin_saveregs");
882 asm ("__builtin_saveregs:");
883 asm (".globl ___builtin_saveregs");
884 asm ("___builtin_saveregs:");
886 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
887 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
888 area and also for a new va_list
890 /* Save all argument registers in the arg reg save area. The
891 arg reg save area must have the following layout (according
903 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
904 asm (" fst.q %f12,16(%sp)");
906 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
907 asm (" st.l %r17,36(%sp)");
908 asm (" st.l %r18,40(%sp)");
909 asm (" st.l %r19,44(%sp)");
910 asm (" st.l %r20,48(%sp)");
911 asm (" st.l %r21,52(%sp)");
912 asm (" st.l %r22,56(%sp)");
913 asm (" st.l %r23,60(%sp)");
914 asm (" st.l %r24,64(%sp)");
915 asm (" st.l %r25,68(%sp)");
916 asm (" st.l %r26,72(%sp)");
917 asm (" st.l %r27,76(%sp)");
919 asm (" adds 80,%sp,%r16"); /* compute the address of the new
920 va_list structure. Put in into
921 r16 so that it will be returned
924 /* Initialize all fields of the new va_list structure. This
925 structure looks like:
928 unsigned long ireg_used;
929 unsigned long freg_used;
935 asm (" st.l %r0, 0(%r16)"); /* nfixed */
936 asm (" st.l %r0, 4(%r16)"); /* nfloating */
937 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
938 asm (" bri %r1"); /* delayed return */
939 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
941 #else /* not __SVR4__ */
945 asm (".globl ___builtin_saveregs");
946 asm ("___builtin_saveregs:");
948 asm (" andnot 0x0f,sp,sp");
949 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
951 /* Fill in the __va_struct. */
952 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
953 asm (" st.l r17, 4(sp)"); /* int fixed[12] */
954 asm (" st.l r18, 8(sp)");
955 asm (" st.l r19,12(sp)");
956 asm (" st.l r20,16(sp)");
957 asm (" st.l r21,20(sp)");
958 asm (" st.l r22,24(sp)");
959 asm (" st.l r23,28(sp)");
960 asm (" st.l r24,32(sp)");
961 asm (" st.l r25,36(sp)");
962 asm (" st.l r26,40(sp)");
963 asm (" st.l r27,44(sp)");
965 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
966 asm (" fst.q f12,64(sp)"); /* int floating[8] */
968 /* Fill in the __va_ctl. */
969 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
970 asm (" st.l r28,84(sp)"); /* pointer to more args */
971 asm (" st.l r0, 88(sp)"); /* nfixed */
972 asm (" st.l r0, 92(sp)"); /* nfloating */
974 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
977 /* recover stack and pass address to start
979 #endif /* not __SVR4__ */
980 #else /* not __i860__ */
982 asm (".global __builtin_saveregs");
983 asm ("__builtin_saveregs:");
984 asm (".global ___builtin_saveregs");
985 asm ("___builtin_saveregs:");
986 #ifdef NEED_PROC_COMMAND
989 asm ("st %i0,[%fp+68]");
990 asm ("st %i1,[%fp+72]");
991 asm ("st %i2,[%fp+76]");
992 asm ("st %i3,[%fp+80]");
993 asm ("st %i4,[%fp+84]");
995 asm ("st %i5,[%fp+88]");
996 #ifdef NEED_TYPE_COMMAND
997 asm (".type __builtin_saveregs,#function");
998 asm (".size __builtin_saveregs,.-__builtin_saveregs");
1000 #else /* not __sparc__ */
1001 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1004 asm (" .ent __builtin_saveregs");
1005 asm (" .globl __builtin_saveregs");
1006 asm ("__builtin_saveregs:");
1007 asm (" sw $4,0($30)");
1008 asm (" sw $5,4($30)");
1009 asm (" sw $6,8($30)");
1010 asm (" sw $7,12($30)");
1012 asm (" .end __builtin_saveregs");
1013 #else /* not __mips__, etc. */
1014 __builtin_saveregs ()
1018 #endif /* not __mips__ */
1019 #endif /* not __sparc__ */
1020 #endif /* not __i860__ */
1024 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1026 /* This is used by the `assert' macro. */
1028 __eprintf (string
, expression
, line
, filename
)
1030 const char *expression
;
1032 const char *filename
;
1034 fprintf (stderr
, string
, expression
, line
, filename
);
1041 /* Avoid warning from ranlib about empty object file. */
1043 __bb_avoid_warning ()
1046 #if defined (__sun__) && defined (__mc68000__)
1057 extern int ___tcov_init
;
1059 __bb_init_func (blocks
)
1063 ___tcov_init_func ();
1065 ___bb_link (blocks
->filename
, blocks
->counts
, blocks
->ncounts
);
1071 /* frills for C++ */
1073 #ifdef L_builtin_new
1074 typedef void (*vfp
)(void);
1076 extern vfp __new_handler
;
1077 extern void *malloc ();
1087 (*__new_handler
) ();
1093 typedef void (*vfp
)(void);
1095 extern void *__builtin_new (size_t);
1096 static void default_new_handler (void);
1098 vfp __new_handler
= default_new_handler
;
1101 __builtin_vec_new (p
, maxindex
, size
, ctor
)
1105 void (*ctor
)(void *);
1108 size_t nelts
= maxindex
+ 1;
1112 p
= __builtin_new (nelts
* size
);
1116 for (i
= 0; i
< nelts
; i
++)
1126 __set_new_handler (handler
)
1131 prev_handler
= __new_handler
;
1132 if (handler
== 0) handler
= default_new_handler
;
1133 __new_handler
= handler
;
1134 return prev_handler
;
1138 set_new_handler (handler
)
1141 return __set_new_handler (handler
);
1144 #define MESSAGE "Virtual memory exceeded in `new'\n"
1147 default_new_handler ()
1149 /* don't use fprintf (stderr, ...) because it may need to call malloc. */
1150 /* This should really print the name of the program, but that is hard to
1151 do. We need a standard, clean way to get at the name. */
1152 write (2, MESSAGE
, sizeof (MESSAGE
));
1153 /* don't call exit () because that may call global destructors which
1154 may cause a loop. */
1159 #ifdef L_builtin_del
1160 typedef void (*vfp
)(void);
1163 __builtin_delete (ptr
)
1171 __builtin_vec_delete (ptr
, maxindex
, size
, dtor
, auto_delete_vec
, auto_delete
)
1175 void (*dtor
)(void *, int);
1179 size_t nelts
= maxindex
+ 1;
1182 ptr
+= nelts
* size
;
1184 for (i
= 0; i
< nelts
; i
++)
1187 (*dtor
) (ptr
, auto_delete
);
1190 if (auto_delete_vec
)
1191 __builtin_delete (p
);
1197 unsigned int __shtab
[] = {
1198 0x00000001, 0x00000002, 0x00000004, 0x00000008,
1199 0x00000010, 0x00000020, 0x00000040, 0x00000080,
1200 0x00000100, 0x00000200, 0x00000400, 0x00000800,
1201 0x00001000, 0x00002000, 0x00004000, 0x00008000,
1202 0x00010000, 0x00020000, 0x00040000, 0x00080000,
1203 0x00100000, 0x00200000, 0x00400000, 0x00800000,
1204 0x01000000, 0x02000000, 0x04000000, 0x08000000,
1205 0x10000000, 0x20000000, 0x40000000, 0x80000000
1209 #ifdef L_clear_cache
1210 /* Clear part of an instruction cache. */
1212 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1215 __clear_cache (beg
, end
)
1218 #ifdef INSN_CACHE_SIZE
1219 static char array
[INSN_CACHE_SIZE
+ INSN_CACHE_PLANE_SIZE
+ INSN_CACHE_LINE_WIDTH
];
1220 static int initialized
= 0;
1224 typedef (*function_ptr
) ();
1226 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1227 /* It's cheaper to clear the whole cache.
1228 Put in a series of jump instructions so that calling the beginning
1229 of the cache will clear the whole thing. */
1233 int ptr
= (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
1234 & -INSN_CACHE_LINE_WIDTH
);
1235 int end_ptr
= ptr
+ INSN_CACHE_SIZE
;
1237 while (ptr
< end_ptr
)
1239 *(INSTRUCTION_TYPE
*)ptr
1240 = JUMP_AHEAD_INSTRUCTION
+ INSN_CACHE_LINE_WIDTH
;
1241 ptr
+= INSN_CACHE_LINE_WIDTH
;
1243 *(INSTRUCTION_TYPE
*)(ptr
- INSN_CACHE_LINE_WIDTH
) = RETURN_INSTRUCTION
;
1248 /* Call the beginning of the sequence. */
1249 (((function_ptr
) (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
1250 & -INSN_CACHE_LINE_WIDTH
))
1253 #else /* Cache is large. */
1257 int ptr
= (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
1258 & -INSN_CACHE_LINE_WIDTH
);
1260 while (ptr
< (int) array
+ sizeof array
)
1262 *(INSTRUCTION_TYPE
*)ptr
= RETURN_INSTRUCTION
;
1263 ptr
+= INSN_CACHE_LINE_WIDTH
;
1269 /* Find the location in array that occupies the same cache line as BEG. */
1271 offset
= ((int) beg
& -INSN_CACHE_LINE_WIDTH
) & (INSN_CACHE_PLANE_SIZE
- 1);
1272 start_addr
= (((int) (array
+ INSN_CACHE_PLANE_SIZE
- 1)
1273 & -INSN_CACHE_PLANE_SIZE
)
1276 /* Compute the cache alignment of the place to stop clearing. */
1277 #if 0 /* This is not needed for gcc's purposes. */
1278 /* If the block to clear is bigger than a cache plane,
1279 we clear the entire cache, and OFFSET is already correct. */
1280 if (end
< beg
+ INSN_CACHE_PLANE_SIZE
)
1282 offset
= (((int) (end
+ INSN_CACHE_LINE_WIDTH
- 1)
1283 & -INSN_CACHE_LINE_WIDTH
)
1284 & (INSN_CACHE_PLANE_SIZE
- 1));
1286 #if INSN_CACHE_DEPTH > 1
1287 end_addr
= (start_addr
& -INSN_CACHE_PLANE_SIZE
) + offset
;
1288 if (end_addr
<= start_addr
)
1289 end_addr
+= INSN_CACHE_PLANE_SIZE
;
1291 for (plane
= 0; plane
< INSN_CACHE_DEPTH
; plane
++)
1293 int addr
= start_addr
+ plane
* INSN_CACHE_PLANE_SIZE
;
1294 int stop
= end_addr
+ plane
* INSN_CACHE_PLANE_SIZE
;
1296 while (addr
!= stop
)
1298 /* Call the return instruction at ADDR. */
1299 ((function_ptr
) addr
) ();
1301 addr
+= INSN_CACHE_LINE_WIDTH
;
1304 #else /* just one plane */
1307 /* Call the return instruction at START_ADDR. */
1308 ((function_ptr
) start_addr
) ();
1310 start_addr
+= INSN_CACHE_LINE_WIDTH
;
1312 while ((start_addr
% INSN_CACHE_SIZE
) != offset
);
1313 #endif /* just one plane */
1314 #endif /* Cache is large */
1315 #endif /* Cache exists */
1318 #endif /* L_clear_cache */
1322 /* Jump to a trampoline, loading the static chain address. */
1324 #ifdef TRANSFER_FROM_TRAMPOLINE
1325 TRANSFER_FROM_TRAMPOLINE
1330 /* Make stack executable so we can call trampolines on stack.
1331 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
1333 #include <sys/mman.h>
1334 #include <sys/vmparam.h>
1335 #include <machine/machparam.h>
1338 __enable_execute_stack ()
1341 static unsigned lowest
= USRSTACK
;
1342 unsigned current
= (unsigned) &fp
& -NBPG
;
1344 if (lowest
> current
)
1346 unsigned len
= lowest
- current
;
1347 mremap (current
, &len
, PROT_READ
| PROT_WRITE
| PROT_EXEC
, MAP_PRIVATE
);
1351 /* Clear instruction cache in case an old trampoline is in it. */
1354 #endif /* __convex__ */
1359 #include <sys/mman.h>
1360 #include <sys/types.h>
1361 #include <sys/param.h>
1362 #include <sys/vmmac.h>
1364 /* Modified from the convex -code above.
1365 mremap promises to clear the i-cache. */
1368 __enable_execute_stack ()
1371 if (mprotect (((unsigned int)&fp
/PAGSIZ
)*PAGSIZ
, PAGSIZ
,
1372 PROT_READ
|PROT_WRITE
|PROT_EXEC
))
1374 perror ("mprotect in __enable_execute_stack");
1379 #endif /* __pyr__ */
1380 #endif /* L_trampoline */
1384 #include "gbl-ctors.h"
1386 /* Run all the global destructors on exit from the program. */
1389 __do_global_dtors ()
1391 #ifdef DO_GLOBAL_DTORS_BODY
1392 DO_GLOBAL_DTORS_BODY
;
1394 unsigned nptrs
= (unsigned) __DTOR_LIST__
[0];
1397 /* Some systems place the number of pointers
1398 in the first word of the table.
1399 On other systems, that word is -1.
1400 In all cases, the table is null-terminated. */
1402 /* If the length is not recorded, count up to the null. */
1404 for (nptrs
= 0; __DTOR_LIST__
[nptrs
+ 1] != 0; nptrs
++);
1406 /* GNU LD format. */
1407 for (i
= nptrs
; i
>= 1; i
--)
1408 __DTOR_LIST__
[i
] ();
1412 #ifndef INIT_SECTION_ASM_OP
1413 /* Run all the global constructors on entry to the program. */
1416 #define ON_EXIT(a, b)
1418 /* Make sure the exit routine is pulled in to define the globals as
1419 bss symbols, just in case the linker does not automatically pull
1420 bss definitions from the library. */
1422 extern int _exit_dummy_decl
;
1423 int *_exit_dummy_ref
= &_exit_dummy_decl
;
1424 #endif /* ON_EXIT */
1427 __do_global_ctors ()
1429 DO_GLOBAL_CTORS_BODY
;
1430 ON_EXIT (__do_global_dtors
, 0);
1432 #endif /* no INIT_SECTION_ASM_OP */
1434 #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
1435 /* Subroutine called automatically by `main'.
1436 Compiling a global function named `main'
1437 produces an automatic call to this function at the beginning.
1439 For many systems, this routine calls __do_global_ctors.
1440 For systems which support a .init section we use the .init section
1441 to run __do_global_ctors, so we need not do anything here. */
1446 /* Support recursive calls to `main': run initializers just once. */
1447 static int initialized
= 0;
1451 __do_global_ctors ();
1454 #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
1456 #endif /* L__main */
1460 #include "gbl-ctors.h"
1462 /* Provide default definitions for the lists of constructors and
1463 destructors, so that we don't get linker errors. These symbols are
1464 intentionally bss symbols, so that gld and/or collect will provide
1465 the right values. */
1467 /* We declare the lists here with two elements each,
1468 so that they are valid empty lists if no other definition is loaded. */
1469 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
1470 func_ptr __CTOR_LIST__
[2];
1471 func_ptr __DTOR_LIST__
[2];
1472 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1476 /* If we have no known way of registering our own __do_global_dtors
1477 routine so that it will be invoked at program exit time, then we
1478 have to define our own exit routine which will get this to happen. */
1480 extern void __do_global_dtors ();
1481 extern void _cleanup ();
1482 extern void _exit ();
1488 __do_global_dtors ();
1498 int _exit_dummy_decl
= 0; /* prevent compiler & linker warnings */
1503 /* In a.out systems, we need to have these dummy constructor and destructor
1504 lists in the library.
1506 When using `collect', the first link will resolve __CTOR_LIST__
1507 and __DTOR_LIST__ to these symbols. We will then run "nm" on the
1508 result, build the correct __CTOR_LIST__ and __DTOR_LIST__, and relink.
1509 Since we don't do the second link if no constructors existed, these
1510 dummies must be fully functional empty lists.
1512 When using `gnu ld', these symbols will be used if there are no
1513 constructors. If there are constructors, the N_SETV symbol defined
1514 by the linker from the N_SETT's in input files will define __CTOR_LIST__
1515 and __DTOR_LIST__ rather than its being allocated as common storage
1516 by the definitions below.
1518 When using a linker that supports constructor and destructor segments,
1519 these definitions will not be used, since crtbegin.o and crtend.o
1520 (from crtstuff.c) will have already defined __CTOR_LIST__ and
1521 __DTOR_LIST__. The crt*.o files are passed directly to the linker
1522 on its command line, by gcc. */
1524 /* The list needs two elements: one is ignored (the old count); the
1525 second is the terminating zero. Since both values are zero, this
1526 declaration is not initialized, and it becomes `common'. */
1529 #include "gbl-ctors.h"
1530 func_ptr __CTOR_LIST__
[2];
1534 #include "gbl-ctors.h"
1535 func_ptr __DTOR_LIST__
[2];
This page took 0.109318 seconds and 6 git commands to generate.