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 #ifdef NO_UNDERSCORES
870 asm (".global __builtin_saveregs");
871 asm ("__builtin_saveregs:");
873 asm (".global ___builtin_saveregs");
874 asm ("___builtin_saveregs:");
876 #ifdef NEED_PROC_COMMAND
879 asm ("st %i0,[%fp+68]");
880 asm ("st %i1,[%fp+72]");
881 asm ("st %i2,[%fp+76]");
882 asm ("st %i3,[%fp+80]");
883 asm ("st %i4,[%fp+84]");
885 asm ("st %i5,[%fp+88]");
886 #ifdef NEED_TYPE_COMMAND
887 asm (".type __builtin_saveregs,#function");
888 asm (".size __builtin_saveregs,.-__builtin_saveregs");
890 #else /* not __sparc__ */
891 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
894 asm (" .ent __builtin_saveregs");
895 asm (" .globl __builtin_saveregs");
896 asm ("__builtin_saveregs:");
897 asm (" sw $4,0($30)");
898 asm (" sw $5,4($30)");
899 asm (" sw $6,8($30)");
900 asm (" sw $7,12($30)");
902 asm (" .end __builtin_saveregs");
903 #else /* not __mips__, etc. */
904 __builtin_saveregs ()
908 #endif /* not __mips__ */
909 #endif /* not __sparc__ */
910 #endif /* not __i860__ */
914 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
916 /* This is used by the `assert' macro. */
918 __eprintf (string, expression, line, filename)
920 const char *expression;
922 const char *filename;
924 fprintf (stderr, string, expression, line, filename);
931 /* Avoid warning from ranlib about empty object file. */
933 __bb_avoid_warning ()
936 #if defined (__sun__) && defined (__mc68000__)
947 extern int ___tcov_init;
949 __bb_init_func (blocks)
953 ___tcov_init_func ();
955 ___bb_link (blocks->filename, blocks->counts, blocks->ncounts);
964 typedef void (*vfp)(void);
966 extern vfp __new_handler;
973 extern void *malloc ();
983 typedef void (*vfp)(void);
985 extern void *__builtin_new ();
986 static void default_new_handler ();
988 vfp __new_handler = default_new_handler;
991 __builtin_vec_new (p, maxindex, size, ctor)
994 void (*ctor)(void *);
996 int i, nelts = maxindex + 1;
1000 p = __builtin_new (nelts * size);
1004 for (i = 0; i < nelts; i++)
1014 __set_new_handler (handler)
1019 prev_handler = __new_handler;
1020 if (handler == 0) handler = default_new_handler;
1021 __new_handler = handler;
1022 return prev_handler;
1026 set_new_handler (handler)
1029 return __set_new_handler (handler);
1032 #define MESSAGE "Virtual memory exceeded in `new'\n"
1035 default_new_handler ()
1037 /* don't use fprintf (stderr, ...) because it may need to call malloc. */
1038 /* This should really print the name of the program, but that is hard to
1039 do. We need a standard, clean way to get at the name. */
1040 write (2, MESSAGE, sizeof (MESSAGE));
1041 /* don't call exit () because that may call global destructors which
1042 may cause a loop. */
1047 #ifdef L_builtin_del
1048 typedef void (*vfp)(void);
1051 __builtin_delete (ptr)
1059 __builtin_vec_delete (ptr, maxindex, size, dtor, auto_delete_vec, auto_delete)
1065 int i, nelts = maxindex + 1;
1068 ptr += nelts * size;
1070 for (i = 0; i < nelts; i++)
1073 (*dtor) (ptr, auto_delete);
1076 if (auto_delete_vec)
1077 __builtin_delete (p);
1083 unsigned int __shtab[] = {
1084 0x00000001, 0x00000002, 0x00000004, 0x00000008,
1085 0x00000010, 0x00000020, 0x00000040, 0x00000080,
1086 0x00000100, 0x00000200, 0x00000400, 0x00000800,
1087 0x00001000, 0x00002000, 0x00004000, 0x00008000,
1088 0x00010000, 0x00020000, 0x00040000, 0x00080000,
1089 0x00100000, 0x00200000, 0x00400000, 0x00800000,
1090 0x01000000, 0x02000000, 0x04000000, 0x08000000,
1091 0x10000000, 0x20000000, 0x40000000, 0x80000000
1095 #ifdef L_clear_cache
1096 /* Clear part of an instruction cache. */
1098 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1101 __clear_cache (beg, end)
1104 #ifdef INSN_CACHE_SIZE
1105 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1106 static int initialized = 0;
1108 unsigned int start_addr, end_addr;
1109 typedef (*function_ptr) ();
1111 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1112 /* It's cheaper to clear the whole cache.
1113 Put in a series of jump instructions so that calling the beginning
1114 of the cache will clear the whole thing. */
1118 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1119 & -INSN_CACHE_LINE_WIDTH);
1120 int end_ptr = ptr + INSN_CACHE_SIZE;
1122 while (ptr < end_ptr)
1124 *(INSTRUCTION_TYPE *)ptr
1125 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1126 ptr += INSN_CACHE_LINE_WIDTH;
1128 *(INSTRUCTION_TYPE *)(ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1133 /* Call the beginning of the sequence. */
1134 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1135 & -INSN_CACHE_LINE_WIDTH))
1138 #else /* Cache is large. */
1142 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1143 & -INSN_CACHE_LINE_WIDTH);
1145 while (ptr < (int) array + sizeof array)
1147 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1148 ptr += INSN_CACHE_LINE_WIDTH;
1154 /* Find the location in array that occupies the same cache line as BEG. */
1156 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1157 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1158 & -INSN_CACHE_PLANE_SIZE)
1161 /* Compute the cache alignment of the place to stop clearing. */
1162 #if 0 /* This is not needed for gcc's purposes. */
1163 /* If the block to clear is bigger than a cache plane,
1164 we clear the entire cache, and OFFSET is already correct. */
1165 if (end < beg + INSN_CACHE_PLANE_SIZE)
1167 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1168 & -INSN_CACHE_LINE_WIDTH)
1169 & (INSN_CACHE_PLANE_SIZE - 1));
1171 #if INSN_CACHE_DEPTH > 1
1172 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1173 if (end_addr <= start_addr)
1174 end_addr += INSN_CACHE_PLANE_SIZE;
1176 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1178 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1179 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1181 while (addr != stop)
1183 /* Call the return instruction at ADDR. */
1184 ((function_ptr) addr) ();
1186 addr += INSN_CACHE_LINE_WIDTH;
1189 #else /* just one plane */
1192 /* Call the return instruction at START_ADDR. */
1193 ((function_ptr) start_addr) ();
1195 start_addr += INSN_CACHE_LINE_WIDTH;
1197 while ((start_addr % INSN_CACHE_SIZE) != offset);
1198 #endif /* just one plane */
1199 #endif /* Cache is large */
1200 #endif /* Cache exists */
1203 #endif /* L_clear_cache */
1207 /* Jump to a trampoline, loading the static chain address. */
1209 #ifdef TRANSFER_FROM_TRAMPOLINE
1210 TRANSFER_FROM_TRAMPOLINE
1215 /* Make stack executable so we can call trampolines on stack.
1216 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
1218 #include <sys/mman.h>
1219 #include <sys/vmparam.h>
1220 #include <machine/machparam.h>
1223 __enable_execute_stack ()
1226 static unsigned lowest = USRSTACK;
1227 unsigned current = (unsigned) &fp & -NBPG;
1229 if (lowest > current)
1231 unsigned len = lowest - current;
1232 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
1236 /* Clear instruction cache in case an old trampoline is in it. */
1239 #endif /* __convex__ */
1244 #include <sys/mman.h>
1245 #include <sys/types.h>
1246 #include <sys/param.h>
1247 #include <sys/vmmac.h>
1249 /* Modified from the convex -code above.
1250 mremap promises to clear the i-cache. */
1253 __enable_execute_stack ()
1256 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
1257 PROT_READ|PROT_WRITE|PROT_EXEC))
1259 perror ("mprotect in __enable_execute_stack");
1264 #endif /* __pyr__ */
1265 #endif /* L_trampoline */
1269 #include "gbl-ctors.h"
1271 /* Run all the global destructors on exit from the program. */
1274 __do_global_dtors ()
1276 #ifdef DO_GLOBAL_DTORS_BODY
1277 DO_GLOBAL_DTORS_BODY;
1279 int nptrs = *(int *)__DTOR_LIST__;
1282 /* Some systems place the number of pointers
1283 in the first word of the table.
1284 On other systems, that word is -1.
1285 In all cases, the table is null-terminated. */
1287 /* If the length is not recorded, count up to the null. */
1289 for (nptrs = 0; __DTOR_LIST__[nptrs + 1] != 0; nptrs++);
1291 /* GNU LD format. */
1292 for (i = nptrs; i >= 1; i--)
1293 __DTOR_LIST__[i] ();
1297 #ifndef INIT_SECTION_ASM_OP
1298 /* Run all the global constructors on entry to the program. */
1301 #define ON_EXIT(a, b)
1303 /* Make sure the exit routine is pulled in to define the globals as
1304 bss symbols, just in case the linker does not automatically pull
1305 bss definitions from the library. */
1307 extern int _exit_dummy_decl;
1308 int *_exit_dummy_ref = &_exit_dummy_decl;
1309 #endif /* ON_EXIT */
1312 __do_global_ctors ()
1314 DO_GLOBAL_CTORS_BODY;
1315 ON_EXIT (__do_global_dtors, 0);
1317 #endif /* no INIT_SECTION_ASM_OP */
1319 #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
1320 /* Subroutine called automatically by `main'.
1321 Compiling a global function named `main'
1322 produces an automatic call to this function at the beginning.
1324 For many systems, this routine calls __do_global_ctors.
1325 For systems which support a .init section we use the .init section
1326 to run __do_global_ctors, so we need not do anything here. */
1331 /* Support recursive calls to `main': run initializers just once. */
1332 static initialized = 0;
1336 __do_global_ctors ();
1339 #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
1341 #endif /* L__main */
1345 #include "gbl-ctors.h"
1347 /* Provide default definitions for the lists of constructors and
1348 destructors, so that we don't get linker errors. These symbols are
1349 intentionally bss symbols, so that gld and/or collect will provide
1350 the right values. */
1352 /* We declare the lists here with two elements each,
1353 so that they are valid empty lists if no other definition is loaded. */
1354 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
1355 func_ptr __CTOR_LIST__[2];
1356 func_ptr __DTOR_LIST__[2];
1357 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1361 /* If we have no known way of registering our own __do_global_dtors
1362 routine so that it will be invoked at program exit time, then we
1363 have to define our own exit routine which will get this to happen. */
1365 extern void __do_global_dtors ();
1366 extern void _cleanup ();
1367 extern void _exit ();
1373 __do_global_dtors ();
1383 int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */
1388 /* In a.out systems, we need to have these dummy constructor and destructor
1389 lists in the library.
1391 When using `collect', the first link will resolve __CTOR_LIST__
1392 and __DTOR_LIST__ to these symbols. We will then run "nm" on the
1393 result, build the correct __CTOR_LIST__ and __DTOR_LIST__, and relink.
1394 Since we don't do the second link if no constructors existed, these
1395 dummies must be fully functional empty lists.
1397 When using `gnu ld', these symbols will be used if there are no
1398 constructors. If there are constructors, the N_SETV symbol defined
1399 by the linker from the N_SETT's in input files will define __CTOR_LIST__
1400 and __DTOR_LIST__ rather than its being allocated as common storage
1401 by the definitions below.
1403 When using a linker that supports constructor and destructor segments,
1404 these definitions will not be used, since crtbegin.o and crtend.o
1405 (from crtstuff.c) will have already defined __CTOR_LIST__ and
1406 __DTOR_LIST__. The crt*.o files are passed directly to the linker
1407 on its command line, by gcc. */
1409 /* The list needs two elements: one is ignored (the old count); the
1410 second is the terminating zero. Since both values are zero, this
1411 declaration is not initialized, and it becomes `common'. */
1414 #include "gbl-ctors.h"
1415 func_ptr __CTOR_LIST__[2];
1419 #include "gbl-ctors.h"
1420 func_ptr __DTOR_LIST__[2];