]>
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 /* Need to undef this because LONG_TYPE_SIZE may rely upon GCC's
42 internal `target_flags' variable. */
45 #define LONG_TYPE_SIZE (sizeof (long) * BITS_PER_UNIT)
48 #define SItype long int
51 /* long long ints are pairs of long ints in the order determined by
55 struct longlong
{long high
, low
;};
57 struct longlong
{long low
, high
;};
60 /* We need this union to unpack/pack longlongs, since we don't have
61 any arithmetic yet. Incoming long long parameters are stored
62 into the `ll' field, and the unpacked result is read from the struct
71 #if defined (L_udivmoddi4) || defined (L_muldi3)
75 #endif /* udiv or mul */
77 extern long long __fixunssfdi (float a
);
78 extern long long __fixunsdfdi (double a
);
80 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
81 #if defined (L_divdi3) || defined (L_moddi3)
94 w
.s
.high
= -uu
.s
.high
- ((unsigned long) w
.s
.low
> 0);
115 bm
= (sizeof (long) * BITS_PER_UNIT
) - b
;
119 w
.s
.high
= (unsigned long)uu
.s
.low
<< -bm
;
123 unsigned long carries
= (unsigned long)uu
.s
.low
>> bm
;
124 w
.s
.low
= (unsigned long)uu
.s
.low
<< b
;
125 w
.s
.high
= ((unsigned long)uu
.s
.high
<< b
) | carries
;
147 bm
= (sizeof (long) * BITS_PER_UNIT
) - b
;
151 w
.s
.low
= (unsigned long)uu
.s
.high
>> -bm
;
155 unsigned long carries
= (unsigned long)uu
.s
.high
<< bm
;
156 w
.s
.high
= (unsigned long)uu
.s
.high
>> b
;
157 w
.s
.low
= ((unsigned long)uu
.s
.low
>> b
) | carries
;
179 bm
= (sizeof (long) * BITS_PER_UNIT
) - b
;
183 w
.s
.high
= (unsigned long)uu
.s
.low
<< -bm
;
187 unsigned long carries
= (unsigned long)uu
.s
.low
>> bm
;
188 w
.s
.low
= (unsigned long)uu
.s
.low
<< b
;
189 w
.s
.high
= ((unsigned long)uu
.s
.high
<< b
) | carries
;
211 bm
= (sizeof (long) * BITS_PER_UNIT
) - b
;
214 /* w.s.high = 1..1 or 0..0 */
215 w
.s
.high
= uu
.s
.high
>> (sizeof (long) * BITS_PER_UNIT
- 1);
216 w
.s
.low
= uu
.s
.high
>> -bm
;
220 unsigned long carries
= (unsigned long)uu
.s
.high
<< bm
;
221 w
.s
.high
= uu
.s
.high
>> b
;
222 w
.s
.low
= ((unsigned long)uu
.s
.low
>> b
) | carries
;
240 w
.ll
= __umulsidi3 (uu
.s
.low
, vv
.s
.low
);
241 w
.s
.high
+= ((unsigned long) uu
.s
.low
* (unsigned long) vv
.s
.high
242 + (unsigned long) uu
.s
.high
* (unsigned long) vv
.s
.low
);
249 static const unsigned char __clz_tab
[] =
251 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,
252 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,
253 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,
254 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,
255 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,
256 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,
257 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,
258 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,
262 __udivmoddi4 (n
, d
, rp
)
263 unsigned long long n
, d
;
264 unsigned long long int *rp
;
269 unsigned long d0
, d1
, n0
, n1
, n2
;
270 unsigned long q0
, q1
;
281 #if !UDIV_NEEDS_NORMALIZATION
288 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
291 /* Remainder in n0. */
298 d0
= 1 / d0
; /* Divide intentionally by zero. */
300 udiv_qrnnd (q1
, n1
, 0, n1
, d0
);
301 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
303 /* Remainder in n0. */
314 #else /* UDIV_NEEDS_NORMALIZATION */
322 count_leading_zeros (bm
, d0
);
326 /* Normalize, i.e. make the most significant bit of the
330 n1
= (n1
<< bm
) | (n0
>> (LONG_TYPE_SIZE
- bm
));
334 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
337 /* Remainder in n0 >> bm. */
344 d0
= 1 / d0
; /* Divide intentionally by zero. */
346 count_leading_zeros (bm
, d0
);
350 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
351 conclude (the most significant bit of n1 is set) /\ (the
352 leading quotient digit q1 = 1).
354 This special case is necessary, not an optimization.
355 (Shifts counts of LONG_TYPE_SIZE are undefined.) */
364 b
= LONG_TYPE_SIZE
- bm
;
368 n1
= (n1
<< bm
) | (n0
>> b
);
371 udiv_qrnnd (q1
, n1
, n2
, n1
, d0
);
376 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
378 /* Remainder in n0 >> bm. */
388 #endif /* UDIV_NEEDS_NORMALIZATION */
399 /* Remainder in n1n0. */
411 count_leading_zeros (bm
, d1
);
414 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
415 conclude (the most significant bit of n1 is set) /\ (the
416 quotient digit q0 = 0 or 1).
418 This special case is necessary, not an optimization. */
420 /* The condition on the next line takes advantage of that
421 n1 >= d1 (true due to program flow). */
422 if (n1
> d1
|| n0
>= d0
)
425 sub_ddmmss (n1
, n0
, n1
, n0
, d1
, d0
);
441 unsigned long m1
, m0
;
444 b
= LONG_TYPE_SIZE
- bm
;
446 d1
= (d1
<< bm
) | (d0
>> b
);
449 n1
= (n1
<< bm
) | (n0
>> b
);
452 udiv_qrnnd (q0
, n1
, n2
, n1
, d1
);
453 umul_ppmm (m1
, m0
, q0
, d0
);
455 if (m1
> n1
|| (m1
== n1
&& m0
> n0
))
458 sub_ddmmss (m1
, m0
, m1
, m0
, d1
, d0
);
463 /* Remainder in (n1n0 - m1m0) >> bm. */
466 sub_ddmmss (n1
, n0
, n1
, n0
, m1
, m0
);
467 rr
.s
.low
= (n1
<< b
) | (n0
>> bm
);
468 rr
.s
.high
= n1
>> bm
;
482 unsigned long long __udivmoddi4 ();
496 uu
.ll
= __negdi2 (uu
.ll
);
499 vv
.ll
= __negdi2 (vv
.ll
);
501 w
= __udivmoddi4 (uu
.ll
, vv
.ll
, (unsigned long long *) 0);
510 unsigned long long __udivmoddi4 ();
524 uu
.ll
= __negdi2 (uu
.ll
);
526 vv
.ll
= __negdi2 (vv
.ll
);
528 (void) __udivmoddi4 (uu
.ll
, vv
.ll
, &w
);
537 unsigned long long __udivmoddi4 ();
540 unsigned long long u
, v
;
544 (void) __udivmoddi4 (u
, v
, &w
);
551 unsigned long long __udivmoddi4 ();
554 unsigned long long n
, d
;
556 return __udivmoddi4 (n
, d
, (unsigned long long *) 0);
567 au
.ll
= a
, bu
.ll
= b
;
569 if (au
.s
.high
< bu
.s
.high
)
571 else if (au
.s
.high
> bu
.s
.high
)
573 if ((unsigned long) au
.s
.low
< (unsigned long) bu
.s
.low
)
575 else if ((unsigned long) au
.s
.low
> (unsigned long) bu
.s
.low
)
588 au
.ll
= a
, bu
.ll
= b
;
590 if ((unsigned long) au
.s
.high
< (unsigned long) bu
.s
.high
)
592 else if ((unsigned long) au
.s
.high
> (unsigned long) bu
.s
.high
)
594 if ((unsigned long) au
.s
.low
< (unsigned long) bu
.s
.low
)
596 else if ((unsigned long) au
.s
.low
> (unsigned long) bu
.s
.low
)
603 #define WORD_SIZE (sizeof (long) * BITS_PER_UNIT)
604 #define HIGH_WORD_COEFF (((long long) 1) << WORD_SIZE)
611 unsigned long long v
;
616 /* Compute high word of result, as a flonum. */
617 b
= (a
/ HIGH_WORD_COEFF
);
618 /* Convert that to fixed (but not to long long!),
619 and shift it into the high word. */
620 v
= (unsigned long int) b
;
622 /* Remove high part from the double, leaving the low part as flonum. */
624 /* Convert that to fixed (but not to long long!) and add it in.
625 Sometimes A comes out negative. This is significant, since
626 A has more bits than a long int does. */
628 v
-= (unsigned long int) (- a
);
630 v
+= (unsigned long int) a
;
641 return - __fixunsdfdi (-a
);
642 return __fixunsdfdi (a
);
647 #define WORD_SIZE (sizeof (long) * BITS_PER_UNIT)
648 #define HIGH_WORD_COEFF (((long long) 1) << WORD_SIZE)
651 __fixunssfdi (float original_a
)
653 /* Convert the float to a double, because that is surely not going
654 to lose any bits. Some day someone else can write a faster version
655 that avoids converting to double, and verify it really works right. */
656 double a
= original_a
;
658 unsigned long long v
;
663 /* Compute high word of result, as a flonum. */
664 b
= (a
/ HIGH_WORD_COEFF
);
665 /* Convert that to fixed (but not to long long!),
666 and shift it into the high word. */
667 v
= (unsigned long int) b
;
669 /* Remove high part from the double, leaving the low part as flonum. */
671 /* Convert that to fixed (but not to long long!) and add it in.
672 Sometimes A comes out negative. This is significant, since
673 A has more bits than a long int does. */
675 v
-= (unsigned long int) (- a
);
677 v
+= (unsigned long int) a
;
687 return - __fixunssfdi (-a
);
688 return __fixunssfdi (a
);
693 #define WORD_SIZE (sizeof (long) * BITS_PER_UNIT)
694 #define HIGH_HALFWORD_COEFF (((long long) 1) << (WORD_SIZE / 2))
695 #define HIGH_WORD_COEFF (((long long) 1) << WORD_SIZE)
707 d
= (unsigned int) (u
>> WORD_SIZE
);
708 d
*= HIGH_HALFWORD_COEFF
;
709 d
*= HIGH_HALFWORD_COEFF
;
710 d
+= (unsigned int) (u
& (HIGH_WORD_COEFF
- 1));
712 return (negate
? -d
: d
);
717 #define WORD_SIZE (sizeof (long) * BITS_PER_UNIT)
718 #define HIGH_HALFWORD_COEFF (((long long) 1) << (WORD_SIZE / 2))
719 #define HIGH_WORD_COEFF (((long long) 1) << WORD_SIZE)
731 f
= (unsigned int) (u
>> WORD_SIZE
);
732 f
*= HIGH_HALFWORD_COEFF
;
733 f
*= HIGH_HALFWORD_COEFF
;
734 f
+= (unsigned int) (u
& (HIGH_WORD_COEFF
- 1));
736 return (negate
? -f
: f
);
747 if (a
>= - (double) LONG_MIN
)
748 return (SItype
) (a
+ LONG_MIN
) - LONG_MIN
;
757 __fixunssfsi (float a
)
759 if (a
>= - (float) LONG_MIN
)
760 return (SItype
) (a
+ LONG_MIN
) - LONG_MIN
;
767 #if defined(SVR4) || defined(__alliant__)
771 /* The Alliant needs the added underscore. */
772 asm (".globl __builtin_saveregs");
773 asm ("__builtin_saveregs:");
774 asm (".globl ___builtin_saveregs");
775 asm ("___builtin_saveregs:");
777 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
778 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
779 area and also for a new va_list
781 /* Save all argument registers in the arg reg save area. The
782 arg reg save area must have the following layout (according
794 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
795 asm (" fst.q %f12,16(%sp)");
797 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
798 asm (" st.l %r17,36(%sp)");
799 asm (" st.l %r18,40(%sp)");
800 asm (" st.l %r19,44(%sp)");
801 asm (" st.l %r20,48(%sp)");
802 asm (" st.l %r21,52(%sp)");
803 asm (" st.l %r22,56(%sp)");
804 asm (" st.l %r23,60(%sp)");
805 asm (" st.l %r24,64(%sp)");
806 asm (" st.l %r25,68(%sp)");
807 asm (" st.l %r26,72(%sp)");
808 asm (" st.l %r27,76(%sp)");
810 asm (" adds 80,%sp,%r16"); /* compute the address of the new
811 va_list structure. Put in into
812 r16 so that it will be returned
815 /* Initialize all fields of the new va_list structure. This
816 structure looks like:
819 unsigned long ireg_used;
820 unsigned long freg_used;
826 asm (" st.l %r0, 0(%r16)"); /* nfixed */
827 asm (" st.l %r0, 4(%r16)"); /* nfloating */
828 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
829 asm (" bri %r1"); /* delayed return */
830 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
836 asm (".globl ___builtin_saveregs");
837 asm ("___builtin_saveregs:");
839 asm (" andnot 0x0f,sp,sp");
840 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
842 /* Fill in the __va_struct. */
843 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
844 asm (" st.l r17, 4(sp)"); /* int fixed[12] */
845 asm (" st.l r18, 8(sp)");
846 asm (" st.l r19,12(sp)");
847 asm (" st.l r20,16(sp)");
848 asm (" st.l r21,20(sp)");
849 asm (" st.l r22,24(sp)");
850 asm (" st.l r23,28(sp)");
851 asm (" st.l r24,32(sp)");
852 asm (" st.l r25,36(sp)");
853 asm (" st.l r26,40(sp)");
854 asm (" st.l r27,44(sp)");
856 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
857 asm (" fst.q f12,64(sp)"); /* int floating[8] */
859 /* Fill in the __va_ctl. */
860 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
861 asm (" st.l r28,84(sp)"); /* pointer to more args */
862 asm (" st.l r0, 88(sp)"); /* nfixed */
863 asm (" st.l r0, 92(sp)"); /* nfloating */
865 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
868 /* recover stack and pass address to start
870 #endif /* not SVR4 */
871 #else /* not __i860__ */
873 asm (".global __builtin_saveregs");
874 asm ("__builtin_saveregs:");
875 asm (".global ___builtin_saveregs");
876 asm ("___builtin_saveregs:");
877 #ifdef NEED_PROC_COMMAND
880 asm ("st %i0,[%fp+68]");
881 asm ("st %i1,[%fp+72]");
882 asm ("st %i2,[%fp+76]");
883 asm ("st %i3,[%fp+80]");
884 asm ("st %i4,[%fp+84]");
886 asm ("st %i5,[%fp+88]");
887 #ifdef NEED_TYPE_COMMAND
888 asm (".type __builtin_saveregs,#function");
889 asm (".size __builtin_saveregs,.-__builtin_saveregs");
891 #else /* not __sparc__ */
892 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
895 asm (" .ent __builtin_saveregs");
896 asm (" .globl __builtin_saveregs");
897 asm ("__builtin_saveregs:");
898 asm (" sw $4,0($30)");
899 asm (" sw $5,4($30)");
900 asm (" sw $6,8($30)");
901 asm (" sw $7,12($30)");
903 asm (" .end __builtin_saveregs");
904 #else /* not __mips__, etc. */
905 __builtin_saveregs ()
909 #endif /* not __mips__ */
910 #endif /* not __sparc__ */
911 #endif /* not __i860__ */
915 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
917 /* This is used by the `assert' macro. */
919 __eprintf (string
, expression
, line
, filename
)
921 const char *expression
;
923 const char *filename
;
925 fprintf (stderr
, string
, expression
, line
, filename
);
932 /* Avoid warning from ranlib about empty object file. */
934 __bb_avoid_warning ()
937 #if defined (__sun__) && defined (__mc68000__)
948 extern int ___tcov_init
;
950 __bb_init_func (blocks
)
954 ___tcov_init_func ();
956 ___bb_link (blocks
->filename
, blocks
->counts
, blocks
->ncounts
);
965 typedef void (*vfp
)(void);
967 extern vfp __new_handler
;
968 extern void *malloc ();
984 typedef void (*vfp
)(void);
986 extern void *__builtin_new (size_t);
987 static void default_new_handler (void);
989 vfp __new_handler
= default_new_handler
;
992 __builtin_vec_new (p
, maxindex
, size
, ctor
)
996 void (*ctor
)(void *);
999 size_t nelts
= maxindex
+ 1;
1003 p
= __builtin_new (nelts
* size
);
1007 for (i
= 0; i
< nelts
; i
++)
1017 __set_new_handler (handler
)
1022 prev_handler
= __new_handler
;
1023 if (handler
== 0) handler
= default_new_handler
;
1024 __new_handler
= handler
;
1025 return prev_handler
;
1029 set_new_handler (handler
)
1032 return __set_new_handler (handler
);
1035 #define MESSAGE "Virtual memory exceeded in `new'\n"
1038 default_new_handler ()
1040 /* don't use fprintf (stderr, ...) because it may need to call malloc. */
1041 /* This should really print the name of the program, but that is hard to
1042 do. We need a standard, clean way to get at the name. */
1043 write (2, MESSAGE
, sizeof (MESSAGE
));
1044 /* don't call exit () because that may call global destructors which
1045 may cause a loop. */
1050 #ifdef L_builtin_del
1051 typedef void (*vfp
)(void);
1054 __builtin_delete (ptr
)
1062 __builtin_vec_delete (ptr
, maxindex
, size
, dtor
, auto_delete_vec
, auto_delete
)
1066 void (*dtor
)(void *, int);
1070 size_t nelts
= maxindex
+ 1;
1073 ptr
+= nelts
* size
;
1075 for (i
= 0; i
< nelts
; i
++)
1078 (*dtor
) (ptr
, auto_delete
);
1081 if (auto_delete_vec
)
1082 __builtin_delete (p
);
1088 unsigned int __shtab
[] = {
1089 0x00000001, 0x00000002, 0x00000004, 0x00000008,
1090 0x00000010, 0x00000020, 0x00000040, 0x00000080,
1091 0x00000100, 0x00000200, 0x00000400, 0x00000800,
1092 0x00001000, 0x00002000, 0x00004000, 0x00008000,
1093 0x00010000, 0x00020000, 0x00040000, 0x00080000,
1094 0x00100000, 0x00200000, 0x00400000, 0x00800000,
1095 0x01000000, 0x02000000, 0x04000000, 0x08000000,
1096 0x10000000, 0x20000000, 0x40000000, 0x80000000
1100 #ifdef L_clear_cache
1101 /* Clear part of an instruction cache. */
1103 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1106 __clear_cache (beg
, end
)
1109 #ifdef INSN_CACHE_SIZE
1110 static char array
[INSN_CACHE_SIZE
+ INSN_CACHE_PLANE_SIZE
+ INSN_CACHE_LINE_WIDTH
];
1111 static int initialized
= 0;
1115 typedef (*function_ptr
) ();
1117 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1118 /* It's cheaper to clear the whole cache.
1119 Put in a series of jump instructions so that calling the beginning
1120 of the cache will clear the whole thing. */
1124 int ptr
= (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
1125 & -INSN_CACHE_LINE_WIDTH
);
1126 int end_ptr
= ptr
+ INSN_CACHE_SIZE
;
1128 while (ptr
< end_ptr
)
1130 *(INSTRUCTION_TYPE
*)ptr
1131 = JUMP_AHEAD_INSTRUCTION
+ INSN_CACHE_LINE_WIDTH
;
1132 ptr
+= INSN_CACHE_LINE_WIDTH
;
1134 *(INSTRUCTION_TYPE
*)(ptr
- INSN_CACHE_LINE_WIDTH
) = RETURN_INSTRUCTION
;
1139 /* Call the beginning of the sequence. */
1140 (((function_ptr
) (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
1141 & -INSN_CACHE_LINE_WIDTH
))
1144 #else /* Cache is large. */
1148 int ptr
= (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
1149 & -INSN_CACHE_LINE_WIDTH
);
1151 while (ptr
< (int) array
+ sizeof array
)
1153 *(INSTRUCTION_TYPE
*)ptr
= RETURN_INSTRUCTION
;
1154 ptr
+= INSN_CACHE_LINE_WIDTH
;
1160 /* Find the location in array that occupies the same cache line as BEG. */
1162 offset
= ((int) beg
& -INSN_CACHE_LINE_WIDTH
) & (INSN_CACHE_PLANE_SIZE
- 1);
1163 start_addr
= (((int) (array
+ INSN_CACHE_PLANE_SIZE
- 1)
1164 & -INSN_CACHE_PLANE_SIZE
)
1167 /* Compute the cache alignment of the place to stop clearing. */
1168 #if 0 /* This is not needed for gcc's purposes. */
1169 /* If the block to clear is bigger than a cache plane,
1170 we clear the entire cache, and OFFSET is already correct. */
1171 if (end
< beg
+ INSN_CACHE_PLANE_SIZE
)
1173 offset
= (((int) (end
+ INSN_CACHE_LINE_WIDTH
- 1)
1174 & -INSN_CACHE_LINE_WIDTH
)
1175 & (INSN_CACHE_PLANE_SIZE
- 1));
1177 #if INSN_CACHE_DEPTH > 1
1178 end_addr
= (start_addr
& -INSN_CACHE_PLANE_SIZE
) + offset
;
1179 if (end_addr
<= start_addr
)
1180 end_addr
+= INSN_CACHE_PLANE_SIZE
;
1182 for (plane
= 0; plane
< INSN_CACHE_DEPTH
; plane
++)
1184 int addr
= start_addr
+ plane
* INSN_CACHE_PLANE_SIZE
;
1185 int stop
= end_addr
+ plane
* INSN_CACHE_PLANE_SIZE
;
1187 while (addr
!= stop
)
1189 /* Call the return instruction at ADDR. */
1190 ((function_ptr
) addr
) ();
1192 addr
+= INSN_CACHE_LINE_WIDTH
;
1195 #else /* just one plane */
1198 /* Call the return instruction at START_ADDR. */
1199 ((function_ptr
) start_addr
) ();
1201 start_addr
+= INSN_CACHE_LINE_WIDTH
;
1203 while ((start_addr
% INSN_CACHE_SIZE
) != offset
);
1204 #endif /* just one plane */
1205 #endif /* Cache is large */
1206 #endif /* Cache exists */
1209 #endif /* L_clear_cache */
1213 /* Jump to a trampoline, loading the static chain address. */
1215 #ifdef TRANSFER_FROM_TRAMPOLINE
1216 TRANSFER_FROM_TRAMPOLINE
1221 /* Make stack executable so we can call trampolines on stack.
1222 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
1224 #include <sys/mman.h>
1225 #include <sys/vmparam.h>
1226 #include <machine/machparam.h>
1229 __enable_execute_stack ()
1232 static unsigned lowest
= USRSTACK
;
1233 unsigned current
= (unsigned) &fp
& -NBPG
;
1235 if (lowest
> current
)
1237 unsigned len
= lowest
- current
;
1238 mremap (current
, &len
, PROT_READ
| PROT_WRITE
| PROT_EXEC
, MAP_PRIVATE
);
1242 /* Clear instruction cache in case an old trampoline is in it. */
1245 #endif /* __convex__ */
1250 #include <sys/mman.h>
1251 #include <sys/types.h>
1252 #include <sys/param.h>
1253 #include <sys/vmmac.h>
1255 /* Modified from the convex -code above.
1256 mremap promises to clear the i-cache. */
1259 __enable_execute_stack ()
1262 if (mprotect (((unsigned int)&fp
/PAGSIZ
)*PAGSIZ
, PAGSIZ
,
1263 PROT_READ
|PROT_WRITE
|PROT_EXEC
))
1265 perror ("mprotect in __enable_execute_stack");
1270 #endif /* __pyr__ */
1271 #endif /* L_trampoline */
1275 #include "gbl-ctors.h"
1277 /* Run all the global destructors on exit from the program. */
1280 __do_global_dtors ()
1282 #ifdef DO_GLOBAL_DTORS_BODY
1283 DO_GLOBAL_DTORS_BODY
;
1285 unsigned nptrs
= (unsigned) __DTOR_LIST__
[0];
1288 /* Some systems place the number of pointers
1289 in the first word of the table.
1290 On other systems, that word is -1.
1291 In all cases, the table is null-terminated. */
1293 /* If the length is not recorded, count up to the null. */
1295 for (nptrs
= 0; __DTOR_LIST__
[nptrs
+ 1] != 0; nptrs
++);
1297 /* GNU LD format. */
1298 for (i
= nptrs
; i
>= 1; i
--)
1299 __DTOR_LIST__
[i
] ();
1303 #ifndef INIT_SECTION_ASM_OP
1304 /* Run all the global constructors on entry to the program. */
1307 #define ON_EXIT(a, b)
1309 /* Make sure the exit routine is pulled in to define the globals as
1310 bss symbols, just in case the linker does not automatically pull
1311 bss definitions from the library. */
1313 extern int _exit_dummy_decl
;
1314 int *_exit_dummy_ref
= &_exit_dummy_decl
;
1315 #endif /* ON_EXIT */
1318 __do_global_ctors ()
1320 DO_GLOBAL_CTORS_BODY
;
1321 ON_EXIT (__do_global_dtors
, 0);
1323 #endif /* no INIT_SECTION_ASM_OP */
1325 #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
1326 /* Subroutine called automatically by `main'.
1327 Compiling a global function named `main'
1328 produces an automatic call to this function at the beginning.
1330 For many systems, this routine calls __do_global_ctors.
1331 For systems which support a .init section we use the .init section
1332 to run __do_global_ctors, so we need not do anything here. */
1337 /* Support recursive calls to `main': run initializers just once. */
1338 static int initialized
= 0;
1342 __do_global_ctors ();
1345 #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
1347 #endif /* L__main */
1351 #include "gbl-ctors.h"
1353 /* Provide default definitions for the lists of constructors and
1354 destructors, so that we don't get linker errors. These symbols are
1355 intentionally bss symbols, so that gld and/or collect will provide
1356 the right values. */
1358 /* We declare the lists here with two elements each,
1359 so that they are valid empty lists if no other definition is loaded. */
1360 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
1361 func_ptr __CTOR_LIST__
[2];
1362 func_ptr __DTOR_LIST__
[2];
1363 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1367 /* If we have no known way of registering our own __do_global_dtors
1368 routine so that it will be invoked at program exit time, then we
1369 have to define our own exit routine which will get this to happen. */
1371 extern void __do_global_dtors ();
1372 extern void _cleanup ();
1373 extern void _exit ();
1379 __do_global_dtors ();
1389 int _exit_dummy_decl
= 0; /* prevent compiler & linker warnings */
1394 /* In a.out systems, we need to have these dummy constructor and destructor
1395 lists in the library.
1397 When using `collect', the first link will resolve __CTOR_LIST__
1398 and __DTOR_LIST__ to these symbols. We will then run "nm" on the
1399 result, build the correct __CTOR_LIST__ and __DTOR_LIST__, and relink.
1400 Since we don't do the second link if no constructors existed, these
1401 dummies must be fully functional empty lists.
1403 When using `gnu ld', these symbols will be used if there are no
1404 constructors. If there are constructors, the N_SETV symbol defined
1405 by the linker from the N_SETT's in input files will define __CTOR_LIST__
1406 and __DTOR_LIST__ rather than its being allocated as common storage
1407 by the definitions below.
1409 When using a linker that supports constructor and destructor segments,
1410 these definitions will not be used, since crtbegin.o and crtend.o
1411 (from crtstuff.c) will have already defined __CTOR_LIST__ and
1412 __DTOR_LIST__. The crt*.o files are passed directly to the linker
1413 on its command line, by gcc. */
1415 /* The list needs two elements: one is ignored (the old count); the
1416 second is the terminating zero. Since both values are zero, this
1417 declaration is not initialized, and it becomes `common'. */
1420 #include "gbl-ctors.h"
1421 func_ptr __CTOR_LIST__
[2];
1425 #include "gbl-ctors.h"
1426 func_ptr __DTOR_LIST__
[2];
This page took 0.099362 seconds and 5 git commands to generate.