* arm.md (stack_tie): New insn. Use an idiom that the alias code
[official-gcc.git] / gcc / libgcc2.c
blob4b1e187bcf4978a4eeb43d531f780a25af383c78
1 /* More subroutines needed by GCC output code on some machines. */
2 /* Compile this one with gcc. */
3 /* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
4 2000, 2001 Free Software Foundation, Inc.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
13 In addition to the permissions in the GNU General Public License, the
14 Free Software Foundation gives you unlimited permission to link the
15 compiled version of this file into combinations with other programs,
16 and to distribute those combinations without any restriction coming
17 from the use of this file. (The General Public License restrictions
18 do apply in other respects; for example, they cover modification of
19 the file, and distribution when not linked into a combine
20 executable.)
22 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
23 WARRANTY; without even the implied warranty of MERCHANTABILITY or
24 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25 for more details.
27 You should have received a copy of the GNU General Public License
28 along with GCC; see the file COPYING. If not, write to the Free
29 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
30 02111-1307, USA. */
32 /* It is incorrect to include config.h here, because this file is being
33 compiled for the target, and hence definitions concerning only the host
34 do not apply. */
36 #include "tconfig.h"
37 #include "tsystem.h"
39 /* Don't use `fancy_abort' here even if config.h says to use it. */
40 #ifdef abort
41 #undef abort
42 #endif
44 #include "libgcc2.h"
46 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
47 #if defined (L_divdi3) || defined (L_moddi3)
48 static inline
49 #endif
50 DWtype
51 __negdi2 (DWtype u)
53 DWunion w;
54 DWunion uu;
56 uu.ll = u;
58 w.s.low = -uu.s.low;
59 w.s.high = -uu.s.high - ((UWtype) w.s.low > 0);
61 return w.ll;
63 #endif
65 #ifdef L_addvsi3
66 Wtype
67 __addvsi3 (Wtype a, Wtype b)
69 Wtype w;
71 w = a + b;
73 if (b >= 0 ? w < a : w > a)
74 abort ();
76 return w;
78 #endif
80 #ifdef L_addvdi3
81 DWtype
82 __addvdi3 (DWtype a, DWtype b)
84 DWtype w;
86 w = a + b;
88 if (b >= 0 ? w < a : w > a)
89 abort ();
91 return w;
93 #endif
95 #ifdef L_subvsi3
96 Wtype
97 __subvsi3 (Wtype a, Wtype b)
99 #ifdef L_addvsi3
100 return __addvsi3 (a, (-b));
101 #else
102 DWtype w;
104 w = a - b;
106 if (b >= 0 ? w > a : w < a)
107 abort ();
109 return w;
110 #endif
112 #endif
114 #ifdef L_subvdi3
115 DWtype
116 __subvdi3 (DWtype a, DWtype b)
118 #ifdef L_addvdi3
119 return (a, (-b));
120 #else
121 DWtype w;
123 w = a - b;
125 if (b >= 0 ? w > a : w < a)
126 abort ();
128 return w;
129 #endif
131 #endif
133 #ifdef L_mulvsi3
134 Wtype
135 __mulvsi3 (Wtype a, Wtype b)
137 DWtype w;
139 w = a * b;
141 if (((a >= 0) == (b >= 0)) ? w < 0 : w > 0)
142 abort ();
144 return w;
146 #endif
148 #ifdef L_negvsi2
149 Wtype
150 __negvsi2 (Wtype a)
152 Wtype w;
154 w = -a;
156 if (a >= 0 ? w > 0 : w < 0)
157 abort ();
159 return w;
161 #endif
163 #ifdef L_negvdi2
164 DWtype
165 __negvdi2 (DWtype a)
167 DWtype w;
169 w = -a;
171 if (a >= 0 ? w > 0 : w < 0)
172 abort ();
174 return w;
176 #endif
178 #ifdef L_absvsi2
179 Wtype
180 __absvsi2 (Wtype a)
182 Wtype w = a;
184 if (a < 0)
185 #ifdef L_negvsi2
186 w = __negvsi2 (a);
187 #else
188 w = -a;
190 if (w < 0)
191 abort ();
192 #endif
194 return w;
196 #endif
198 #ifdef L_absvdi2
199 DWtype
200 __absvdi2 (DWtype a)
202 DWtype w = a;
204 if (a < 0)
205 #ifdef L_negvsi2
206 w = __negvsi2 (a);
207 #else
208 w = -a;
210 if (w < 0)
211 abort ();
212 #endif
214 return w;
216 #endif
218 #ifdef L_mulvdi3
219 DWtype
220 __mulvdi3 (DWtype u, DWtype v)
222 DWtype w;
224 w = u * v;
226 if (((u >= 0) == (v >= 0)) ? w < 0 : w > 0)
227 abort ();
229 return w;
231 #endif
234 /* Unless shift functions are defined whith full ANSI prototypes,
235 parameter b will be promoted to int if word_type is smaller than an int. */
236 #ifdef L_lshrdi3
237 DWtype
238 __lshrdi3 (DWtype u, word_type b)
240 DWunion w;
241 word_type bm;
242 DWunion uu;
244 if (b == 0)
245 return u;
247 uu.ll = u;
249 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
250 if (bm <= 0)
252 w.s.high = 0;
253 w.s.low = (UWtype) uu.s.high >> -bm;
255 else
257 UWtype carries = (UWtype) uu.s.high << bm;
259 w.s.high = (UWtype) uu.s.high >> b;
260 w.s.low = ((UWtype) uu.s.low >> b) | carries;
263 return w.ll;
265 #endif
267 #ifdef L_ashldi3
268 DWtype
269 __ashldi3 (DWtype u, word_type b)
271 DWunion w;
272 word_type bm;
273 DWunion uu;
275 if (b == 0)
276 return u;
278 uu.ll = u;
280 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
281 if (bm <= 0)
283 w.s.low = 0;
284 w.s.high = (UWtype) uu.s.low << -bm;
286 else
288 UWtype carries = (UWtype) uu.s.low >> bm;
290 w.s.low = (UWtype) uu.s.low << b;
291 w.s.high = ((UWtype) uu.s.high << b) | carries;
294 return w.ll;
296 #endif
298 #ifdef L_ashrdi3
299 DWtype
300 __ashrdi3 (DWtype u, word_type b)
302 DWunion w;
303 word_type bm;
304 DWunion uu;
306 if (b == 0)
307 return u;
309 uu.ll = u;
311 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
312 if (bm <= 0)
314 /* w.s.high = 1..1 or 0..0 */
315 w.s.high = uu.s.high >> (sizeof (Wtype) * BITS_PER_UNIT - 1);
316 w.s.low = uu.s.high >> -bm;
318 else
320 UWtype carries = (UWtype) uu.s.high << bm;
322 w.s.high = uu.s.high >> b;
323 w.s.low = ((UWtype) uu.s.low >> b) | carries;
326 return w.ll;
328 #endif
330 #ifdef L_ffsdi2
331 DWtype
332 __ffsdi2 (DWtype u)
334 DWunion uu;
335 UWtype word, count, add;
337 uu.ll = u;
338 if (uu.s.low != 0)
339 word = uu.s.low, add = 0;
340 else if (uu.s.high != 0)
341 word = uu.s.high, add = BITS_PER_UNIT * sizeof (Wtype);
342 else
343 return 0;
345 count_trailing_zeros (count, word);
346 return count + add + 1;
348 #endif
350 #ifdef L_muldi3
351 DWtype
352 __muldi3 (DWtype u, DWtype v)
354 DWunion w;
355 DWunion uu, vv;
357 uu.ll = u,
358 vv.ll = v;
360 w.ll = __umulsidi3 (uu.s.low, vv.s.low);
361 w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
362 + (UWtype) uu.s.high * (UWtype) vv.s.low);
364 return w.ll;
366 #endif
368 #ifdef L_udiv_w_sdiv
369 #if defined (sdiv_qrnnd)
370 UWtype
371 __udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d)
373 UWtype q, r;
374 UWtype c0, c1, b1;
376 if ((Wtype) d >= 0)
378 if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1)))
380 /* dividend, divisor, and quotient are nonnegative */
381 sdiv_qrnnd (q, r, a1, a0, d);
383 else
385 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
386 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1));
387 /* Divide (c1*2^32 + c0) by d */
388 sdiv_qrnnd (q, r, c1, c0, d);
389 /* Add 2^31 to quotient */
390 q += (UWtype) 1 << (W_TYPE_SIZE - 1);
393 else
395 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
396 c1 = a1 >> 1; /* A/2 */
397 c0 = (a1 << (W_TYPE_SIZE - 1)) + (a0 >> 1);
399 if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
401 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
403 r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
404 if ((d & 1) != 0)
406 if (r >= q)
407 r = r - q;
408 else if (q - r <= d)
410 r = r - q + d;
411 q--;
413 else
415 r = r - q + 2*d;
416 q -= 2;
420 else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
422 c1 = (b1 - 1) - c1;
423 c0 = ~c0; /* logical NOT */
425 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
427 q = ~q; /* (A/2)/b1 */
428 r = (b1 - 1) - r;
430 r = 2*r + (a0 & 1); /* A/(2*b1) */
432 if ((d & 1) != 0)
434 if (r >= q)
435 r = r - q;
436 else if (q - r <= d)
438 r = r - q + d;
439 q--;
441 else
443 r = r - q + 2*d;
444 q -= 2;
448 else /* Implies c1 = b1 */
449 { /* Hence a1 = d - 1 = 2*b1 - 1 */
450 if (a0 >= -d)
452 q = -1;
453 r = a0 + d;
455 else
457 q = -2;
458 r = a0 + 2*d;
463 *rp = r;
464 return q;
466 #else
467 /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */
468 UWtype
469 __udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)),
470 UWtype a1 __attribute__ ((__unused__)),
471 UWtype a0 __attribute__ ((__unused__)),
472 UWtype d __attribute__ ((__unused__)))
474 return 0;
476 #endif
477 #endif
479 #if (defined (L_udivdi3) || defined (L_divdi3) || \
480 defined (L_umoddi3) || defined (L_moddi3))
481 #define L_udivmoddi4
482 #endif
484 #ifdef L_clz
485 const UQItype __clz_tab[] =
487 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,
488 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,
489 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,
490 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,
491 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,
492 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,
493 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,
494 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,
496 #endif
498 #ifdef L_udivmoddi4
500 #if (defined (L_udivdi3) || defined (L_divdi3) || \
501 defined (L_umoddi3) || defined (L_moddi3))
502 static inline
503 #endif
504 UDWtype
505 __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
507 DWunion ww;
508 DWunion nn, dd;
509 DWunion rr;
510 UWtype d0, d1, n0, n1, n2;
511 UWtype q0, q1;
512 UWtype b, bm;
514 nn.ll = n;
515 dd.ll = d;
517 d0 = dd.s.low;
518 d1 = dd.s.high;
519 n0 = nn.s.low;
520 n1 = nn.s.high;
522 #if !UDIV_NEEDS_NORMALIZATION
523 if (d1 == 0)
525 if (d0 > n1)
527 /* 0q = nn / 0D */
529 udiv_qrnnd (q0, n0, n1, n0, d0);
530 q1 = 0;
532 /* Remainder in n0. */
534 else
536 /* qq = NN / 0d */
538 if (d0 == 0)
539 d0 = 1 / d0; /* Divide intentionally by zero. */
541 udiv_qrnnd (q1, n1, 0, n1, d0);
542 udiv_qrnnd (q0, n0, n1, n0, d0);
544 /* Remainder in n0. */
547 if (rp != 0)
549 rr.s.low = n0;
550 rr.s.high = 0;
551 *rp = rr.ll;
555 #else /* UDIV_NEEDS_NORMALIZATION */
557 if (d1 == 0)
559 if (d0 > n1)
561 /* 0q = nn / 0D */
563 count_leading_zeros (bm, d0);
565 if (bm != 0)
567 /* Normalize, i.e. make the most significant bit of the
568 denominator set. */
570 d0 = d0 << bm;
571 n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
572 n0 = n0 << bm;
575 udiv_qrnnd (q0, n0, n1, n0, d0);
576 q1 = 0;
578 /* Remainder in n0 >> bm. */
580 else
582 /* qq = NN / 0d */
584 if (d0 == 0)
585 d0 = 1 / d0; /* Divide intentionally by zero. */
587 count_leading_zeros (bm, d0);
589 if (bm == 0)
591 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
592 conclude (the most significant bit of n1 is set) /\ (the
593 leading quotient digit q1 = 1).
595 This special case is necessary, not an optimization.
596 (Shifts counts of W_TYPE_SIZE are undefined.) */
598 n1 -= d0;
599 q1 = 1;
601 else
603 /* Normalize. */
605 b = W_TYPE_SIZE - bm;
607 d0 = d0 << bm;
608 n2 = n1 >> b;
609 n1 = (n1 << bm) | (n0 >> b);
610 n0 = n0 << bm;
612 udiv_qrnnd (q1, n1, n2, n1, d0);
615 /* n1 != d0... */
617 udiv_qrnnd (q0, n0, n1, n0, d0);
619 /* Remainder in n0 >> bm. */
622 if (rp != 0)
624 rr.s.low = n0 >> bm;
625 rr.s.high = 0;
626 *rp = rr.ll;
629 #endif /* UDIV_NEEDS_NORMALIZATION */
631 else
633 if (d1 > n1)
635 /* 00 = nn / DD */
637 q0 = 0;
638 q1 = 0;
640 /* Remainder in n1n0. */
641 if (rp != 0)
643 rr.s.low = n0;
644 rr.s.high = n1;
645 *rp = rr.ll;
648 else
650 /* 0q = NN / dd */
652 count_leading_zeros (bm, d1);
653 if (bm == 0)
655 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
656 conclude (the most significant bit of n1 is set) /\ (the
657 quotient digit q0 = 0 or 1).
659 This special case is necessary, not an optimization. */
661 /* The condition on the next line takes advantage of that
662 n1 >= d1 (true due to program flow). */
663 if (n1 > d1 || n0 >= d0)
665 q0 = 1;
666 sub_ddmmss (n1, n0, n1, n0, d1, d0);
668 else
669 q0 = 0;
671 q1 = 0;
673 if (rp != 0)
675 rr.s.low = n0;
676 rr.s.high = n1;
677 *rp = rr.ll;
680 else
682 UWtype m1, m0;
683 /* Normalize. */
685 b = W_TYPE_SIZE - bm;
687 d1 = (d1 << bm) | (d0 >> b);
688 d0 = d0 << bm;
689 n2 = n1 >> b;
690 n1 = (n1 << bm) | (n0 >> b);
691 n0 = n0 << bm;
693 udiv_qrnnd (q0, n1, n2, n1, d1);
694 umul_ppmm (m1, m0, q0, d0);
696 if (m1 > n1 || (m1 == n1 && m0 > n0))
698 q0--;
699 sub_ddmmss (m1, m0, m1, m0, d1, d0);
702 q1 = 0;
704 /* Remainder in (n1n0 - m1m0) >> bm. */
705 if (rp != 0)
707 sub_ddmmss (n1, n0, n1, n0, m1, m0);
708 rr.s.low = (n1 << b) | (n0 >> bm);
709 rr.s.high = n1 >> bm;
710 *rp = rr.ll;
716 ww.s.low = q0;
717 ww.s.high = q1;
718 return ww.ll;
720 #endif
722 #ifdef L_divdi3
723 DWtype
724 __divdi3 (DWtype u, DWtype v)
726 word_type c = 0;
727 DWunion uu, vv;
728 DWtype w;
730 uu.ll = u;
731 vv.ll = v;
733 if (uu.s.high < 0)
734 c = ~c,
735 uu.ll = __negdi2 (uu.ll);
736 if (vv.s.high < 0)
737 c = ~c,
738 vv.ll = __negdi2 (vv.ll);
740 w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
741 if (c)
742 w = __negdi2 (w);
744 return w;
746 #endif
748 #ifdef L_moddi3
749 DWtype
750 __moddi3 (DWtype u, DWtype v)
752 word_type c = 0;
753 DWunion uu, vv;
754 DWtype w;
756 uu.ll = u;
757 vv.ll = v;
759 if (uu.s.high < 0)
760 c = ~c,
761 uu.ll = __negdi2 (uu.ll);
762 if (vv.s.high < 0)
763 vv.ll = __negdi2 (vv.ll);
765 (void) __udivmoddi4 (uu.ll, vv.ll, &w);
766 if (c)
767 w = __negdi2 (w);
769 return w;
771 #endif
773 #ifdef L_umoddi3
774 UDWtype
775 __umoddi3 (UDWtype u, UDWtype v)
777 UDWtype w;
779 (void) __udivmoddi4 (u, v, &w);
781 return w;
783 #endif
785 #ifdef L_udivdi3
786 UDWtype
787 __udivdi3 (UDWtype n, UDWtype d)
789 return __udivmoddi4 (n, d, (UDWtype *) 0);
791 #endif
793 #ifdef L_cmpdi2
794 word_type
795 __cmpdi2 (DWtype a, DWtype b)
797 DWunion au, bu;
799 au.ll = a, bu.ll = b;
801 if (au.s.high < bu.s.high)
802 return 0;
803 else if (au.s.high > bu.s.high)
804 return 2;
805 if ((UWtype) au.s.low < (UWtype) bu.s.low)
806 return 0;
807 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
808 return 2;
809 return 1;
811 #endif
813 #ifdef L_ucmpdi2
814 word_type
815 __ucmpdi2 (DWtype a, DWtype b)
817 DWunion au, bu;
819 au.ll = a, bu.ll = b;
821 if ((UWtype) au.s.high < (UWtype) bu.s.high)
822 return 0;
823 else if ((UWtype) au.s.high > (UWtype) bu.s.high)
824 return 2;
825 if ((UWtype) au.s.low < (UWtype) bu.s.low)
826 return 0;
827 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
828 return 2;
829 return 1;
831 #endif
833 #if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
834 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
835 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
837 DWtype
838 __fixunstfDI (TFtype a)
840 TFtype b;
841 UDWtype v;
843 if (a < 0)
844 return 0;
846 /* Compute high word of result, as a flonum. */
847 b = (a / HIGH_WORD_COEFF);
848 /* Convert that to fixed (but not to DWtype!),
849 and shift it into the high word. */
850 v = (UWtype) b;
851 v <<= WORD_SIZE;
852 /* Remove high part from the TFtype, leaving the low part as flonum. */
853 a -= (TFtype)v;
854 /* Convert that to fixed (but not to DWtype!) and add it in.
855 Sometimes A comes out negative. This is significant, since
856 A has more bits than a long int does. */
857 if (a < 0)
858 v -= (UWtype) (- a);
859 else
860 v += (UWtype) a;
861 return v;
863 #endif
865 #if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
866 DWtype
867 __fixtfdi (TFtype a)
869 if (a < 0)
870 return - __fixunstfDI (-a);
871 return __fixunstfDI (a);
873 #endif
875 #if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
876 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
877 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
879 DWtype
880 __fixunsxfDI (XFtype a)
882 XFtype b;
883 UDWtype v;
885 if (a < 0)
886 return 0;
888 /* Compute high word of result, as a flonum. */
889 b = (a / HIGH_WORD_COEFF);
890 /* Convert that to fixed (but not to DWtype!),
891 and shift it into the high word. */
892 v = (UWtype) b;
893 v <<= WORD_SIZE;
894 /* Remove high part from the XFtype, leaving the low part as flonum. */
895 a -= (XFtype)v;
896 /* Convert that to fixed (but not to DWtype!) and add it in.
897 Sometimes A comes out negative. This is significant, since
898 A has more bits than a long int does. */
899 if (a < 0)
900 v -= (UWtype) (- a);
901 else
902 v += (UWtype) a;
903 return v;
905 #endif
907 #if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
908 DWtype
909 __fixxfdi (XFtype a)
911 if (a < 0)
912 return - __fixunsxfDI (-a);
913 return __fixunsxfDI (a);
915 #endif
917 #ifdef L_fixunsdfdi
918 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
919 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
921 DWtype
922 __fixunsdfDI (DFtype a)
924 DFtype b;
925 UDWtype v;
927 if (a < 0)
928 return 0;
930 /* Compute high word of result, as a flonum. */
931 b = (a / HIGH_WORD_COEFF);
932 /* Convert that to fixed (but not to DWtype!),
933 and shift it into the high word. */
934 v = (UWtype) b;
935 v <<= WORD_SIZE;
936 /* Remove high part from the DFtype, leaving the low part as flonum. */
937 a -= (DFtype)v;
938 /* Convert that to fixed (but not to DWtype!) and add it in.
939 Sometimes A comes out negative. This is significant, since
940 A has more bits than a long int does. */
941 if (a < 0)
942 v -= (UWtype) (- a);
943 else
944 v += (UWtype) a;
945 return v;
947 #endif
949 #ifdef L_fixdfdi
950 DWtype
951 __fixdfdi (DFtype a)
953 if (a < 0)
954 return - __fixunsdfDI (-a);
955 return __fixunsdfDI (a);
957 #endif
959 #ifdef L_fixunssfdi
960 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
961 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
963 DWtype
964 __fixunssfDI (SFtype original_a)
966 /* Convert the SFtype to a DFtype, because that is surely not going
967 to lose any bits. Some day someone else can write a faster version
968 that avoids converting to DFtype, and verify it really works right. */
969 DFtype a = original_a;
970 DFtype b;
971 UDWtype v;
973 if (a < 0)
974 return 0;
976 /* Compute high word of result, as a flonum. */
977 b = (a / HIGH_WORD_COEFF);
978 /* Convert that to fixed (but not to DWtype!),
979 and shift it into the high word. */
980 v = (UWtype) b;
981 v <<= WORD_SIZE;
982 /* Remove high part from the DFtype, leaving the low part as flonum. */
983 a -= (DFtype) v;
984 /* Convert that to fixed (but not to DWtype!) and add it in.
985 Sometimes A comes out negative. This is significant, since
986 A has more bits than a long int does. */
987 if (a < 0)
988 v -= (UWtype) (- a);
989 else
990 v += (UWtype) a;
991 return v;
993 #endif
995 #ifdef L_fixsfdi
996 DWtype
997 __fixsfdi (SFtype a)
999 if (a < 0)
1000 return - __fixunssfDI (-a);
1001 return __fixunssfDI (a);
1003 #endif
1005 #if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
1006 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1007 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1008 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1010 XFtype
1011 __floatdixf (DWtype u)
1013 XFtype d;
1015 d = (Wtype) (u >> WORD_SIZE);
1016 d *= HIGH_HALFWORD_COEFF;
1017 d *= HIGH_HALFWORD_COEFF;
1018 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1020 return d;
1022 #endif
1024 #if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
1025 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1026 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1027 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1029 TFtype
1030 __floatditf (DWtype u)
1032 TFtype d;
1034 d = (Wtype) (u >> WORD_SIZE);
1035 d *= HIGH_HALFWORD_COEFF;
1036 d *= HIGH_HALFWORD_COEFF;
1037 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1039 return d;
1041 #endif
1043 #ifdef L_floatdidf
1044 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1045 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1046 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1048 DFtype
1049 __floatdidf (DWtype u)
1051 DFtype d;
1053 d = (Wtype) (u >> WORD_SIZE);
1054 d *= HIGH_HALFWORD_COEFF;
1055 d *= HIGH_HALFWORD_COEFF;
1056 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1058 return d;
1060 #endif
1062 #ifdef L_floatdisf
1063 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1064 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1065 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1067 #define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT)
1068 #define DF_SIZE DBL_MANT_DIG
1069 #define SF_SIZE FLT_MANT_DIG
1071 SFtype
1072 __floatdisf (DWtype u)
1074 /* Do the calculation in DFmode
1075 so that we don't lose any of the precision of the high word
1076 while multiplying it. */
1077 DFtype f;
1079 /* Protect against double-rounding error.
1080 Represent any low-order bits, that might be truncated in DFmode,
1081 by a bit that won't be lost. The bit can go in anywhere below the
1082 rounding position of the SFmode. A fixed mask and bit position
1083 handles all usual configurations. It doesn't handle the case
1084 of 128-bit DImode, however. */
1085 if (DF_SIZE < DI_SIZE
1086 && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1088 #define REP_BIT ((UDWtype) 1 << (DI_SIZE - DF_SIZE))
1089 if (! (- ((DWtype) 1 << DF_SIZE) < u
1090 && u < ((DWtype) 1 << DF_SIZE)))
1092 if ((UDWtype) u & (REP_BIT - 1))
1093 u |= REP_BIT;
1096 f = (Wtype) (u >> WORD_SIZE);
1097 f *= HIGH_HALFWORD_COEFF;
1098 f *= HIGH_HALFWORD_COEFF;
1099 f += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1101 return (SFtype) f;
1103 #endif
1105 #if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
1106 /* Reenable the normal types, in case limits.h needs them. */
1107 #undef char
1108 #undef short
1109 #undef int
1110 #undef long
1111 #undef unsigned
1112 #undef float
1113 #undef double
1114 #undef MIN
1115 #undef MAX
1116 #include <limits.h>
1118 UWtype
1119 __fixunsxfSI (XFtype a)
1121 if (a >= - (DFtype) Wtype_MIN)
1122 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1123 return (Wtype) a;
1125 #endif
1127 #ifdef L_fixunsdfsi
1128 /* Reenable the normal types, in case limits.h needs them. */
1129 #undef char
1130 #undef short
1131 #undef int
1132 #undef long
1133 #undef unsigned
1134 #undef float
1135 #undef double
1136 #undef MIN
1137 #undef MAX
1138 #include <limits.h>
1140 UWtype
1141 __fixunsdfSI (DFtype a)
1143 if (a >= - (DFtype) Wtype_MIN)
1144 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1145 return (Wtype) a;
1147 #endif
1149 #ifdef L_fixunssfsi
1150 /* Reenable the normal types, in case limits.h needs them. */
1151 #undef char
1152 #undef short
1153 #undef int
1154 #undef long
1155 #undef unsigned
1156 #undef float
1157 #undef double
1158 #undef MIN
1159 #undef MAX
1160 #include <limits.h>
1162 UWtype
1163 __fixunssfSI (SFtype a)
1165 if (a >= - (SFtype) Wtype_MIN)
1166 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1167 return (Wtype) a;
1169 #endif
1171 /* From here on down, the routines use normal data types. */
1173 #define SItype bogus_type
1174 #define USItype bogus_type
1175 #define DItype bogus_type
1176 #define UDItype bogus_type
1177 #define SFtype bogus_type
1178 #define DFtype bogus_type
1179 #undef Wtype
1180 #undef UWtype
1181 #undef HWtype
1182 #undef UHWtype
1183 #undef DWtype
1184 #undef UDWtype
1186 #undef char
1187 #undef short
1188 #undef int
1189 #undef long
1190 #undef unsigned
1191 #undef float
1192 #undef double
1194 #ifdef L__gcc_bcmp
1196 /* Like bcmp except the sign is meaningful.
1197 Result is negative if S1 is less than S2,
1198 positive if S1 is greater, 0 if S1 and S2 are equal. */
1201 __gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
1203 while (size > 0)
1205 unsigned char c1 = *s1++, c2 = *s2++;
1206 if (c1 != c2)
1207 return c1 - c2;
1208 size--;
1210 return 0;
1213 #endif
1215 /* __eprintf used to be used by GCC's private version of <assert.h>.
1216 We no longer provide that header, but this routine remains in libgcc.a
1217 for binary backward compatibility. Note that it is not included in
1218 the shared version of libgcc. */
1219 #ifdef L_eprintf
1220 #ifndef inhibit_libc
1222 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1223 #include <stdio.h>
1225 void
1226 __eprintf (const char *string, const char *expression,
1227 unsigned int line, const char *filename)
1229 fprintf (stderr, string, expression, line, filename);
1230 fflush (stderr);
1231 abort ();
1234 #endif
1235 #endif
1237 #ifdef L_bb
1239 struct bb_function_info {
1240 long checksum;
1241 int arc_count;
1242 const char *name;
1245 /* Structure emitted by -a */
1246 struct bb
1248 long zero_word;
1249 const char *filename;
1250 gcov_type *counts;
1251 long ncounts;
1252 struct bb *next;
1254 /* Older GCC's did not emit these fields. */
1255 long sizeof_bb;
1256 struct bb_function_info *function_infos;
1259 #ifndef inhibit_libc
1261 /* Simple minded basic block profiling output dumper for
1262 systems that don't provide tcov support. At present,
1263 it requires atexit and stdio. */
1265 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1266 #include <stdio.h>
1268 #include "gbl-ctors.h"
1269 #include "gcov-io.h"
1270 #include <string.h>
1271 #ifdef TARGET_HAS_F_SETLKW
1272 #include <fcntl.h>
1273 #include <errno.h>
1274 #endif
1276 #include <gthr.h>
1278 static struct bb *bb_head;
1280 int __global_counters = 0, __gthreads_active = 0;
1282 void
1283 __bb_exit_func (void)
1285 FILE *da_file;
1286 struct bb *ptr;
1287 long n_counters_p = 0;
1288 gcov_type max_counter_p = 0;
1289 gcov_type sum_counters_p = 0;
1291 if (bb_head == 0)
1292 return;
1294 /* Calculate overall "statistics". */
1296 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1298 int i;
1300 n_counters_p += ptr->ncounts;
1302 for (i = 0; i < ptr->ncounts; i++)
1304 sum_counters_p += ptr->counts[i];
1306 if (ptr->counts[i] > max_counter_p)
1307 max_counter_p = ptr->counts[i];
1311 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1313 gcov_type max_counter_o = 0;
1314 gcov_type sum_counters_o = 0;
1315 int i;
1317 /* Calculate the per-object statistics. */
1319 for (i = 0; i < ptr->ncounts; i++)
1321 sum_counters_o += ptr->counts[i];
1323 if (ptr->counts[i] > max_counter_o)
1324 max_counter_o = ptr->counts[i];
1327 /* open the file for appending, creating it if necessary. */
1328 da_file = fopen (ptr->filename, "ab");
1329 /* Some old systems might not allow the 'b' mode modifier.
1330 Therefore, try to open without it. This can lead to a race
1331 condition so that when you delete and re-create the file, the
1332 file might be opened in text mode, but then, you shouldn't
1333 delete the file in the first place. */
1334 if (da_file == 0)
1335 da_file = fopen (ptr->filename, "a");
1336 if (da_file == 0)
1338 fprintf (stderr, "arc profiling: Can't open output file %s.\n",
1339 ptr->filename);
1340 continue;
1343 /* After a fork, another process might try to read and/or write
1344 the same file simultanously. So if we can, lock the file to
1345 avoid race conditions. */
1346 #if defined (TARGET_HAS_F_SETLKW)
1348 struct flock s_flock;
1350 s_flock.l_type = F_WRLCK;
1351 s_flock.l_whence = SEEK_SET;
1352 s_flock.l_start = 0;
1353 s_flock.l_len = 1;
1354 s_flock.l_pid = getpid ();
1356 while (fcntl (fileno (da_file), F_SETLKW, &s_flock)
1357 && errno == EINTR);
1359 #endif
1361 if (__write_long (-123, da_file, 4) != 0) /* magic */
1363 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1364 ptr->filename);
1366 else
1369 struct bb_function_info *fn_info;
1370 gcov_type *count_ptr = ptr->counts;
1371 int i;
1372 int count_functions = 0;
1374 for (fn_info = ptr->function_infos; fn_info->arc_count != -1;
1375 fn_info++)
1376 count_functions++;
1378 /* number of functions in this block. */
1379 __write_long (count_functions, da_file, 4);
1381 /* length of extra data in bytes. */
1382 __write_long ((4 + 8 + 8) + (4 + 8 + 8), da_file, 4);
1384 /* overall statistics. */
1385 /* number of counters. */
1386 __write_long (n_counters_p, da_file, 4);
1387 /* sum of counters. */
1388 __write_gcov_type (sum_counters_p, da_file, 8);
1389 /* maximal counter. */
1390 __write_gcov_type (max_counter_p, da_file, 8);
1392 /* per-object statistics. */
1393 /* number of counters. */
1394 __write_long (ptr->ncounts, da_file, 4);
1395 /* sum of counters. */
1396 __write_gcov_type (sum_counters_o, da_file, 8);
1397 /* maximal counter. */
1398 __write_gcov_type (max_counter_o, da_file, 8);
1400 /* write execution counts for each function. */
1402 for (fn_info = ptr->function_infos; fn_info->arc_count != -1;
1403 fn_info++)
1405 /* new function. */
1406 if (__write_gcov_string
1407 (fn_info->name, strlen (fn_info->name), da_file, -1) != 0)
1409 fprintf (stderr,
1410 "arc profiling: Error writing output file %s.\n",
1411 ptr->filename);
1412 break;
1415 if (__write_long (fn_info->checksum, da_file, 4) != 0)
1417 fprintf (stderr,
1418 "arc profiling: Error writing output file %s.\n",
1419 ptr->filename);
1420 break;
1423 if (__write_long (fn_info->arc_count, da_file, 4) != 0)
1425 fprintf (stderr,
1426 "arc profiling: Error writing output file %s.\n",
1427 ptr->filename);
1428 break;
1431 for (i = fn_info->arc_count; i > 0; i--, count_ptr++)
1433 if (__write_gcov_type (*count_ptr, da_file, 8) != 0)
1434 break;
1437 if (i) /* there was an error */
1439 fprintf (stderr,
1440 "arc profiling: Error writing output file %s.\n",
1441 ptr->filename);
1442 break;
1447 if (fclose (da_file) != 0)
1448 fprintf (stderr, "arc profiling: Error closing output file %s.\n",
1449 ptr->filename);
1453 void
1454 __bb_init_func (struct bb *blocks)
1456 /* User is supposed to check whether the first word is non-0,
1457 but just in case.... */
1459 if (blocks->zero_word)
1460 return;
1462 /* Initialize destructor and per-thread data. */
1463 if (!bb_head)
1464 atexit (__bb_exit_func);
1466 /* Set up linked list. */
1467 blocks->zero_word = 1;
1468 blocks->next = bb_head;
1469 bb_head = blocks;
1472 /* Called before fork or exec - write out profile information gathered so
1473 far and reset it to zero. This avoids duplication or loss of the
1474 profile information gathered so far. */
1475 void
1476 __bb_fork_func (void)
1478 struct bb *ptr;
1480 __bb_exit_func ();
1481 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1483 long i;
1484 for (i = ptr->ncounts - 1; i >= 0; i--)
1485 ptr->counts[i] = 0;
1489 #endif /* not inhibit_libc */
1490 #endif /* L_bb */
1492 #ifdef L_clear_cache
1493 /* Clear part of an instruction cache. */
1495 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1497 void
1498 __clear_cache (char *beg __attribute__((__unused__)),
1499 char *end __attribute__((__unused__)))
1501 #ifdef CLEAR_INSN_CACHE
1502 CLEAR_INSN_CACHE (beg, end);
1503 #else
1504 #ifdef INSN_CACHE_SIZE
1505 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1506 static int initialized;
1507 int offset;
1508 void *start_addr
1509 void *end_addr;
1510 typedef (*function_ptr) (void);
1512 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1513 /* It's cheaper to clear the whole cache.
1514 Put in a series of jump instructions so that calling the beginning
1515 of the cache will clear the whole thing. */
1517 if (! initialized)
1519 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1520 & -INSN_CACHE_LINE_WIDTH);
1521 int end_ptr = ptr + INSN_CACHE_SIZE;
1523 while (ptr < end_ptr)
1525 *(INSTRUCTION_TYPE *)ptr
1526 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1527 ptr += INSN_CACHE_LINE_WIDTH;
1529 *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1531 initialized = 1;
1534 /* Call the beginning of the sequence. */
1535 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1536 & -INSN_CACHE_LINE_WIDTH))
1537 ());
1539 #else /* Cache is large. */
1541 if (! initialized)
1543 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1544 & -INSN_CACHE_LINE_WIDTH);
1546 while (ptr < (int) array + sizeof array)
1548 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1549 ptr += INSN_CACHE_LINE_WIDTH;
1552 initialized = 1;
1555 /* Find the location in array that occupies the same cache line as BEG. */
1557 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1558 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1559 & -INSN_CACHE_PLANE_SIZE)
1560 + offset);
1562 /* Compute the cache alignment of the place to stop clearing. */
1563 #if 0 /* This is not needed for gcc's purposes. */
1564 /* If the block to clear is bigger than a cache plane,
1565 we clear the entire cache, and OFFSET is already correct. */
1566 if (end < beg + INSN_CACHE_PLANE_SIZE)
1567 #endif
1568 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1569 & -INSN_CACHE_LINE_WIDTH)
1570 & (INSN_CACHE_PLANE_SIZE - 1));
1572 #if INSN_CACHE_DEPTH > 1
1573 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1574 if (end_addr <= start_addr)
1575 end_addr += INSN_CACHE_PLANE_SIZE;
1577 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1579 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1580 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1582 while (addr != stop)
1584 /* Call the return instruction at ADDR. */
1585 ((function_ptr) addr) ();
1587 addr += INSN_CACHE_LINE_WIDTH;
1590 #else /* just one plane */
1593 /* Call the return instruction at START_ADDR. */
1594 ((function_ptr) start_addr) ();
1596 start_addr += INSN_CACHE_LINE_WIDTH;
1598 while ((start_addr % INSN_CACHE_SIZE) != offset);
1599 #endif /* just one plane */
1600 #endif /* Cache is large */
1601 #endif /* Cache exists */
1602 #endif /* CLEAR_INSN_CACHE */
1605 #endif /* L_clear_cache */
1607 #ifdef L_trampoline
1609 /* Jump to a trampoline, loading the static chain address. */
1611 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
1613 long
1614 getpagesize (void)
1616 #ifdef _ALPHA_
1617 return 8192;
1618 #else
1619 return 4096;
1620 #endif
1623 #ifdef __i386__
1624 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
1625 #endif
1628 mprotect (char *addr, int len, int prot)
1630 int np, op;
1632 if (prot == 7)
1633 np = 0x40;
1634 else if (prot == 5)
1635 np = 0x20;
1636 else if (prot == 4)
1637 np = 0x10;
1638 else if (prot == 3)
1639 np = 0x04;
1640 else if (prot == 1)
1641 np = 0x02;
1642 else if (prot == 0)
1643 np = 0x01;
1645 if (VirtualProtect (addr, len, np, &op))
1646 return 0;
1647 else
1648 return -1;
1651 #endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
1653 #ifdef TRANSFER_FROM_TRAMPOLINE
1654 TRANSFER_FROM_TRAMPOLINE
1655 #endif
1657 #if defined (NeXT) && defined (__MACH__)
1659 /* Make stack executable so we can call trampolines on stack.
1660 This is called from INITIALIZE_TRAMPOLINE in next.h. */
1661 #ifdef NeXTStep21
1662 #include <mach.h>
1663 #else
1664 #include <mach/mach.h>
1665 #endif
1667 void
1668 __enable_execute_stack (char *addr)
1670 kern_return_t r;
1671 char *eaddr = addr + TRAMPOLINE_SIZE;
1672 vm_address_t a = (vm_address_t) addr;
1674 /* turn on execute access on stack */
1675 r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
1676 if (r != KERN_SUCCESS)
1678 mach_error("vm_protect VM_PROT_ALL", r);
1679 exit(1);
1682 /* We inline the i-cache invalidation for speed */
1684 #ifdef CLEAR_INSN_CACHE
1685 CLEAR_INSN_CACHE (addr, eaddr);
1686 #else
1687 __clear_cache ((int) addr, (int) eaddr);
1688 #endif
1691 #endif /* defined (NeXT) && defined (__MACH__) */
1693 #ifdef __convex__
1695 /* Make stack executable so we can call trampolines on stack.
1696 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
1698 #include <sys/mman.h>
1699 #include <sys/vmparam.h>
1700 #include <machine/machparam.h>
1702 void
1703 __enable_execute_stack (void)
1705 int fp;
1706 static unsigned lowest = USRSTACK;
1707 unsigned current = (unsigned) &fp & -NBPG;
1709 if (lowest > current)
1711 unsigned len = lowest - current;
1712 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
1713 lowest = current;
1716 /* Clear instruction cache in case an old trampoline is in it. */
1717 asm ("pich");
1719 #endif /* __convex__ */
1721 #ifdef __sysV88__
1723 /* Modified from the convex -code above. */
1725 #include <sys/param.h>
1726 #include <errno.h>
1727 #include <sys/m88kbcs.h>
1729 void
1730 __enable_execute_stack (void)
1732 int save_errno;
1733 static unsigned long lowest = USRSTACK;
1734 unsigned long current = (unsigned long) &save_errno & -NBPC;
1736 /* Ignore errno being set. memctl sets errno to EINVAL whenever the
1737 address is seen as 'negative'. That is the case with the stack. */
1739 save_errno=errno;
1740 if (lowest > current)
1742 unsigned len=lowest-current;
1743 memctl(current,len,MCT_TEXT);
1744 lowest = current;
1746 else
1747 memctl(current,NBPC,MCT_TEXT);
1748 errno=save_errno;
1751 #endif /* __sysV88__ */
1753 #ifdef __sysV68__
1755 #include <sys/signal.h>
1756 #include <errno.h>
1758 /* Motorola forgot to put memctl.o in the libp version of libc881.a,
1759 so define it here, because we need it in __clear_insn_cache below */
1760 /* On older versions of this OS, no memctl or MCT_TEXT are defined;
1761 hence we enable this stuff only if MCT_TEXT is #define'd. */
1763 #ifdef MCT_TEXT
1764 asm("\n\
1765 global memctl\n\
1766 memctl:\n\
1767 movq &75,%d0\n\
1768 trap &0\n\
1769 bcc.b noerror\n\
1770 jmp cerror%\n\
1771 noerror:\n\
1772 movq &0,%d0\n\
1773 rts");
1774 #endif
1776 /* Clear instruction cache so we can call trampolines on stack.
1777 This is called from FINALIZE_TRAMPOLINE in mot3300.h. */
1779 void
1780 __clear_insn_cache (void)
1782 #ifdef MCT_TEXT
1783 int save_errno;
1785 /* Preserve errno, because users would be surprised to have
1786 errno changing without explicitly calling any system-call. */
1787 save_errno = errno;
1789 /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache.
1790 No need to use an address derived from _start or %sp, as 0 works also. */
1791 memctl(0, 4096, MCT_TEXT);
1792 errno = save_errno;
1793 #endif
1796 #endif /* __sysV68__ */
1798 #ifdef __pyr__
1800 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1801 #include <stdio.h>
1802 #include <sys/mman.h>
1803 #include <sys/types.h>
1804 #include <sys/param.h>
1805 #include <sys/vmmac.h>
1807 /* Modified from the convex -code above.
1808 mremap promises to clear the i-cache. */
1810 void
1811 __enable_execute_stack (void)
1813 int fp;
1814 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
1815 PROT_READ|PROT_WRITE|PROT_EXEC))
1817 perror ("mprotect in __enable_execute_stack");
1818 fflush (stderr);
1819 abort ();
1822 #endif /* __pyr__ */
1824 #if defined (sony_news) && defined (SYSTYPE_BSD)
1826 #include <stdio.h>
1827 #include <sys/types.h>
1828 #include <sys/param.h>
1829 #include <syscall.h>
1830 #include <machine/sysnews.h>
1832 /* cacheflush function for NEWS-OS 4.2.
1833 This function is called from trampoline-initialize code
1834 defined in config/mips/mips.h. */
1836 void
1837 cacheflush (char *beg, int size, int flag)
1839 if (syscall (SYS_sysnews, NEWS_CACHEFLUSH, beg, size, FLUSH_BCACHE))
1841 perror ("cache_flush");
1842 fflush (stderr);
1843 abort ();
1847 #endif /* sony_news */
1848 #endif /* L_trampoline */
1850 #ifndef __CYGWIN__
1851 #ifdef L__main
1853 #include "gbl-ctors.h"
1854 /* Some systems use __main in a way incompatible with its use in gcc, in these
1855 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
1856 give the same symbol without quotes for an alternative entry point. You
1857 must define both, or neither. */
1858 #ifndef NAME__MAIN
1859 #define NAME__MAIN "__main"
1860 #define SYMBOL__MAIN __main
1861 #endif
1863 #ifdef INIT_SECTION_ASM_OP
1864 #undef HAS_INIT_SECTION
1865 #define HAS_INIT_SECTION
1866 #endif
1868 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
1870 /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
1871 code to run constructors. In that case, we need to handle EH here, too. */
1873 #ifdef EH_FRAME_SECTION_NAME
1874 #include "unwind-dw2-fde.h"
1875 extern unsigned char __EH_FRAME_BEGIN__[];
1876 #endif
1878 /* Run all the global destructors on exit from the program. */
1880 void
1881 __do_global_dtors (void)
1883 #ifdef DO_GLOBAL_DTORS_BODY
1884 DO_GLOBAL_DTORS_BODY;
1885 #else
1886 static func_ptr *p = __DTOR_LIST__ + 1;
1887 while (*p)
1889 p++;
1890 (*(p-1)) ();
1892 #endif
1893 #if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION)
1895 static int completed = 0;
1896 if (! completed)
1898 completed = 1;
1899 __deregister_frame_info (__EH_FRAME_BEGIN__);
1902 #endif
1904 #endif
1906 #ifndef HAS_INIT_SECTION
1907 /* Run all the global constructors on entry to the program. */
1909 void
1910 __do_global_ctors (void)
1912 #ifdef EH_FRAME_SECTION_NAME
1914 static struct object object;
1915 __register_frame_info (__EH_FRAME_BEGIN__, &object);
1917 #endif
1918 DO_GLOBAL_CTORS_BODY;
1919 atexit (__do_global_dtors);
1921 #endif /* no HAS_INIT_SECTION */
1923 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
1924 /* Subroutine called automatically by `main'.
1925 Compiling a global function named `main'
1926 produces an automatic call to this function at the beginning.
1928 For many systems, this routine calls __do_global_ctors.
1929 For systems which support a .init section we use the .init section
1930 to run __do_global_ctors, so we need not do anything here. */
1932 void
1933 SYMBOL__MAIN ()
1935 /* Support recursive calls to `main': run initializers just once. */
1936 static int initialized;
1937 if (! initialized)
1939 initialized = 1;
1940 __do_global_ctors ();
1943 #endif /* no HAS_INIT_SECTION or INVOKE__main */
1945 #endif /* L__main */
1946 #endif /* __CYGWIN__ */
1948 #ifdef L_ctors
1950 #include "gbl-ctors.h"
1952 /* Provide default definitions for the lists of constructors and
1953 destructors, so that we don't get linker errors. These symbols are
1954 intentionally bss symbols, so that gld and/or collect will provide
1955 the right values. */
1957 /* We declare the lists here with two elements each,
1958 so that they are valid empty lists if no other definition is loaded.
1960 If we are using the old "set" extensions to have the gnu linker
1961 collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
1962 must be in the bss/common section.
1964 Long term no port should use those extensions. But many still do. */
1965 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
1966 #if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2)
1967 func_ptr __CTOR_LIST__[2] = {0, 0};
1968 func_ptr __DTOR_LIST__[2] = {0, 0};
1969 #else
1970 func_ptr __CTOR_LIST__[2];
1971 func_ptr __DTOR_LIST__[2];
1972 #endif
1973 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1974 #endif /* L_ctors */
1976 #ifdef L_exit
1978 #include "gbl-ctors.h"
1980 #ifdef NEED_ATEXIT
1982 #ifndef ON_EXIT
1984 # include <errno.h>
1986 static func_ptr *atexit_chain = 0;
1987 static long atexit_chain_length = 0;
1988 static volatile long last_atexit_chain_slot = -1;
1991 atexit (func_ptr func)
1993 if (++last_atexit_chain_slot == atexit_chain_length)
1995 atexit_chain_length += 32;
1996 if (atexit_chain)
1997 atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
1998 * sizeof (func_ptr));
1999 else
2000 atexit_chain = (func_ptr *) malloc (atexit_chain_length
2001 * sizeof (func_ptr));
2002 if (! atexit_chain)
2004 atexit_chain_length = 0;
2005 last_atexit_chain_slot = -1;
2006 errno = ENOMEM;
2007 return (-1);
2010 atexit_chain[last_atexit_chain_slot] = func;
2011 return (0);
2014 extern void _cleanup (void);
2015 extern void _exit (int) __attribute__ ((__noreturn__));
2017 void
2018 exit (int status)
2020 if (atexit_chain)
2022 for ( ; last_atexit_chain_slot-- >= 0; )
2024 (*atexit_chain[last_atexit_chain_slot + 1]) ();
2025 atexit_chain[last_atexit_chain_slot + 1] = 0;
2027 free (atexit_chain);
2028 atexit_chain = 0;
2030 #ifdef EXIT_BODY
2031 EXIT_BODY;
2032 #else
2033 _cleanup ();
2034 #endif
2035 _exit (status);
2038 #else /* ON_EXIT */
2040 /* Simple; we just need a wrapper for ON_EXIT. */
2042 atexit (func_ptr func)
2044 return ON_EXIT (func);
2047 #endif /* ON_EXIT */
2048 #endif /* NEED_ATEXIT */
2050 #endif /* L_exit */