]>
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
34 /* Don't use `fancy_abort' here even if config.h says to use it. */
39 /* Need to undef this because LONG_TYPE_SIZE may rely upon GCC's
40 internal `target_flags' variable. */
43 #define LONG_TYPE_SIZE (sizeof (long) * BITS_PER_UNIT)
46 #define SItype long int
49 /* long long ints are pairs of long ints in the order determined by
53 struct longlong
{long high
, low
;};
55 struct longlong
{long low
, high
;};
58 /* We need this union to unpack/pack longlongs, since we don't have
59 any arithmetic yet. Incoming long long parameters are stored
60 into the `ll' field, and the unpacked result is read from the struct
69 #if defined (L_udivmoddi4) || defined (L_muldi3)
73 #endif /* udiv or mul */
75 extern long long __fixunssfdi (float a
);
76 extern long long __fixunsdfdi (double a
);
78 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
79 #if defined (L_divdi3) || defined (L_moddi3)
92 w
.s
.high
= -uu
.s
.high
- ((unsigned long) w
.s
.low
> 0);
113 bm
= (sizeof (long) * BITS_PER_UNIT
) - b
;
117 w
.s
.high
= (unsigned long)uu
.s
.low
<< -bm
;
121 unsigned long carries
= (unsigned long)uu
.s
.low
>> bm
;
122 w
.s
.low
= (unsigned long)uu
.s
.low
<< b
;
123 w
.s
.high
= ((unsigned long)uu
.s
.high
<< b
) | carries
;
145 bm
= (sizeof (long) * BITS_PER_UNIT
) - b
;
149 w
.s
.low
= (unsigned long)uu
.s
.high
>> -bm
;
153 unsigned long carries
= (unsigned long)uu
.s
.high
<< bm
;
154 w
.s
.high
= (unsigned long)uu
.s
.high
>> b
;
155 w
.s
.low
= ((unsigned long)uu
.s
.low
>> b
) | carries
;
177 bm
= (sizeof (long) * BITS_PER_UNIT
) - b
;
181 w
.s
.high
= (unsigned long)uu
.s
.low
<< -bm
;
185 unsigned long carries
= (unsigned long)uu
.s
.low
>> bm
;
186 w
.s
.low
= (unsigned long)uu
.s
.low
<< b
;
187 w
.s
.high
= ((unsigned long)uu
.s
.high
<< b
) | carries
;
209 bm
= (sizeof (long) * BITS_PER_UNIT
) - b
;
212 /* w.s.high = 1..1 or 0..0 */
213 w
.s
.high
= uu
.s
.high
>> (sizeof (long) * BITS_PER_UNIT
- 1);
214 w
.s
.low
= uu
.s
.high
>> -bm
;
218 unsigned long carries
= (unsigned long)uu
.s
.high
<< bm
;
219 w
.s
.high
= uu
.s
.high
>> b
;
220 w
.s
.low
= ((unsigned long)uu
.s
.low
>> b
) | carries
;
238 w
.ll
= __umulsidi3 (uu
.s
.low
, vv
.s
.low
);
239 w
.s
.high
+= ((unsigned long) uu
.s
.low
* (unsigned long) vv
.s
.high
240 + (unsigned long) uu
.s
.high
* (unsigned long) vv
.s
.low
);
247 static const unsigned char __clz_tab
[] =
249 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,
250 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,
251 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,
252 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,
253 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,
254 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,
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,
260 __udivmoddi4 (n
, d
, rp
)
261 unsigned long long n
, d
;
262 unsigned long long int *rp
;
267 unsigned long d0
, d1
, n0
, n1
, n2
;
268 unsigned long q0
, q1
;
279 #if !UDIV_NEEDS_NORMALIZATION
286 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
289 /* Remainder in n0. */
296 d0
= 1 / d0
; /* Divide intentionally by zero. */
298 udiv_qrnnd (q1
, n1
, 0, n1
, d0
);
299 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
301 /* Remainder in n0. */
312 #else /* UDIV_NEEDS_NORMALIZATION */
320 count_leading_zeros (bm
, d0
);
324 /* Normalize, i.e. make the most significant bit of the
328 n1
= (n1
<< bm
) | (n0
>> (LONG_TYPE_SIZE
- bm
));
332 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
335 /* Remainder in n0 >> bm. */
342 d0
= 1 / d0
; /* Divide intentionally by zero. */
344 count_leading_zeros (bm
, d0
);
348 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
349 conclude (the most significant bit of n1 is set) /\ (the
350 leading quotient digit q1 = 1).
352 This special case is necessary, not an optimization.
353 (Shifts counts of LONG_TYPE_SIZE are undefined.) */
362 b
= LONG_TYPE_SIZE
- bm
;
366 n1
= (n1
<< bm
) | (n0
>> b
);
369 udiv_qrnnd (q1
, n1
, n2
, n1
, d0
);
374 udiv_qrnnd (q0
, n0
, n1
, n0
, d0
);
376 /* Remainder in n0 >> bm. */
386 #endif /* UDIV_NEEDS_NORMALIZATION */
397 /* Remainder in n1n0. */
409 count_leading_zeros (bm
, d1
);
412 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
413 conclude (the most significant bit of n1 is set) /\ (the
414 quotient digit q0 = 0 or 1).
416 This special case is necessary, not an optimization. */
418 /* The condition on the next line takes advantage of that
419 n1 >= d1 (true due to program flow). */
420 if (n1
> d1
|| n0
>= d0
)
423 sub_ddmmss (n1
, n0
, n1
, n0
, d1
, d0
);
439 unsigned long m1
, m0
;
442 b
= LONG_TYPE_SIZE
- bm
;
444 d1
= (d1
<< bm
) | (d0
>> b
);
447 n1
= (n1
<< bm
) | (n0
>> b
);
450 udiv_qrnnd (q0
, n1
, n2
, n1
, d1
);
451 umul_ppmm (m1
, m0
, q0
, d0
);
453 if (m1
> n1
|| (m1
== n1
&& m0
> n0
))
456 sub_ddmmss (m1
, m0
, m1
, m0
, d1
, d0
);
461 /* Remainder in (n1n0 - m1m0) >> bm. */
464 sub_ddmmss (n1
, n0
, n1
, n0
, m1
, m0
);
465 rr
.s
.low
= (n1
<< b
) | (n0
>> bm
);
466 rr
.s
.high
= n1
>> bm
;
480 unsigned long long __udivmoddi4 ();
494 uu
.ll
= __negdi2 (uu
.ll
);
497 vv
.ll
= __negdi2 (vv
.ll
);
499 w
= __udivmoddi4 (uu
.ll
, vv
.ll
, (unsigned long long *) 0);
508 unsigned long long __udivmoddi4 ();
522 uu
.ll
= __negdi2 (uu
.ll
);
524 vv
.ll
= __negdi2 (vv
.ll
);
526 (void) __udivmoddi4 (uu
.ll
, vv
.ll
, &w
);
535 unsigned long long __udivmoddi4 ();
538 unsigned long long u
, v
;
542 (void) __udivmoddi4 (u
, v
, &w
);
549 unsigned long long __udivmoddi4 ();
552 unsigned long long n
, d
;
554 return __udivmoddi4 (n
, d
, (unsigned long long *) 0);
565 au
.ll
= a
, bu
.ll
= b
;
567 if (au
.s
.high
< bu
.s
.high
)
569 else if (au
.s
.high
> bu
.s
.high
)
571 if ((unsigned long) au
.s
.low
< (unsigned long) bu
.s
.low
)
573 else if ((unsigned long) au
.s
.low
> (unsigned long) bu
.s
.low
)
586 au
.ll
= a
, bu
.ll
= b
;
588 if ((unsigned long) au
.s
.high
< (unsigned long) bu
.s
.high
)
590 else if ((unsigned long) au
.s
.high
> (unsigned long) bu
.s
.high
)
592 if ((unsigned long) au
.s
.low
< (unsigned long) bu
.s
.low
)
594 else if ((unsigned long) au
.s
.low
> (unsigned long) bu
.s
.low
)
601 #define WORD_SIZE (sizeof (long) * BITS_PER_UNIT)
602 #define HIGH_WORD_COEFF (((long long) 1) << WORD_SIZE)
609 unsigned long long v
;
614 /* Compute high word of result, as a flonum. */
615 b
= (a
/ HIGH_WORD_COEFF
);
616 /* Convert that to fixed (but not to long long!),
617 and shift it into the high word. */
618 v
= (unsigned long int) b
;
620 /* Remove high part from the double, leaving the low part as flonum. */
622 /* Convert that to fixed (but not to long long!) and add it in.
623 Sometimes A comes out negative. This is significant, since
624 A has more bits than a long int does. */
626 v
-= (unsigned long int) (- a
);
628 v
+= (unsigned long int) a
;
639 return - __fixunsdfdi (-a
);
640 return __fixunsdfdi (a
);
645 #define WORD_SIZE (sizeof (long) * BITS_PER_UNIT)
646 #define HIGH_WORD_COEFF (((long long) 1) << WORD_SIZE)
649 __fixunssfdi (float original_a
)
651 /* Convert the float to a double, because that is surely not going
652 to lose any bits. Some day someone else can write a faster version
653 that avoids converting to double, and verify it really works right. */
654 double a
= original_a
;
656 unsigned long long v
;
661 /* Compute high word of result, as a flonum. */
662 b
= (a
/ HIGH_WORD_COEFF
);
663 /* Convert that to fixed (but not to long long!),
664 and shift it into the high word. */
665 v
= (unsigned long int) b
;
667 /* Remove high part from the double, leaving the low part as flonum. */
669 /* Convert that to fixed (but not to long long!) and add it in.
670 Sometimes A comes out negative. This is significant, since
671 A has more bits than a long int does. */
673 v
-= (unsigned long int) (- a
);
675 v
+= (unsigned long int) a
;
685 return - __fixunssfdi (-a
);
686 return __fixunssfdi (a
);
691 #define WORD_SIZE (sizeof (long) * BITS_PER_UNIT)
692 #define HIGH_HALFWORD_COEFF (((long long) 1) << (WORD_SIZE / 2))
693 #define HIGH_WORD_COEFF (((long long) 1) << WORD_SIZE)
705 d
= (unsigned int) (u
>> WORD_SIZE
);
706 d
*= HIGH_HALFWORD_COEFF
;
707 d
*= HIGH_HALFWORD_COEFF
;
708 d
+= (unsigned int) (u
& (HIGH_WORD_COEFF
- 1));
710 return (negate
? -d
: d
);
715 #define WORD_SIZE (sizeof (long) * BITS_PER_UNIT)
716 #define HIGH_HALFWORD_COEFF (((long long) 1) << (WORD_SIZE / 2))
717 #define HIGH_WORD_COEFF (((long long) 1) << WORD_SIZE)
729 f
= (unsigned int) (u
>> WORD_SIZE
);
730 f
*= HIGH_HALFWORD_COEFF
;
731 f
*= HIGH_HALFWORD_COEFF
;
732 f
+= (unsigned int) (u
& (HIGH_WORD_COEFF
- 1));
734 return (negate
? -f
: f
);
745 if (a
>= - (double) LONG_MIN
)
746 return (SItype
) (a
+ LONG_MIN
) - LONG_MIN
;
755 __fixunssfsi (float a
)
757 if (a
>= - (float) LONG_MIN
)
758 return (SItype
) (a
+ LONG_MIN
) - LONG_MIN
;
769 asm (".globl __builtin_saveregs");
770 asm ("__builtin_saveregs:");
771 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
772 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
773 area and also for a new va_list
775 /* Save all argument registers in the arg reg save area. The
776 arg reg save area must have the following layout (according
788 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
789 asm (" fst.q %f12,16(%sp)");
791 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
792 asm (" st.l %r17,36(%sp)");
793 asm (" st.l %r18,40(%sp)");
794 asm (" st.l %r19,44(%sp)");
795 asm (" st.l %r20,48(%sp)");
796 asm (" st.l %r21,52(%sp)");
797 asm (" st.l %r22,56(%sp)");
798 asm (" st.l %r23,60(%sp)");
799 asm (" st.l %r24,64(%sp)");
800 asm (" st.l %r25,68(%sp)");
801 asm (" st.l %r26,72(%sp)");
802 asm (" st.l %r27,76(%sp)");
804 asm (" adds 80,%sp,%r16"); /* compute the address of the new
805 va_list structure. Put in into
806 r16 so that it will be returned
809 /* Initialize all fields of the new va_list structure. This
810 structure looks like:
813 unsigned long ireg_used;
814 unsigned long freg_used;
820 asm (" st.l %r0, 0(%r16)"); /* nfixed */
821 asm (" st.l %r0, 4(%r16)"); /* nfloating */
822 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
823 asm (" bri %r1"); /* delayed return */
824 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
830 asm (".globl ___builtin_saveregs");
831 asm ("___builtin_saveregs:");
833 asm (" andnot 0x0f,sp,sp");
834 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
836 /* Fill in the __va_struct. */
837 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
838 asm (" st.l r17, 4(sp)"); /* int fixed[12] */
839 asm (" st.l r18, 8(sp)");
840 asm (" st.l r19,12(sp)");
841 asm (" st.l r20,16(sp)");
842 asm (" st.l r21,20(sp)");
843 asm (" st.l r22,24(sp)");
844 asm (" st.l r23,28(sp)");
845 asm (" st.l r24,32(sp)");
846 asm (" st.l r25,36(sp)");
847 asm (" st.l r26,40(sp)");
848 asm (" st.l r27,44(sp)");
850 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
851 asm (" fst.q f12,64(sp)"); /* int floating[8] */
853 /* Fill in the __va_ctl. */
854 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
855 asm (" st.l r28,84(sp)"); /* pointer to more args */
856 asm (" st.l r0, 88(sp)"); /* nfixed */
857 asm (" st.l r0, 92(sp)"); /* nfloating */
859 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
862 /* recover stack and pass address to start
864 #endif /* not SVR4 */
865 #else /* not __i860__ */
867 asm (".global ___builtin_saveregs");
868 asm ("___builtin_saveregs:");
869 asm ("st %i0,[%fp+68]");
870 asm ("st %i1,[%fp+72]");
871 asm ("st %i2,[%fp+76]");
872 asm ("st %i3,[%fp+80]");
873 asm ("st %i4,[%fp+84]");
875 asm ("st %i5,[%fp+88]");
876 #else /* not __sparc__ */
877 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
880 asm (" .ent __builtin_saveregs");
881 asm (" .globl __builtin_saveregs");
882 asm ("__builtin_saveregs:");
883 asm (" sw $4,0($30)");
884 asm (" sw $5,4($30)");
885 asm (" sw $6,8($30)");
886 asm (" sw $7,12($30)");
888 asm (" .end __builtin_saveregs");
889 #else /* not __mips__, etc. */
890 __builtin_saveregs ()
894 #endif /* not __mips__ */
895 #endif /* not __sparc__ */
896 #endif /* not __i860__ */
900 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
902 /* This is used by the `assert' macro. */
904 __eprintf (string
, expression
, line
, filename
)
910 fprintf (stderr
, string
, expression
, line
, filename
);
917 /* Avoid warning from ranlib about empty object file. */
919 __bb_avoid_warning ()
922 #if defined (__sun__) && defined (__mc68000__)
933 extern int ___tcov_init
;
935 __bb_init_func (blocks
)
939 ___tcov_init_func ();
941 ___bb_link (blocks
->filename
, blocks
->counts
, blocks
->ncounts
);
950 typedef void (*vfp
)(void);
952 extern vfp __new_handler
;
960 p
= (void *) malloc (sz
);
968 typedef void (*vfp
)(void);
970 static void default_new_handler ();
972 vfp __new_handler
= default_new_handler
;
975 __builtin_vec_new (p
, maxindex
, size
, ctor
)
978 void (*ctor
)(void *);
980 int i
, nelts
= maxindex
+ 1;
984 p
= (void *)__builtin_new (nelts
* size
);
988 for (i
= 0; i
< nelts
; i
++)
998 __set_new_handler (handler
)
1003 prev_handler
= __new_handler
;
1004 if (handler
== 0) handler
= default_new_handler
;
1005 __new_handler
= handler
;
1006 return prev_handler
;
1010 set_new_handler (handler
)
1013 return __set_new_handler (handler
);
1017 default_new_handler ()
1019 /* don't use fprintf (stderr, ...) because it may need to call malloc. */
1020 /* This should really print the name of the program, but that is hard to
1021 do. We need a standard, clean way to get at the name. */
1022 write (2, "Virtual memory exceeded in `new'\n", 33);
1023 /* don't call exit () because that may call global destructors which
1024 may cause a loop. */
1029 #ifdef L_builtin_del
1030 typedef void (*vfp
)(void);
1033 __builtin_delete (ptr
)
1041 __builtin_vec_delete (ptr
, maxindex
, size
, dtor
, auto_delete_vec
, auto_delete
)
1047 int i
, nelts
= maxindex
+ 1;
1050 ptr
+= nelts
* size
;
1052 for (i
= 0; i
< nelts
; i
++)
1055 (*dtor
) (ptr
, auto_delete
);
1058 if (auto_delete_vec
)
1059 __builtin_delete (p
);
1065 unsigned int __shtab
[] = {
1066 0x00000001, 0x00000002, 0x00000004, 0x00000008,
1067 0x00000010, 0x00000020, 0x00000040, 0x00000080,
1068 0x00000100, 0x00000200, 0x00000400, 0x00000800,
1069 0x00001000, 0x00002000, 0x00004000, 0x00008000,
1070 0x00010000, 0x00020000, 0x00040000, 0x00080000,
1071 0x00100000, 0x00200000, 0x00400000, 0x00800000,
1072 0x01000000, 0x02000000, 0x04000000, 0x08000000,
1073 0x10000000, 0x20000000, 0x40000000, 0x80000000
1077 #ifdef L_clear_cache
1078 /* Clear part of an instruction cache. */
1080 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1083 __clear_cache (beg
, end
)
1086 #ifdef INSN_CACHE_SIZE
1087 static char array
[INSN_CACHE_SIZE
+ INSN_CACHE_PLANE_SIZE
+ INSN_CACHE_LINE_WIDTH
];
1088 static int initialized
= 0;
1090 unsigned int start_addr
, end_addr
;
1091 typedef (*function_ptr
) ();
1093 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1094 /* It's cheaper to clear the whole cache.
1095 Put in a series of jump instructions so that calling the beginning
1096 of the cache will clear the whole thing. */
1100 int ptr
= (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
1101 & -INSN_CACHE_LINE_WIDTH
);
1102 int end_ptr
= ptr
+ INSN_CACHE_SIZE
;
1104 while (ptr
< end_ptr
)
1106 *(INSTRUCTION_TYPE
*)ptr
1107 = JUMP_AHEAD_INSTRUCTION
+ INSN_CACHE_LINE_WIDTH
;
1108 ptr
+= INSN_CACHE_LINE_WIDTH
;
1110 *(INSTRUCTION_TYPE
*)(ptr
- INSN_CACHE_LINE_WIDTH
) = RETURN_INSTRUCTION
;
1115 /* Call the beginning of the sequence. */
1116 (((function_ptr
) (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
1117 & -INSN_CACHE_LINE_WIDTH
))
1120 #else /* Cache is large. */
1124 int ptr
= (((int) array
+ INSN_CACHE_LINE_WIDTH
- 1)
1125 & -INSN_CACHE_LINE_WIDTH
);
1127 while (ptr
< (int) array
+ sizeof array
)
1129 *(INSTRUCTION_TYPE
*)ptr
= RETURN_INSTRUCTION
;
1130 ptr
+= INSN_CACHE_LINE_WIDTH
;
1136 /* Find the location in array that occupies the same cache line as BEG. */
1138 offset
= ((int) beg
& -INSN_CACHE_LINE_WIDTH
) & (INSN_CACHE_PLANE_SIZE
- 1);
1139 start_addr
= (((int) (array
+ INSN_CACHE_PLANE_SIZE
- 1)
1140 & -INSN_CACHE_PLANE_SIZE
)
1143 /* Compute the cache alignment of the place to stop clearing. */
1144 #if 0 /* This is not needed for gcc's purposes. */
1145 /* If the block to clear is bigger than a cache plane,
1146 we clear the entire cache, and OFFSET is already correct. */
1147 if (end
< beg
+ INSN_CACHE_PLANE_SIZE
)
1149 offset
= (((int) (end
+ INSN_CACHE_LINE_WIDTH
- 1)
1150 & -INSN_CACHE_LINE_WIDTH
)
1151 & (INSN_CACHE_PLANE_SIZE
- 1));
1153 #if INSN_CACHE_DEPTH > 1
1154 end_addr
= (start_addr
& -INSN_CACHE_PLANE_SIZE
) + offset
;
1155 if (end_addr
<= start_addr
)
1156 end_addr
+= INSN_CACHE_PLANE_SIZE
;
1158 for (plane
= 0; plane
< INSN_CACHE_DEPTH
; plane
++)
1160 int addr
= start_addr
+ plane
* INSN_CACHE_PLANE_SIZE
;
1161 int stop
= end_addr
+ plane
* INSN_CACHE_PLANE_SIZE
;
1163 while (addr
!= stop
)
1165 /* Call the return instruction at ADDR. */
1166 ((function_ptr
) addr
) ();
1168 addr
+= INSN_CACHE_LINE_WIDTH
;
1171 #else /* just one plane */
1174 /* Call the return instruction at START_ADDR. */
1175 ((function_ptr
) start_addr
) ();
1177 start_addr
+= INSN_CACHE_LINE_WIDTH
;
1179 while ((start_addr
% INSN_CACHE_SIZE
) != offset
);
1180 #endif /* just one plane */
1181 #endif /* Cache is large */
1182 #endif /* Cache exists */
1185 #endif /* L_clear_cache */
1189 /* Jump to a trampoline, loading the static chain address. */
1191 #ifdef TRANSFER_FROM_TRAMPOLINE
1192 TRANSFER_FROM_TRAMPOLINE
1197 /* Make stack executable so we can call trampolines on stack.
1198 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
1200 #include <sys/mman.h>
1201 #include <sys/vmparam.h>
1202 #include <machine/machparam.h>
1205 __enable_execute_stack ()
1208 static unsigned lowest
= USRSTACK
;
1209 unsigned current
= (unsigned) &fp
& -NBPG
;
1211 if (lowest
> current
)
1213 unsigned len
= lowest
- current
;
1214 mremap (current
, &len
, PROT_READ
| PROT_WRITE
| PROT_EXEC
, MAP_PRIVATE
);
1218 /* Clear instruction cache in case an old trampoline is in it. */
1221 #endif /* __convex__ */
1222 #endif /* L_trampoline */
1226 #include "gbl-ctors.h"
1228 /* Run all the global destructors on exit from the program. */
1231 __do_global_dtors ()
1233 #ifdef DO_GLOBAL_DTORS_BODY
1234 DO_GLOBAL_DTORS_BODY
;
1236 int nptrs
= *(int *)__DTOR_LIST__
;
1239 /* Some systems place the number of pointers
1240 in the first word of the table.
1241 On other systems, that word is -1.
1242 In all cases, the table is null-terminated. */
1244 /* If the length is not recorded, count up to the null. */
1246 for (nptrs
= 0; __DTOR_LIST__
[nptrs
+ 1] != 0; nptrs
++);
1248 /* GNU LD format. */
1249 for (i
= nptrs
; i
>= 1; i
--)
1250 __DTOR_LIST__
[i
] ();
1254 #ifndef INIT_SECTION_ASM_OP
1255 /* Run all the global constructors on entry to the program. */
1257 #ifndef ON_EXIT /* DO_GLOBAL_CTORS_BODY uses ON_EXIT */
1258 #define ON_EXIT(a, b)
1260 /* Make sure the exit routine is pulled in to define the globals as
1261 bss symbols, just in case the linker does not automatically pull
1262 bss definitions from the library. */
1264 extern int _exit_dummy_decl
;
1265 int *_exit_dummy_ref
= &_exit_dummy_decl
;
1266 #endif /* ON_EXIT */
1269 __do_global_ctors ()
1271 DO_GLOBAL_CTORS_BODY
;
1274 /* Subroutine called automatically by `main'.
1275 Compiling a global function named `main'
1276 produces an automatic call to this function at the beginning.
1278 For many systems, this routine calls __do_global_ctors.
1279 For systems which support a .init section we use the .init section
1280 to run __do_global_ctors, so we need not do anything here. */
1285 /* Support recursive calls to `main': run initializers just once. */
1286 static initialized
= 0;
1290 __do_global_ctors ();
1293 #endif /* no INIT_SECTION_ASM_OP */
1295 #endif /* L__main */
1299 #include "gbl-ctors.h"
1301 /* Provide default definitions for the lists of constructors and
1302 destructors, so that we don't get linker errors. These symbols are
1303 intentionally bss symbols, so that gld and/or collect will provide
1304 the right values. */
1306 /* We declare the lists here with two elements each,
1307 so that they are valid empty lists if no other definition is loaded. */
1308 #ifndef INIT_SECTION_ASM_OP
1309 func_ptr __CTOR_LIST__
[2];
1310 func_ptr __DTOR_LIST__
[2];
1311 #endif /* INIT_SECTION_ASM_OP */
1315 /* If we have no known way of registering our own __do_global_dtors
1316 routine so that it will be invoked at program exit time, then we
1317 have to define our own exit routine which will get this to happen. */
1319 extern void __do_global_dtors ();
1320 extern void _cleanup ();
1321 extern void _exit ();
1327 __do_global_dtors ();
1337 int _exit_dummy_decl
= 0; /* prevent compiler & linker warnings */
1342 /* In a.out systems, we need to have these dummy constructor and destructor
1343 lists in the library.
1345 When using `collect', the first link will resolve __CTOR_LIST__
1346 and __DTOR_LIST__ to these symbols. We will then run "nm" on the
1347 result, build the correct __CTOR_LIST__ and __DTOR_LIST__, and relink.
1348 Since we don't do the second link if no constructors existed, these
1349 dummies must be fully functional empty lists.
1351 When using `gnu ld', these symbols will be used if there are no
1352 constructors. If there are constructors, the N_SETV symbol defined
1353 by the linker from the N_SETT's in input files will define __CTOR_LIST__
1354 and __DTOR_LIST__ rather than its being allocated as common storage
1355 by the definitions below.
1357 When using a linker that supports constructor and destructor segments,
1358 these definitions will not be used, since crtbegin.o and crtend.o
1359 (from crtstuff.c) will have already defined __CTOR_LIST__ and
1360 __DTOR_LIST__. The crt*.o files are passed directly to the linker
1361 on its command line, by gcc. */
1363 /* The list needs two elements: one is ignored (the old count); the
1364 second is the terminating zero. Since both values are zero, this
1365 declaration is not initialized, and it becomes `common'. */
1368 #include "gbl-ctors.h"
1369 func_ptr __CTOR_LIST__
[2];
1373 #include "gbl-ctors.h"
1374 func_ptr __DTOR_LIST__
[2];
This page took 0.101039 seconds and 6 git commands to generate.