]>
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
;
771 asm (".globl __builtin_saveregs");
772 asm ("__builtin_saveregs:");
773 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
774 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
775 area and also for a new va_list
777 /* Save all argument registers in the arg reg save area. The
778 arg reg save area must have the following layout (according
790 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
791 asm (" fst.q %f12,16(%sp)");
793 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
794 asm (" st.l %r17,36(%sp)");
795 asm (" st.l %r18,40(%sp)");
796 asm (" st.l %r19,44(%sp)");
797 asm (" st.l %r20,48(%sp)");
798 asm (" st.l %r21,52(%sp)");
799 asm (" st.l %r22,56(%sp)");
800 asm (" st.l %r23,60(%sp)");
801 asm (" st.l %r24,64(%sp)");
802 asm (" st.l %r25,68(%sp)");
803 asm (" st.l %r26,72(%sp)");
804 asm (" st.l %r27,76(%sp)");
806 asm (" adds 80,%sp,%r16"); /* compute the address of the new
807 va_list structure. Put in into
808 r16 so that it will be returned
811 /* Initialize all fields of the new va_list structure. This
812 structure looks like:
815 unsigned long ireg_used;
816 unsigned long freg_used;
822 asm (" st.l %r0, 0(%r16)"); /* nfixed */
823 asm (" st.l %r0, 4(%r16)"); /* nfloating */
824 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
825 asm (" bri %r1"); /* delayed return */
826 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
832 asm (".globl ___builtin_saveregs");
833 asm ("___builtin_saveregs:");
835 asm (" andnot 0x0f,sp,sp");
836 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
838 /* Fill in the __va_struct. */
839 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
840 asm (" st.l r17, 4(sp)"); /* int fixed[12] */
841 asm (" st.l r18, 8(sp)");
842 asm (" st.l r19,12(sp)");
843 asm (" st.l r20,16(sp)");
844 asm (" st.l r21,20(sp)");
845 asm (" st.l r22,24(sp)");
846 asm (" st.l r23,28(sp)");
847 asm (" st.l r24,32(sp)");
848 asm (" st.l r25,36(sp)");
849 asm (" st.l r26,40(sp)");
850 asm (" st.l r27,44(sp)");
852 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
853 asm (" fst.q f12,64(sp)"); /* int floating[8] */
855 /* Fill in the __va_ctl. */
856 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
857 asm (" st.l r28,84(sp)"); /* pointer to more args */
858 asm (" st.l r0, 88(sp)"); /* nfixed */
859 asm (" st.l r0, 92(sp)"); /* nfloating */
861 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
864 /* recover stack and pass address to start
866 #endif /* not SVR4 */
867 #else /* not __i860__ */
869 asm (".global __builtin_saveregs");
870 asm ("__builtin_saveregs:");
871 asm (".global ___builtin_saveregs");
872 asm ("___builtin_saveregs:");
873 #ifdef NEED_PROC_COMMAND
876 asm ("st %i0,[%fp+68]");
877 asm ("st %i1,[%fp+72]");
878 asm ("st %i2,[%fp+76]");
879 asm ("st %i3,[%fp+80]");
880 asm ("st %i4,[%fp+84]");
882 asm ("st %i5,[%fp+88]");
883 #ifdef NEED_TYPE_COMMAND
884 asm (".type __builtin_saveregs,#function");
885 asm (".size __builtin_saveregs,.-__builtin_saveregs");
887 #else /* not __sparc__ */
888 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
891 asm (" .ent __builtin_saveregs");
892 asm (" .globl __builtin_saveregs");
893 asm ("__builtin_saveregs:");
894 asm (" sw $4,0($30)");
895 asm (" sw $5,4($30)");
896 asm (" sw $6,8($30)");
897 asm (" sw $7,12($30)");
899 asm (" .end __builtin_saveregs");
900 #else /* not __mips__, etc. */
901 __builtin_saveregs ()
905 #endif /* not __mips__ */
906 #endif /* not __sparc__ */
907 #endif /* not __i860__ */
911 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
913 /* This is used by the `assert' macro. */
915 __eprintf (string
, expression
, line
, filename
)
917 const char *expression
;
919 const char *filename
;
921 fprintf (stderr
, string
, expression
, line
, filename
);
928 /* Avoid warning from ranlib about empty object file. */
930 __bb_avoid_warning ()
933 #if defined (__sun__) && defined (__mc68000__)
944 extern int ___tcov_init
;
946 __bb_init_func (blocks
)
950 ___tcov_init_func ();
952 ___bb_link (blocks
->filename
, blocks
->counts
, blocks
->ncounts
);
961 typedef void (*vfp
)(void);
963 extern vfp __new_handler
;
964 extern void *malloc ();
980 typedef void (*vfp
)(void);
982 extern void *__builtin_new (size_t);
983 static void default_new_handler (void);
985 vfp __new_handler
= default_new_handler
;
988 __builtin_vec_new (p
, maxindex
, size
, ctor
)
992 void (*ctor
)(void *);
995 size_t nelts
= maxindex
+ 1;
999 p
= __builtin_new (nelts
* size
);
1003 for (i
= 0; i
< nelts
; i
++)
1013 __set_new_handler (handler
)
1018 prev_handler
= __new_handler
;
1019 if (handler
== 0) handler
= default_new_handler
;
1020 __new_handler
= handler
;
1021 return prev_handler
;
1025 set_new_handler (handler
)
1028 return __set_new_handler (handler
);
1031 #define MESSAGE "Virtual memory exceeded in `new'\n"
1034 default_new_handler ()
1036 /* don't use fprintf (stderr, ...) because it may need to call malloc. */
1037 /* This should really print the name of the program, but that is hard to
1038 do. We need a standard, clean way to get at the name. */
1039 write (2, MESSAGE
, sizeof (MESSAGE
));
1040 /* don't call exit () because that may call global destructors which
1041 may cause a loop. */
1046 #ifdef L_builtin_del
1047 typedef void (*vfp
)(void);
1050 __builtin_delete (ptr
)
1058 __builtin_vec_delete (ptr
, maxindex
, size
, dtor
, auto_delete_vec
, auto_delete
)
1062 void (*dtor
)(void *, int);
1066 size_t nelts
= maxindex
+ 1;
1069 ptr
+= nelts
* size
;
1071 for (i
= 0; i
< nelts
; i
++)
1074 (*dtor
) (ptr
, auto_delete
);
1077 if (auto_delete_vec
)
1078 __builtin_delete (p
);
1084 unsigned int __shtab
[] = {
1085 0x00000001, 0x00000002, 0x00000004, 0x00000008,
1086 0x00000010, 0x00000020, 0x00000040, 0x00000080,
1087 0x00000100, 0x00000200, 0x00000400, 0x00000800,
1088 0x00001000, 0x00002000, 0x00004000, 0x00008000,
1089 0x00010000, 0x00020000, 0x00040000, 0x00080000,
1090 0x00100000, 0x00200000, 0x00400000, 0x00800000,
1091 0x01000000, 0x02000000, 0x04000000, 0x08000000,
1092 0x10000000, 0x20000000, 0x40000000, 0x80000000
1096 #ifdef L_clear_cache
1097 /* Clear part of an instruction cache. */
1099 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1102 __clear_cache (beg
, end
)
1105 #ifdef INSN_CACHE_SIZE
1106 static char array
[INSN_CACHE_SIZE
+ INSN_CACHE_PLANE_SIZE
+ INSN_CACHE_LINE_WIDTH
];
1107 static int initialized
= 0;
1111 typedef (*function_ptr
) ();
1113 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1114 /* It's cheaper to clear the whole cache.
1115 Put in a series of jump instructions so that calling the beginning
1116 of the cache will clear the whole thing. */
1120 int ptr
= (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
1121 & -INSN_CACHE_LINE_WIDTH
);
1122 int end_ptr
= ptr
+ INSN_CACHE_SIZE
;
1124 while (ptr
< end_ptr
)
1126 *(INSTRUCTION_TYPE
*)ptr
1127 = JUMP_AHEAD_INSTRUCTION
+ INSN_CACHE_LINE_WIDTH
;
1128 ptr
+= INSN_CACHE_LINE_WIDTH
;
1130 *(INSTRUCTION_TYPE
*)(ptr
- INSN_CACHE_LINE_WIDTH
) = RETURN_INSTRUCTION
;
1135 /* Call the beginning of the sequence. */
1136 (((function_ptr
) (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
1137 & -INSN_CACHE_LINE_WIDTH
))
1140 #else /* Cache is large. */
1144 int ptr
= (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
1145 & -INSN_CACHE_LINE_WIDTH
);
1147 while (ptr
< (int) array
+ sizeof array
)
1149 *(INSTRUCTION_TYPE
*)ptr
= RETURN_INSTRUCTION
;
1150 ptr
+= INSN_CACHE_LINE_WIDTH
;
1156 /* Find the location in array that occupies the same cache line as BEG. */
1158 offset
= ((int) beg
& -INSN_CACHE_LINE_WIDTH
) & (INSN_CACHE_PLANE_SIZE
- 1);
1159 start_addr
= (((int) (array
+ INSN_CACHE_PLANE_SIZE
- 1)
1160 & -INSN_CACHE_PLANE_SIZE
)
1163 /* Compute the cache alignment of the place to stop clearing. */
1164 #if 0 /* This is not needed for gcc's purposes. */
1165 /* If the block to clear is bigger than a cache plane,
1166 we clear the entire cache, and OFFSET is already correct. */
1167 if (end
< beg
+ INSN_CACHE_PLANE_SIZE
)
1169 offset
= (((int) (end
+ INSN_CACHE_LINE_WIDTH
- 1)
1170 & -INSN_CACHE_LINE_WIDTH
)
1171 & (INSN_CACHE_PLANE_SIZE
- 1));
1173 #if INSN_CACHE_DEPTH > 1
1174 end_addr
= (start_addr
& -INSN_CACHE_PLANE_SIZE
) + offset
;
1175 if (end_addr
<= start_addr
)
1176 end_addr
+= INSN_CACHE_PLANE_SIZE
;
1178 for (plane
= 0; plane
< INSN_CACHE_DEPTH
; plane
++)
1180 int addr
= start_addr
+ plane
* INSN_CACHE_PLANE_SIZE
;
1181 int stop
= end_addr
+ plane
* INSN_CACHE_PLANE_SIZE
;
1183 while (addr
!= stop
)
1185 /* Call the return instruction at ADDR. */
1186 ((function_ptr
) addr
) ();
1188 addr
+= INSN_CACHE_LINE_WIDTH
;
1191 #else /* just one plane */
1194 /* Call the return instruction at START_ADDR. */
1195 ((function_ptr
) start_addr
) ();
1197 start_addr
+= INSN_CACHE_LINE_WIDTH
;
1199 while ((start_addr
% INSN_CACHE_SIZE
) != offset
);
1200 #endif /* just one plane */
1201 #endif /* Cache is large */
1202 #endif /* Cache exists */
1205 #endif /* L_clear_cache */
1209 /* Jump to a trampoline, loading the static chain address. */
1211 #ifdef TRANSFER_FROM_TRAMPOLINE
1212 TRANSFER_FROM_TRAMPOLINE
1217 /* Make stack executable so we can call trampolines on stack.
1218 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
1220 #include <sys/mman.h>
1221 #include <sys/vmparam.h>
1222 #include <machine/machparam.h>
1225 __enable_execute_stack ()
1228 static unsigned lowest
= USRSTACK
;
1229 unsigned current
= (unsigned) &fp
& -NBPG
;
1231 if (lowest
> current
)
1233 unsigned len
= lowest
- current
;
1234 mremap (current
, &len
, PROT_READ
| PROT_WRITE
| PROT_EXEC
, MAP_PRIVATE
);
1238 /* Clear instruction cache in case an old trampoline is in it. */
1241 #endif /* __convex__ */
1246 #include <sys/mman.h>
1247 #include <sys/types.h>
1248 #include <sys/param.h>
1249 #include <sys/vmmac.h>
1251 /* Modified from the convex -code above.
1252 mremap promises to clear the i-cache. */
1255 __enable_execute_stack ()
1258 if (mprotect (((unsigned int)&fp
/PAGSIZ
)*PAGSIZ
, PAGSIZ
,
1259 PROT_READ
|PROT_WRITE
|PROT_EXEC
))
1261 perror ("mprotect in __enable_execute_stack");
1266 #endif /* __pyr__ */
1267 #endif /* L_trampoline */
1271 #include "gbl-ctors.h"
1273 /* Run all the global destructors on exit from the program. */
1276 __do_global_dtors ()
1278 #ifdef DO_GLOBAL_DTORS_BODY
1279 DO_GLOBAL_DTORS_BODY
;
1281 unsigned nptrs
= (unsigned) __DTOR_LIST__
[0];
1284 /* Some systems place the number of pointers
1285 in the first word of the table.
1286 On other systems, that word is -1.
1287 In all cases, the table is null-terminated. */
1289 /* If the length is not recorded, count up to the null. */
1291 for (nptrs
= 0; __DTOR_LIST__
[nptrs
+ 1] != 0; nptrs
++);
1293 /* GNU LD format. */
1294 for (i
= nptrs
; i
>= 1; i
--)
1295 __DTOR_LIST__
[i
] ();
1299 #ifndef INIT_SECTION_ASM_OP
1300 /* Run all the global constructors on entry to the program. */
1303 #define ON_EXIT(a, b)
1305 /* Make sure the exit routine is pulled in to define the globals as
1306 bss symbols, just in case the linker does not automatically pull
1307 bss definitions from the library. */
1309 extern int _exit_dummy_decl
;
1310 int *_exit_dummy_ref
= &_exit_dummy_decl
;
1311 #endif /* ON_EXIT */
1314 __do_global_ctors ()
1316 DO_GLOBAL_CTORS_BODY
;
1317 ON_EXIT (__do_global_dtors
, 0);
1319 #endif /* no INIT_SECTION_ASM_OP */
1321 #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
1322 /* Subroutine called automatically by `main'.
1323 Compiling a global function named `main'
1324 produces an automatic call to this function at the beginning.
1326 For many systems, this routine calls __do_global_ctors.
1327 For systems which support a .init section we use the .init section
1328 to run __do_global_ctors, so we need not do anything here. */
1333 /* Support recursive calls to `main': run initializers just once. */
1334 static int initialized
= 0;
1338 __do_global_ctors ();
1341 #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
1343 #endif /* L__main */
1347 #include "gbl-ctors.h"
1349 /* Provide default definitions for the lists of constructors and
1350 destructors, so that we don't get linker errors. These symbols are
1351 intentionally bss symbols, so that gld and/or collect will provide
1352 the right values. */
1354 /* We declare the lists here with two elements each,
1355 so that they are valid empty lists if no other definition is loaded. */
1356 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
1357 func_ptr __CTOR_LIST__
[2];
1358 func_ptr __DTOR_LIST__
[2];
1359 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1363 /* If we have no known way of registering our own __do_global_dtors
1364 routine so that it will be invoked at program exit time, then we
1365 have to define our own exit routine which will get this to happen. */
1367 extern void __do_global_dtors ();
1368 extern void _cleanup ();
1369 extern void _exit ();
1375 __do_global_dtors ();
1385 int _exit_dummy_decl
= 0; /* prevent compiler & linker warnings */
1390 /* In a.out systems, we need to have these dummy constructor and destructor
1391 lists in the library.
1393 When using `collect', the first link will resolve __CTOR_LIST__
1394 and __DTOR_LIST__ to these symbols. We will then run "nm" on the
1395 result, build the correct __CTOR_LIST__ and __DTOR_LIST__, and relink.
1396 Since we don't do the second link if no constructors existed, these
1397 dummies must be fully functional empty lists.
1399 When using `gnu ld', these symbols will be used if there are no
1400 constructors. If there are constructors, the N_SETV symbol defined
1401 by the linker from the N_SETT's in input files will define __CTOR_LIST__
1402 and __DTOR_LIST__ rather than its being allocated as common storage
1403 by the definitions below.
1405 When using a linker that supports constructor and destructor segments,
1406 these definitions will not be used, since crtbegin.o and crtend.o
1407 (from crtstuff.c) will have already defined __CTOR_LIST__ and
1408 __DTOR_LIST__. The crt*.o files are passed directly to the linker
1409 on its command line, by gcc. */
1411 /* The list needs two elements: one is ignored (the old count); the
1412 second is the terminating zero. Since both values are zero, this
1413 declaration is not initialized, and it becomes `common'. */
1416 #include "gbl-ctors.h"
1417 func_ptr __CTOR_LIST__
[2];
1421 #include "gbl-ctors.h"
1422 func_ptr __DTOR_LIST__
[2];
This page took 0.102149 seconds and 5 git commands to generate.