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;
970 extern void *malloc ();
980 typedef void (*vfp)(void);
982 extern void *__builtin_new ();
983 static void default_new_handler ();
985 vfp __new_handler = default_new_handler;
988 __builtin_vec_new (p, maxindex, size, ctor)
991 void (*ctor)(void *);
993 int i, nelts = maxindex + 1;
997 p = __builtin_new (nelts * size);
1001 for (i = 0; i < nelts; i++)
1011 __set_new_handler (handler)
1016 prev_handler = __new_handler;
1017 if (handler == 0) handler = default_new_handler;
1018 __new_handler = handler;
1019 return prev_handler;
1023 set_new_handler (handler)
1026 return __set_new_handler (handler);
1029 #define MESSAGE "Virtual memory exceeded in `new'\n"
1032 default_new_handler ()
1034 /* don't use fprintf (stderr, ...) because it may need to call malloc. */
1035 /* This should really print the name of the program, but that is hard to
1036 do. We need a standard, clean way to get at the name. */
1037 write (2, MESSAGE, sizeof (MESSAGE));
1038 /* don't call exit () because that may call global destructors which
1039 may cause a loop. */
1044 #ifdef L_builtin_del
1045 typedef void (*vfp)(void);
1048 __builtin_delete (ptr)
1056 __builtin_vec_delete (ptr, maxindex, size, dtor, auto_delete_vec, auto_delete)
1062 int i, nelts = maxindex + 1;
1065 ptr += nelts * size;
1067 for (i = 0; i < nelts; i++)
1070 (*dtor) (ptr, auto_delete);
1073 if (auto_delete_vec)
1074 __builtin_delete (p);
1080 unsigned int __shtab[] = {
1081 0x00000001, 0x00000002, 0x00000004, 0x00000008,
1082 0x00000010, 0x00000020, 0x00000040, 0x00000080,
1083 0x00000100, 0x00000200, 0x00000400, 0x00000800,
1084 0x00001000, 0x00002000, 0x00004000, 0x00008000,
1085 0x00010000, 0x00020000, 0x00040000, 0x00080000,
1086 0x00100000, 0x00200000, 0x00400000, 0x00800000,
1087 0x01000000, 0x02000000, 0x04000000, 0x08000000,
1088 0x10000000, 0x20000000, 0x40000000, 0x80000000
1092 #ifdef L_clear_cache
1093 /* Clear part of an instruction cache. */
1095 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1098 __clear_cache (beg, end)
1101 #ifdef INSN_CACHE_SIZE
1102 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1103 static int initialized = 0;
1105 unsigned int start_addr, end_addr;
1106 typedef (*function_ptr) ();
1108 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1109 /* It's cheaper to clear the whole cache.
1110 Put in a series of jump instructions so that calling the beginning
1111 of the cache will clear the whole thing. */
1115 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1116 & -INSN_CACHE_LINE_WIDTH);
1117 int end_ptr = ptr + INSN_CACHE_SIZE;
1119 while (ptr < end_ptr)
1121 *(INSTRUCTION_TYPE *)ptr
1122 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1123 ptr += INSN_CACHE_LINE_WIDTH;
1125 *(INSTRUCTION_TYPE *)(ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1130 /* Call the beginning of the sequence. */
1131 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1132 & -INSN_CACHE_LINE_WIDTH))
1135 #else /* Cache is large. */
1139 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1140 & -INSN_CACHE_LINE_WIDTH);
1142 while (ptr < (int) array + sizeof array)
1144 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1145 ptr += INSN_CACHE_LINE_WIDTH;
1151 /* Find the location in array that occupies the same cache line as BEG. */
1153 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1154 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1155 & -INSN_CACHE_PLANE_SIZE)
1158 /* Compute the cache alignment of the place to stop clearing. */
1159 #if 0 /* This is not needed for gcc's purposes. */
1160 /* If the block to clear is bigger than a cache plane,
1161 we clear the entire cache, and OFFSET is already correct. */
1162 if (end < beg + INSN_CACHE_PLANE_SIZE)
1164 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1165 & -INSN_CACHE_LINE_WIDTH)
1166 & (INSN_CACHE_PLANE_SIZE - 1));
1168 #if INSN_CACHE_DEPTH > 1
1169 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1170 if (end_addr <= start_addr)
1171 end_addr += INSN_CACHE_PLANE_SIZE;
1173 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1175 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1176 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1178 while (addr != stop)
1180 /* Call the return instruction at ADDR. */
1181 ((function_ptr) addr) ();
1183 addr += INSN_CACHE_LINE_WIDTH;
1186 #else /* just one plane */
1189 /* Call the return instruction at START_ADDR. */
1190 ((function_ptr) start_addr) ();
1192 start_addr += INSN_CACHE_LINE_WIDTH;
1194 while ((start_addr % INSN_CACHE_SIZE) != offset);
1195 #endif /* just one plane */
1196 #endif /* Cache is large */
1197 #endif /* Cache exists */
1200 #endif /* L_clear_cache */
1204 /* Jump to a trampoline, loading the static chain address. */
1206 #ifdef TRANSFER_FROM_TRAMPOLINE
1207 TRANSFER_FROM_TRAMPOLINE
1212 /* Make stack executable so we can call trampolines on stack.
1213 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
1215 #include <sys/mman.h>
1216 #include <sys/vmparam.h>
1217 #include <machine/machparam.h>
1220 __enable_execute_stack ()
1223 static unsigned lowest = USRSTACK;
1224 unsigned current = (unsigned) &fp & -NBPG;
1226 if (lowest > current)
1228 unsigned len = lowest - current;
1229 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
1233 /* Clear instruction cache in case an old trampoline is in it. */
1236 #endif /* __convex__ */
1241 #include <sys/mman.h>
1242 #include <sys/types.h>
1243 #include <sys/param.h>
1244 #include <sys/vmmac.h>
1246 /* Modified from the convex -code above.
1247 mremap promises to clear the i-cache. */
1250 __enable_execute_stack ()
1253 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
1254 PROT_READ|PROT_WRITE|PROT_EXEC))
1256 perror ("mprotect in __enable_execute_stack");
1261 #endif /* __pyr__ */
1262 #endif /* L_trampoline */
1266 #include "gbl-ctors.h"
1268 /* Run all the global destructors on exit from the program. */
1271 __do_global_dtors ()
1273 #ifdef DO_GLOBAL_DTORS_BODY
1274 DO_GLOBAL_DTORS_BODY;
1276 int nptrs = *(int *)__DTOR_LIST__;
1279 /* Some systems place the number of pointers
1280 in the first word of the table.
1281 On other systems, that word is -1.
1282 In all cases, the table is null-terminated. */
1284 /* If the length is not recorded, count up to the null. */
1286 for (nptrs = 0; __DTOR_LIST__[nptrs + 1] != 0; nptrs++);
1288 /* GNU LD format. */
1289 for (i = nptrs; i >= 1; i--)
1290 __DTOR_LIST__[i] ();
1294 #ifndef INIT_SECTION_ASM_OP
1295 /* Run all the global constructors on entry to the program. */
1298 #define ON_EXIT(a, b)
1300 /* Make sure the exit routine is pulled in to define the globals as
1301 bss symbols, just in case the linker does not automatically pull
1302 bss definitions from the library. */
1304 extern int _exit_dummy_decl;
1305 int *_exit_dummy_ref = &_exit_dummy_decl;
1306 #endif /* ON_EXIT */
1309 __do_global_ctors ()
1311 DO_GLOBAL_CTORS_BODY;
1312 ON_EXIT (__do_global_dtors, 0);
1314 #endif /* no INIT_SECTION_ASM_OP */
1316 #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
1317 /* Subroutine called automatically by `main'.
1318 Compiling a global function named `main'
1319 produces an automatic call to this function at the beginning.
1321 For many systems, this routine calls __do_global_ctors.
1322 For systems which support a .init section we use the .init section
1323 to run __do_global_ctors, so we need not do anything here. */
1328 /* Support recursive calls to `main': run initializers just once. */
1329 static initialized = 0;
1333 __do_global_ctors ();
1336 #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
1338 #endif /* L__main */
1342 #include "gbl-ctors.h"
1344 /* Provide default definitions for the lists of constructors and
1345 destructors, so that we don't get linker errors. These symbols are
1346 intentionally bss symbols, so that gld and/or collect will provide
1347 the right values. */
1349 /* We declare the lists here with two elements each,
1350 so that they are valid empty lists if no other definition is loaded. */
1351 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
1352 func_ptr __CTOR_LIST__[2];
1353 func_ptr __DTOR_LIST__[2];
1354 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1358 /* If we have no known way of registering our own __do_global_dtors
1359 routine so that it will be invoked at program exit time, then we
1360 have to define our own exit routine which will get this to happen. */
1362 extern void __do_global_dtors ();
1363 extern void _cleanup ();
1364 extern void _exit ();
1370 __do_global_dtors ();
1380 int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */
1385 /* In a.out systems, we need to have these dummy constructor and destructor
1386 lists in the library.
1388 When using `collect', the first link will resolve __CTOR_LIST__
1389 and __DTOR_LIST__ to these symbols. We will then run "nm" on the
1390 result, build the correct __CTOR_LIST__ and __DTOR_LIST__, and relink.
1391 Since we don't do the second link if no constructors existed, these
1392 dummies must be fully functional empty lists.
1394 When using `gnu ld', these symbols will be used if there are no
1395 constructors. If there are constructors, the N_SETV symbol defined
1396 by the linker from the N_SETT's in input files will define __CTOR_LIST__
1397 and __DTOR_LIST__ rather than its being allocated as common storage
1398 by the definitions below.
1400 When using a linker that supports constructor and destructor segments,
1401 these definitions will not be used, since crtbegin.o and crtend.o
1402 (from crtstuff.c) will have already defined __CTOR_LIST__ and
1403 __DTOR_LIST__. The crt*.o files are passed directly to the linker
1404 on its command line, by gcc. */
1406 /* The list needs two elements: one is ignored (the old count); the
1407 second is the terminating zero. Since both values are zero, this
1408 declaration is not initialized, and it becomes `common'. */
1411 #include "gbl-ctors.h"
1412 func_ptr __CTOR_LIST__[2];
1416 #include "gbl-ctors.h"
1417 func_ptr __DTOR_LIST__[2];