* config/arm/netbsd.h (TARGET_OS_CPP_BUILTINS): Use
[official-gcc.git] / gcc / libgcc2.c
bloba88c08df366b099978b4e7ba63c94942d0a1669b
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 #include "machmode.h"
41 /* Don't use `fancy_abort' here even if config.h says to use it. */
42 #ifdef abort
43 #undef abort
44 #endif
46 #include "libgcc2.h"
48 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
49 #if defined (L_divdi3) || defined (L_moddi3)
50 static inline
51 #endif
52 DWtype
53 __negdi2 (DWtype u)
55 DWunion w;
56 DWunion uu;
58 uu.ll = u;
60 w.s.low = -uu.s.low;
61 w.s.high = -uu.s.high - ((UWtype) w.s.low > 0);
63 return w.ll;
65 #endif
67 #ifdef L_addvsi3
68 Wtype
69 __addvsi3 (Wtype a, Wtype b)
71 Wtype w;
73 w = a + b;
75 if (b >= 0 ? w < a : w > a)
76 abort ();
78 return w;
80 #endif
82 #ifdef L_addvdi3
83 DWtype
84 __addvdi3 (DWtype a, DWtype b)
86 DWtype w;
88 w = a + b;
90 if (b >= 0 ? w < a : w > a)
91 abort ();
93 return w;
95 #endif
97 #ifdef L_subvsi3
98 Wtype
99 __subvsi3 (Wtype a, Wtype b)
101 #ifdef L_addvsi3
102 return __addvsi3 (a, (-b));
103 #else
104 DWtype w;
106 w = a - b;
108 if (b >= 0 ? w > a : w < a)
109 abort ();
111 return w;
112 #endif
114 #endif
116 #ifdef L_subvdi3
117 DWtype
118 __subvdi3 (DWtype a, DWtype b)
120 #ifdef L_addvdi3
121 return (a, (-b));
122 #else
123 DWtype w;
125 w = a - b;
127 if (b >= 0 ? w > a : w < a)
128 abort ();
130 return w;
131 #endif
133 #endif
135 #ifdef L_mulvsi3
136 Wtype
137 __mulvsi3 (Wtype a, Wtype b)
139 DWtype w;
141 w = a * b;
143 if (((a >= 0) == (b >= 0)) ? w < 0 : w > 0)
144 abort ();
146 return w;
148 #endif
150 #ifdef L_negvsi2
151 Wtype
152 __negvsi2 (Wtype a)
154 Wtype w;
156 w = -a;
158 if (a >= 0 ? w > 0 : w < 0)
159 abort ();
161 return w;
163 #endif
165 #ifdef L_negvdi2
166 DWtype
167 __negvdi2 (DWtype a)
169 DWtype w;
171 w = -a;
173 if (a >= 0 ? w > 0 : w < 0)
174 abort ();
176 return w;
178 #endif
180 #ifdef L_absvsi2
181 Wtype
182 __absvsi2 (Wtype a)
184 Wtype w = a;
186 if (a < 0)
187 #ifdef L_negvsi2
188 w = __negvsi2 (a);
189 #else
190 w = -a;
192 if (w < 0)
193 abort ();
194 #endif
196 return w;
198 #endif
200 #ifdef L_absvdi2
201 DWtype
202 __absvdi2 (DWtype a)
204 DWtype w = a;
206 if (a < 0)
207 #ifdef L_negvsi2
208 w = __negvsi2 (a);
209 #else
210 w = -a;
212 if (w < 0)
213 abort ();
214 #endif
216 return w;
218 #endif
220 #ifdef L_mulvdi3
221 DWtype
222 __mulvdi3 (DWtype u, DWtype v)
224 DWtype w;
226 w = u * v;
228 if (((u >= 0) == (v >= 0)) ? w < 0 : w > 0)
229 abort ();
231 return w;
233 #endif
236 /* Unless shift functions are defined whith full ANSI prototypes,
237 parameter b will be promoted to int if word_type is smaller than an int. */
238 #ifdef L_lshrdi3
239 DWtype
240 __lshrdi3 (DWtype u, word_type b)
242 DWunion w;
243 word_type bm;
244 DWunion uu;
246 if (b == 0)
247 return u;
249 uu.ll = u;
251 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
252 if (bm <= 0)
254 w.s.high = 0;
255 w.s.low = (UWtype) uu.s.high >> -bm;
257 else
259 UWtype carries = (UWtype) uu.s.high << bm;
261 w.s.high = (UWtype) uu.s.high >> b;
262 w.s.low = ((UWtype) uu.s.low >> b) | carries;
265 return w.ll;
267 #endif
269 #ifdef L_ashldi3
270 DWtype
271 __ashldi3 (DWtype u, word_type b)
273 DWunion w;
274 word_type bm;
275 DWunion uu;
277 if (b == 0)
278 return u;
280 uu.ll = u;
282 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
283 if (bm <= 0)
285 w.s.low = 0;
286 w.s.high = (UWtype) uu.s.low << -bm;
288 else
290 UWtype carries = (UWtype) uu.s.low >> bm;
292 w.s.low = (UWtype) uu.s.low << b;
293 w.s.high = ((UWtype) uu.s.high << b) | carries;
296 return w.ll;
298 #endif
300 #ifdef L_ashrdi3
301 DWtype
302 __ashrdi3 (DWtype u, word_type b)
304 DWunion w;
305 word_type bm;
306 DWunion uu;
308 if (b == 0)
309 return u;
311 uu.ll = u;
313 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
314 if (bm <= 0)
316 /* w.s.high = 1..1 or 0..0 */
317 w.s.high = uu.s.high >> (sizeof (Wtype) * BITS_PER_UNIT - 1);
318 w.s.low = uu.s.high >> -bm;
320 else
322 UWtype carries = (UWtype) uu.s.high << bm;
324 w.s.high = uu.s.high >> b;
325 w.s.low = ((UWtype) uu.s.low >> b) | carries;
328 return w.ll;
330 #endif
332 #ifdef L_ffsdi2
333 DWtype
334 __ffsdi2 (DWtype u)
336 DWunion uu;
337 UWtype word, count, add;
339 uu.ll = u;
340 if (uu.s.low != 0)
341 word = uu.s.low, add = 0;
342 else if (uu.s.high != 0)
343 word = uu.s.high, add = BITS_PER_UNIT * sizeof (Wtype);
344 else
345 return 0;
347 count_trailing_zeros (count, word);
348 return count + add + 1;
350 #endif
352 #ifdef L_muldi3
353 DWtype
354 __muldi3 (DWtype u, DWtype v)
356 DWunion w;
357 DWunion uu, vv;
359 uu.ll = u,
360 vv.ll = v;
362 w.ll = __umulsidi3 (uu.s.low, vv.s.low);
363 w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
364 + (UWtype) uu.s.high * (UWtype) vv.s.low);
366 return w.ll;
368 #endif
370 #ifdef L_udiv_w_sdiv
371 #if defined (sdiv_qrnnd)
372 UWtype
373 __udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d)
375 UWtype q, r;
376 UWtype c0, c1, b1;
378 if ((Wtype) d >= 0)
380 if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1)))
382 /* dividend, divisor, and quotient are nonnegative */
383 sdiv_qrnnd (q, r, a1, a0, d);
385 else
387 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
388 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1));
389 /* Divide (c1*2^32 + c0) by d */
390 sdiv_qrnnd (q, r, c1, c0, d);
391 /* Add 2^31 to quotient */
392 q += (UWtype) 1 << (W_TYPE_SIZE - 1);
395 else
397 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
398 c1 = a1 >> 1; /* A/2 */
399 c0 = (a1 << (W_TYPE_SIZE - 1)) + (a0 >> 1);
401 if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
403 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
405 r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
406 if ((d & 1) != 0)
408 if (r >= q)
409 r = r - q;
410 else if (q - r <= d)
412 r = r - q + d;
413 q--;
415 else
417 r = r - q + 2*d;
418 q -= 2;
422 else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
424 c1 = (b1 - 1) - c1;
425 c0 = ~c0; /* logical NOT */
427 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
429 q = ~q; /* (A/2)/b1 */
430 r = (b1 - 1) - r;
432 r = 2*r + (a0 & 1); /* A/(2*b1) */
434 if ((d & 1) != 0)
436 if (r >= q)
437 r = r - q;
438 else if (q - r <= d)
440 r = r - q + d;
441 q--;
443 else
445 r = r - q + 2*d;
446 q -= 2;
450 else /* Implies c1 = b1 */
451 { /* Hence a1 = d - 1 = 2*b1 - 1 */
452 if (a0 >= -d)
454 q = -1;
455 r = a0 + d;
457 else
459 q = -2;
460 r = a0 + 2*d;
465 *rp = r;
466 return q;
468 #else
469 /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */
470 UWtype
471 __udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)),
472 UWtype a1 __attribute__ ((__unused__)),
473 UWtype a0 __attribute__ ((__unused__)),
474 UWtype d __attribute__ ((__unused__)))
476 return 0;
478 #endif
479 #endif
481 #if (defined (L_udivdi3) || defined (L_divdi3) || \
482 defined (L_umoddi3) || defined (L_moddi3))
483 #define L_udivmoddi4
484 #endif
486 #ifdef L_clz
487 const UQItype __clz_tab[] =
489 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,
490 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,
491 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,
492 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,
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,
495 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 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,
498 #endif
500 #ifdef L_udivmoddi4
502 #if (defined (L_udivdi3) || defined (L_divdi3) || \
503 defined (L_umoddi3) || defined (L_moddi3))
504 static inline
505 #endif
506 UDWtype
507 __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
509 DWunion ww;
510 DWunion nn, dd;
511 DWunion rr;
512 UWtype d0, d1, n0, n1, n2;
513 UWtype q0, q1;
514 UWtype b, bm;
516 nn.ll = n;
517 dd.ll = d;
519 d0 = dd.s.low;
520 d1 = dd.s.high;
521 n0 = nn.s.low;
522 n1 = nn.s.high;
524 #if !UDIV_NEEDS_NORMALIZATION
525 if (d1 == 0)
527 if (d0 > n1)
529 /* 0q = nn / 0D */
531 udiv_qrnnd (q0, n0, n1, n0, d0);
532 q1 = 0;
534 /* Remainder in n0. */
536 else
538 /* qq = NN / 0d */
540 if (d0 == 0)
541 d0 = 1 / d0; /* Divide intentionally by zero. */
543 udiv_qrnnd (q1, n1, 0, n1, d0);
544 udiv_qrnnd (q0, n0, n1, n0, d0);
546 /* Remainder in n0. */
549 if (rp != 0)
551 rr.s.low = n0;
552 rr.s.high = 0;
553 *rp = rr.ll;
557 #else /* UDIV_NEEDS_NORMALIZATION */
559 if (d1 == 0)
561 if (d0 > n1)
563 /* 0q = nn / 0D */
565 count_leading_zeros (bm, d0);
567 if (bm != 0)
569 /* Normalize, i.e. make the most significant bit of the
570 denominator set. */
572 d0 = d0 << bm;
573 n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
574 n0 = n0 << bm;
577 udiv_qrnnd (q0, n0, n1, n0, d0);
578 q1 = 0;
580 /* Remainder in n0 >> bm. */
582 else
584 /* qq = NN / 0d */
586 if (d0 == 0)
587 d0 = 1 / d0; /* Divide intentionally by zero. */
589 count_leading_zeros (bm, d0);
591 if (bm == 0)
593 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
594 conclude (the most significant bit of n1 is set) /\ (the
595 leading quotient digit q1 = 1).
597 This special case is necessary, not an optimization.
598 (Shifts counts of W_TYPE_SIZE are undefined.) */
600 n1 -= d0;
601 q1 = 1;
603 else
605 /* Normalize. */
607 b = W_TYPE_SIZE - bm;
609 d0 = d0 << bm;
610 n2 = n1 >> b;
611 n1 = (n1 << bm) | (n0 >> b);
612 n0 = n0 << bm;
614 udiv_qrnnd (q1, n1, n2, n1, d0);
617 /* n1 != d0... */
619 udiv_qrnnd (q0, n0, n1, n0, d0);
621 /* Remainder in n0 >> bm. */
624 if (rp != 0)
626 rr.s.low = n0 >> bm;
627 rr.s.high = 0;
628 *rp = rr.ll;
631 #endif /* UDIV_NEEDS_NORMALIZATION */
633 else
635 if (d1 > n1)
637 /* 00 = nn / DD */
639 q0 = 0;
640 q1 = 0;
642 /* Remainder in n1n0. */
643 if (rp != 0)
645 rr.s.low = n0;
646 rr.s.high = n1;
647 *rp = rr.ll;
650 else
652 /* 0q = NN / dd */
654 count_leading_zeros (bm, d1);
655 if (bm == 0)
657 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
658 conclude (the most significant bit of n1 is set) /\ (the
659 quotient digit q0 = 0 or 1).
661 This special case is necessary, not an optimization. */
663 /* The condition on the next line takes advantage of that
664 n1 >= d1 (true due to program flow). */
665 if (n1 > d1 || n0 >= d0)
667 q0 = 1;
668 sub_ddmmss (n1, n0, n1, n0, d1, d0);
670 else
671 q0 = 0;
673 q1 = 0;
675 if (rp != 0)
677 rr.s.low = n0;
678 rr.s.high = n1;
679 *rp = rr.ll;
682 else
684 UWtype m1, m0;
685 /* Normalize. */
687 b = W_TYPE_SIZE - bm;
689 d1 = (d1 << bm) | (d0 >> b);
690 d0 = d0 << bm;
691 n2 = n1 >> b;
692 n1 = (n1 << bm) | (n0 >> b);
693 n0 = n0 << bm;
695 udiv_qrnnd (q0, n1, n2, n1, d1);
696 umul_ppmm (m1, m0, q0, d0);
698 if (m1 > n1 || (m1 == n1 && m0 > n0))
700 q0--;
701 sub_ddmmss (m1, m0, m1, m0, d1, d0);
704 q1 = 0;
706 /* Remainder in (n1n0 - m1m0) >> bm. */
707 if (rp != 0)
709 sub_ddmmss (n1, n0, n1, n0, m1, m0);
710 rr.s.low = (n1 << b) | (n0 >> bm);
711 rr.s.high = n1 >> bm;
712 *rp = rr.ll;
718 ww.s.low = q0;
719 ww.s.high = q1;
720 return ww.ll;
722 #endif
724 #ifdef L_divdi3
725 DWtype
726 __divdi3 (DWtype u, DWtype v)
728 word_type c = 0;
729 DWunion uu, vv;
730 DWtype w;
732 uu.ll = u;
733 vv.ll = v;
735 if (uu.s.high < 0)
736 c = ~c,
737 uu.ll = __negdi2 (uu.ll);
738 if (vv.s.high < 0)
739 c = ~c,
740 vv.ll = __negdi2 (vv.ll);
742 w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
743 if (c)
744 w = __negdi2 (w);
746 return w;
748 #endif
750 #ifdef L_moddi3
751 DWtype
752 __moddi3 (DWtype u, DWtype v)
754 word_type c = 0;
755 DWunion uu, vv;
756 DWtype w;
758 uu.ll = u;
759 vv.ll = v;
761 if (uu.s.high < 0)
762 c = ~c,
763 uu.ll = __negdi2 (uu.ll);
764 if (vv.s.high < 0)
765 vv.ll = __negdi2 (vv.ll);
767 (void) __udivmoddi4 (uu.ll, vv.ll, &w);
768 if (c)
769 w = __negdi2 (w);
771 return w;
773 #endif
775 #ifdef L_umoddi3
776 UDWtype
777 __umoddi3 (UDWtype u, UDWtype v)
779 UDWtype w;
781 (void) __udivmoddi4 (u, v, &w);
783 return w;
785 #endif
787 #ifdef L_udivdi3
788 UDWtype
789 __udivdi3 (UDWtype n, UDWtype d)
791 return __udivmoddi4 (n, d, (UDWtype *) 0);
793 #endif
795 #ifdef L_cmpdi2
796 word_type
797 __cmpdi2 (DWtype a, DWtype b)
799 DWunion au, bu;
801 au.ll = a, bu.ll = b;
803 if (au.s.high < bu.s.high)
804 return 0;
805 else if (au.s.high > bu.s.high)
806 return 2;
807 if ((UWtype) au.s.low < (UWtype) bu.s.low)
808 return 0;
809 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
810 return 2;
811 return 1;
813 #endif
815 #ifdef L_ucmpdi2
816 word_type
817 __ucmpdi2 (DWtype a, DWtype b)
819 DWunion au, bu;
821 au.ll = a, bu.ll = b;
823 if ((UWtype) au.s.high < (UWtype) bu.s.high)
824 return 0;
825 else if ((UWtype) au.s.high > (UWtype) bu.s.high)
826 return 2;
827 if ((UWtype) au.s.low < (UWtype) bu.s.low)
828 return 0;
829 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
830 return 2;
831 return 1;
833 #endif
835 #if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
836 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
837 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
839 DWtype
840 __fixunstfDI (TFtype a)
842 TFtype b;
843 UDWtype v;
845 if (a < 0)
846 return 0;
848 /* Compute high word of result, as a flonum. */
849 b = (a / HIGH_WORD_COEFF);
850 /* Convert that to fixed (but not to DWtype!),
851 and shift it into the high word. */
852 v = (UWtype) b;
853 v <<= WORD_SIZE;
854 /* Remove high part from the TFtype, leaving the low part as flonum. */
855 a -= (TFtype)v;
856 /* Convert that to fixed (but not to DWtype!) and add it in.
857 Sometimes A comes out negative. This is significant, since
858 A has more bits than a long int does. */
859 if (a < 0)
860 v -= (UWtype) (- a);
861 else
862 v += (UWtype) a;
863 return v;
865 #endif
867 #if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
868 DWtype
869 __fixtfdi (TFtype a)
871 if (a < 0)
872 return - __fixunstfDI (-a);
873 return __fixunstfDI (a);
875 #endif
877 #if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
878 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
879 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
881 DWtype
882 __fixunsxfDI (XFtype a)
884 XFtype b;
885 UDWtype v;
887 if (a < 0)
888 return 0;
890 /* Compute high word of result, as a flonum. */
891 b = (a / HIGH_WORD_COEFF);
892 /* Convert that to fixed (but not to DWtype!),
893 and shift it into the high word. */
894 v = (UWtype) b;
895 v <<= WORD_SIZE;
896 /* Remove high part from the XFtype, leaving the low part as flonum. */
897 a -= (XFtype)v;
898 /* Convert that to fixed (but not to DWtype!) and add it in.
899 Sometimes A comes out negative. This is significant, since
900 A has more bits than a long int does. */
901 if (a < 0)
902 v -= (UWtype) (- a);
903 else
904 v += (UWtype) a;
905 return v;
907 #endif
909 #if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
910 DWtype
911 __fixxfdi (XFtype a)
913 if (a < 0)
914 return - __fixunsxfDI (-a);
915 return __fixunsxfDI (a);
917 #endif
919 #ifdef L_fixunsdfdi
920 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
921 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
923 DWtype
924 __fixunsdfDI (DFtype a)
926 DFtype b;
927 UDWtype v;
929 if (a < 0)
930 return 0;
932 /* Compute high word of result, as a flonum. */
933 b = (a / HIGH_WORD_COEFF);
934 /* Convert that to fixed (but not to DWtype!),
935 and shift it into the high word. */
936 v = (UWtype) b;
937 v <<= WORD_SIZE;
938 /* Remove high part from the DFtype, leaving the low part as flonum. */
939 a -= (DFtype)v;
940 /* Convert that to fixed (but not to DWtype!) and add it in.
941 Sometimes A comes out negative. This is significant, since
942 A has more bits than a long int does. */
943 if (a < 0)
944 v -= (UWtype) (- a);
945 else
946 v += (UWtype) a;
947 return v;
949 #endif
951 #ifdef L_fixdfdi
952 DWtype
953 __fixdfdi (DFtype a)
955 if (a < 0)
956 return - __fixunsdfDI (-a);
957 return __fixunsdfDI (a);
959 #endif
961 #ifdef L_fixunssfdi
962 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
963 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
965 DWtype
966 __fixunssfDI (SFtype original_a)
968 /* Convert the SFtype to a DFtype, because that is surely not going
969 to lose any bits. Some day someone else can write a faster version
970 that avoids converting to DFtype, and verify it really works right. */
971 DFtype a = original_a;
972 DFtype b;
973 UDWtype v;
975 if (a < 0)
976 return 0;
978 /* Compute high word of result, as a flonum. */
979 b = (a / HIGH_WORD_COEFF);
980 /* Convert that to fixed (but not to DWtype!),
981 and shift it into the high word. */
982 v = (UWtype) b;
983 v <<= WORD_SIZE;
984 /* Remove high part from the DFtype, leaving the low part as flonum. */
985 a -= (DFtype) v;
986 /* Convert that to fixed (but not to DWtype!) and add it in.
987 Sometimes A comes out negative. This is significant, since
988 A has more bits than a long int does. */
989 if (a < 0)
990 v -= (UWtype) (- a);
991 else
992 v += (UWtype) a;
993 return v;
995 #endif
997 #ifdef L_fixsfdi
998 DWtype
999 __fixsfdi (SFtype a)
1001 if (a < 0)
1002 return - __fixunssfDI (-a);
1003 return __fixunssfDI (a);
1005 #endif
1007 #if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
1008 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1009 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1010 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1012 XFtype
1013 __floatdixf (DWtype u)
1015 XFtype d;
1017 d = (Wtype) (u >> WORD_SIZE);
1018 d *= HIGH_HALFWORD_COEFF;
1019 d *= HIGH_HALFWORD_COEFF;
1020 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1022 return d;
1024 #endif
1026 #if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
1027 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1028 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1029 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1031 TFtype
1032 __floatditf (DWtype u)
1034 TFtype d;
1036 d = (Wtype) (u >> WORD_SIZE);
1037 d *= HIGH_HALFWORD_COEFF;
1038 d *= HIGH_HALFWORD_COEFF;
1039 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1041 return d;
1043 #endif
1045 #ifdef L_floatdidf
1046 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1047 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1048 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1050 DFtype
1051 __floatdidf (DWtype u)
1053 DFtype d;
1055 d = (Wtype) (u >> WORD_SIZE);
1056 d *= HIGH_HALFWORD_COEFF;
1057 d *= HIGH_HALFWORD_COEFF;
1058 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1060 return d;
1062 #endif
1064 #ifdef L_floatdisf
1065 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1066 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1067 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1069 #define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT)
1070 #define DF_SIZE DBL_MANT_DIG
1071 #define SF_SIZE FLT_MANT_DIG
1073 SFtype
1074 __floatdisf (DWtype u)
1076 /* Do the calculation in DFmode
1077 so that we don't lose any of the precision of the high word
1078 while multiplying it. */
1079 DFtype f;
1081 /* Protect against double-rounding error.
1082 Represent any low-order bits, that might be truncated in DFmode,
1083 by a bit that won't be lost. The bit can go in anywhere below the
1084 rounding position of the SFmode. A fixed mask and bit position
1085 handles all usual configurations. It doesn't handle the case
1086 of 128-bit DImode, however. */
1087 if (DF_SIZE < DI_SIZE
1088 && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1090 #define REP_BIT ((UDWtype) 1 << (DI_SIZE - DF_SIZE))
1091 if (! (- ((DWtype) 1 << DF_SIZE) < u
1092 && u < ((DWtype) 1 << DF_SIZE)))
1094 if ((UDWtype) u & (REP_BIT - 1))
1095 u |= REP_BIT;
1098 f = (Wtype) (u >> WORD_SIZE);
1099 f *= HIGH_HALFWORD_COEFF;
1100 f *= HIGH_HALFWORD_COEFF;
1101 f += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1103 return (SFtype) f;
1105 #endif
1107 #if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
1108 /* Reenable the normal types, in case limits.h needs them. */
1109 #undef char
1110 #undef short
1111 #undef int
1112 #undef long
1113 #undef unsigned
1114 #undef float
1115 #undef double
1116 #undef MIN
1117 #undef MAX
1118 #include <limits.h>
1120 UWtype
1121 __fixunsxfSI (XFtype a)
1123 if (a >= - (DFtype) Wtype_MIN)
1124 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1125 return (Wtype) a;
1127 #endif
1129 #ifdef L_fixunsdfsi
1130 /* Reenable the normal types, in case limits.h needs them. */
1131 #undef char
1132 #undef short
1133 #undef int
1134 #undef long
1135 #undef unsigned
1136 #undef float
1137 #undef double
1138 #undef MIN
1139 #undef MAX
1140 #include <limits.h>
1142 UWtype
1143 __fixunsdfSI (DFtype a)
1145 if (a >= - (DFtype) Wtype_MIN)
1146 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1147 return (Wtype) a;
1149 #endif
1151 #ifdef L_fixunssfsi
1152 /* Reenable the normal types, in case limits.h needs them. */
1153 #undef char
1154 #undef short
1155 #undef int
1156 #undef long
1157 #undef unsigned
1158 #undef float
1159 #undef double
1160 #undef MIN
1161 #undef MAX
1162 #include <limits.h>
1164 UWtype
1165 __fixunssfSI (SFtype a)
1167 if (a >= - (SFtype) Wtype_MIN)
1168 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1169 return (Wtype) a;
1171 #endif
1173 /* From here on down, the routines use normal data types. */
1175 #define SItype bogus_type
1176 #define USItype bogus_type
1177 #define DItype bogus_type
1178 #define UDItype bogus_type
1179 #define SFtype bogus_type
1180 #define DFtype bogus_type
1181 #undef Wtype
1182 #undef UWtype
1183 #undef HWtype
1184 #undef UHWtype
1185 #undef DWtype
1186 #undef UDWtype
1188 #undef char
1189 #undef short
1190 #undef int
1191 #undef long
1192 #undef unsigned
1193 #undef float
1194 #undef double
1196 #ifdef L__gcc_bcmp
1198 /* Like bcmp except the sign is meaningful.
1199 Result is negative if S1 is less than S2,
1200 positive if S1 is greater, 0 if S1 and S2 are equal. */
1203 __gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
1205 while (size > 0)
1207 unsigned char c1 = *s1++, c2 = *s2++;
1208 if (c1 != c2)
1209 return c1 - c2;
1210 size--;
1212 return 0;
1215 #endif
1217 /* __eprintf used to be used by GCC's private version of <assert.h>.
1218 We no longer provide that header, but this routine remains in libgcc.a
1219 for binary backward compatibility. Note that it is not included in
1220 the shared version of libgcc. */
1221 #ifdef L_eprintf
1222 #ifndef inhibit_libc
1224 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1225 #include <stdio.h>
1227 void
1228 __eprintf (const char *string, const char *expression,
1229 unsigned int line, const char *filename)
1231 fprintf (stderr, string, expression, line, filename);
1232 fflush (stderr);
1233 abort ();
1236 #endif
1237 #endif
1239 #ifdef L_bb
1241 struct bb_function_info {
1242 long checksum;
1243 int arc_count;
1244 const char *name;
1247 /* Structure emitted by -a */
1248 struct bb
1250 long zero_word;
1251 const char *filename;
1252 gcov_type *counts;
1253 long ncounts;
1254 struct bb *next;
1256 /* Older GCC's did not emit these fields. */
1257 long sizeof_bb;
1258 struct bb_function_info *function_infos;
1261 #ifndef inhibit_libc
1263 /* Simple minded basic block profiling output dumper for
1264 systems that don't provide tcov support. At present,
1265 it requires atexit and stdio. */
1267 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1268 #include <stdio.h>
1270 #include "gbl-ctors.h"
1271 #include "gcov-io.h"
1272 #include <string.h>
1273 #ifdef TARGET_HAS_F_SETLKW
1274 #include <fcntl.h>
1275 #include <errno.h>
1276 #endif
1278 #include <gthr.h>
1280 static struct bb *bb_head;
1282 int __global_counters = 0, __gthreads_active = 0;
1284 void
1285 __bb_exit_func (void)
1287 FILE *da_file;
1288 struct bb *ptr;
1289 long n_counters_p = 0;
1290 gcov_type max_counter_p = 0;
1291 gcov_type sum_counters_p = 0;
1293 if (bb_head == 0)
1294 return;
1296 /* Calculate overall "statistics". */
1298 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1300 int i;
1302 n_counters_p += ptr->ncounts;
1304 for (i = 0; i < ptr->ncounts; i++)
1306 sum_counters_p += ptr->counts[i];
1308 if (ptr->counts[i] > max_counter_p)
1309 max_counter_p = ptr->counts[i];
1313 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1315 gcov_type max_counter_o = 0;
1316 gcov_type sum_counters_o = 0;
1317 int i;
1319 /* Calculate the per-object statistics. */
1321 for (i = 0; i < ptr->ncounts; i++)
1323 sum_counters_o += ptr->counts[i];
1325 if (ptr->counts[i] > max_counter_o)
1326 max_counter_o = ptr->counts[i];
1329 /* open the file for appending, creating it if necessary. */
1330 da_file = fopen (ptr->filename, "ab");
1331 /* Some old systems might not allow the 'b' mode modifier.
1332 Therefore, try to open without it. This can lead to a race
1333 condition so that when you delete and re-create the file, the
1334 file might be opened in text mode, but then, you shouldn't
1335 delete the file in the first place. */
1336 if (da_file == 0)
1337 da_file = fopen (ptr->filename, "a");
1338 if (da_file == 0)
1340 fprintf (stderr, "arc profiling: Can't open output file %s.\n",
1341 ptr->filename);
1342 continue;
1345 /* After a fork, another process might try to read and/or write
1346 the same file simultanously. So if we can, lock the file to
1347 avoid race conditions. */
1348 #if defined (TARGET_HAS_F_SETLKW)
1350 struct flock s_flock;
1352 s_flock.l_type = F_WRLCK;
1353 s_flock.l_whence = SEEK_SET;
1354 s_flock.l_start = 0;
1355 s_flock.l_len = 1;
1356 s_flock.l_pid = getpid ();
1358 while (fcntl (fileno (da_file), F_SETLKW, &s_flock)
1359 && errno == EINTR);
1361 #endif
1363 if (__write_long (-123, da_file, 4) != 0) /* magic */
1365 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1366 ptr->filename);
1368 else
1371 struct bb_function_info *fn_info;
1372 gcov_type *count_ptr = ptr->counts;
1373 int i;
1374 int count_functions = 0;
1376 for (fn_info = ptr->function_infos; fn_info->arc_count != -1;
1377 fn_info++)
1378 count_functions++;
1380 /* number of functions in this block. */
1381 __write_long (count_functions, da_file, 4);
1383 /* length of extra data in bytes. */
1384 __write_long ((4 + 8 + 8) + (4 + 8 + 8), da_file, 4);
1386 /* overall statistics. */
1387 /* number of counters. */
1388 __write_long (n_counters_p, da_file, 4);
1389 /* sum of counters. */
1390 __write_gcov_type (sum_counters_p, da_file, 8);
1391 /* maximal counter. */
1392 __write_gcov_type (max_counter_p, da_file, 8);
1394 /* per-object statistics. */
1395 /* number of counters. */
1396 __write_long (ptr->ncounts, da_file, 4);
1397 /* sum of counters. */
1398 __write_gcov_type (sum_counters_o, da_file, 8);
1399 /* maximal counter. */
1400 __write_gcov_type (max_counter_o, da_file, 8);
1402 /* write execution counts for each function. */
1404 for (fn_info = ptr->function_infos; fn_info->arc_count != -1;
1405 fn_info++)
1407 /* new function. */
1408 if (__write_gcov_string
1409 (fn_info->name, strlen (fn_info->name), da_file, -1) != 0)
1411 fprintf (stderr,
1412 "arc profiling: Error writing output file %s.\n",
1413 ptr->filename);
1414 break;
1417 if (__write_long (fn_info->checksum, da_file, 4) != 0)
1419 fprintf (stderr,
1420 "arc profiling: Error writing output file %s.\n",
1421 ptr->filename);
1422 break;
1425 if (__write_long (fn_info->arc_count, da_file, 4) != 0)
1427 fprintf (stderr,
1428 "arc profiling: Error writing output file %s.\n",
1429 ptr->filename);
1430 break;
1433 for (i = fn_info->arc_count; i > 0; i--, count_ptr++)
1435 if (__write_gcov_type (*count_ptr, da_file, 8) != 0)
1436 break;
1439 if (i) /* there was an error */
1441 fprintf (stderr,
1442 "arc profiling: Error writing output file %s.\n",
1443 ptr->filename);
1444 break;
1449 if (fclose (da_file) != 0)
1450 fprintf (stderr, "arc profiling: Error closing output file %s.\n",
1451 ptr->filename);
1455 void
1456 __bb_init_func (struct bb *blocks)
1458 /* User is supposed to check whether the first word is non-0,
1459 but just in case.... */
1461 if (blocks->zero_word)
1462 return;
1464 /* Initialize destructor and per-thread data. */
1465 if (!bb_head)
1466 atexit (__bb_exit_func);
1468 /* Set up linked list. */
1469 blocks->zero_word = 1;
1470 blocks->next = bb_head;
1471 bb_head = blocks;
1474 /* Called before fork or exec - write out profile information gathered so
1475 far and reset it to zero. This avoids duplication or loss of the
1476 profile information gathered so far. */
1477 void
1478 __bb_fork_func (void)
1480 struct bb *ptr;
1482 __bb_exit_func ();
1483 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1485 long i;
1486 for (i = ptr->ncounts - 1; i >= 0; i--)
1487 ptr->counts[i] = 0;
1491 #endif /* not inhibit_libc */
1492 #endif /* L_bb */
1494 #ifdef L_clear_cache
1495 /* Clear part of an instruction cache. */
1497 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1499 void
1500 __clear_cache (char *beg __attribute__((__unused__)),
1501 char *end __attribute__((__unused__)))
1503 #ifdef CLEAR_INSN_CACHE
1504 CLEAR_INSN_CACHE (beg, end);
1505 #else
1506 #ifdef INSN_CACHE_SIZE
1507 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1508 static int initialized;
1509 int offset;
1510 void *start_addr
1511 void *end_addr;
1512 typedef (*function_ptr) (void);
1514 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1515 /* It's cheaper to clear the whole cache.
1516 Put in a series of jump instructions so that calling the beginning
1517 of the cache will clear the whole thing. */
1519 if (! initialized)
1521 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1522 & -INSN_CACHE_LINE_WIDTH);
1523 int end_ptr = ptr + INSN_CACHE_SIZE;
1525 while (ptr < end_ptr)
1527 *(INSTRUCTION_TYPE *)ptr
1528 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1529 ptr += INSN_CACHE_LINE_WIDTH;
1531 *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1533 initialized = 1;
1536 /* Call the beginning of the sequence. */
1537 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1538 & -INSN_CACHE_LINE_WIDTH))
1539 ());
1541 #else /* Cache is large. */
1543 if (! initialized)
1545 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1546 & -INSN_CACHE_LINE_WIDTH);
1548 while (ptr < (int) array + sizeof array)
1550 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1551 ptr += INSN_CACHE_LINE_WIDTH;
1554 initialized = 1;
1557 /* Find the location in array that occupies the same cache line as BEG. */
1559 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1560 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1561 & -INSN_CACHE_PLANE_SIZE)
1562 + offset);
1564 /* Compute the cache alignment of the place to stop clearing. */
1565 #if 0 /* This is not needed for gcc's purposes. */
1566 /* If the block to clear is bigger than a cache plane,
1567 we clear the entire cache, and OFFSET is already correct. */
1568 if (end < beg + INSN_CACHE_PLANE_SIZE)
1569 #endif
1570 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1571 & -INSN_CACHE_LINE_WIDTH)
1572 & (INSN_CACHE_PLANE_SIZE - 1));
1574 #if INSN_CACHE_DEPTH > 1
1575 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1576 if (end_addr <= start_addr)
1577 end_addr += INSN_CACHE_PLANE_SIZE;
1579 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1581 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1582 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1584 while (addr != stop)
1586 /* Call the return instruction at ADDR. */
1587 ((function_ptr) addr) ();
1589 addr += INSN_CACHE_LINE_WIDTH;
1592 #else /* just one plane */
1595 /* Call the return instruction at START_ADDR. */
1596 ((function_ptr) start_addr) ();
1598 start_addr += INSN_CACHE_LINE_WIDTH;
1600 while ((start_addr % INSN_CACHE_SIZE) != offset);
1601 #endif /* just one plane */
1602 #endif /* Cache is large */
1603 #endif /* Cache exists */
1604 #endif /* CLEAR_INSN_CACHE */
1607 #endif /* L_clear_cache */
1609 #ifdef L_trampoline
1611 /* Jump to a trampoline, loading the static chain address. */
1613 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
1615 long
1616 getpagesize (void)
1618 #ifdef _ALPHA_
1619 return 8192;
1620 #else
1621 return 4096;
1622 #endif
1625 #ifdef __i386__
1626 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
1627 #endif
1630 mprotect (char *addr, int len, int prot)
1632 int np, op;
1634 if (prot == 7)
1635 np = 0x40;
1636 else if (prot == 5)
1637 np = 0x20;
1638 else if (prot == 4)
1639 np = 0x10;
1640 else if (prot == 3)
1641 np = 0x04;
1642 else if (prot == 1)
1643 np = 0x02;
1644 else if (prot == 0)
1645 np = 0x01;
1647 if (VirtualProtect (addr, len, np, &op))
1648 return 0;
1649 else
1650 return -1;
1653 #endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
1655 #ifdef TRANSFER_FROM_TRAMPOLINE
1656 TRANSFER_FROM_TRAMPOLINE
1657 #endif
1659 #if defined (NeXT) && defined (__MACH__)
1661 /* Make stack executable so we can call trampolines on stack.
1662 This is called from INITIALIZE_TRAMPOLINE in next.h. */
1663 #ifdef NeXTStep21
1664 #include <mach.h>
1665 #else
1666 #include <mach/mach.h>
1667 #endif
1669 void
1670 __enable_execute_stack (char *addr)
1672 kern_return_t r;
1673 char *eaddr = addr + TRAMPOLINE_SIZE;
1674 vm_address_t a = (vm_address_t) addr;
1676 /* turn on execute access on stack */
1677 r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
1678 if (r != KERN_SUCCESS)
1680 mach_error("vm_protect VM_PROT_ALL", r);
1681 exit(1);
1684 /* We inline the i-cache invalidation for speed */
1686 #ifdef CLEAR_INSN_CACHE
1687 CLEAR_INSN_CACHE (addr, eaddr);
1688 #else
1689 __clear_cache ((int) addr, (int) eaddr);
1690 #endif
1693 #endif /* defined (NeXT) && defined (__MACH__) */
1695 #ifdef __convex__
1697 /* Make stack executable so we can call trampolines on stack.
1698 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
1700 #include <sys/mman.h>
1701 #include <sys/vmparam.h>
1702 #include <machine/machparam.h>
1704 void
1705 __enable_execute_stack (void)
1707 int fp;
1708 static unsigned lowest = USRSTACK;
1709 unsigned current = (unsigned) &fp & -NBPG;
1711 if (lowest > current)
1713 unsigned len = lowest - current;
1714 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
1715 lowest = current;
1718 /* Clear instruction cache in case an old trampoline is in it. */
1719 asm ("pich");
1721 #endif /* __convex__ */
1723 #ifdef __sysV88__
1725 /* Modified from the convex -code above. */
1727 #include <sys/param.h>
1728 #include <errno.h>
1729 #include <sys/m88kbcs.h>
1731 void
1732 __enable_execute_stack (void)
1734 int save_errno;
1735 static unsigned long lowest = USRSTACK;
1736 unsigned long current = (unsigned long) &save_errno & -NBPC;
1738 /* Ignore errno being set. memctl sets errno to EINVAL whenever the
1739 address is seen as 'negative'. That is the case with the stack. */
1741 save_errno=errno;
1742 if (lowest > current)
1744 unsigned len=lowest-current;
1745 memctl(current,len,MCT_TEXT);
1746 lowest = current;
1748 else
1749 memctl(current,NBPC,MCT_TEXT);
1750 errno=save_errno;
1753 #endif /* __sysV88__ */
1755 #ifdef __sysV68__
1757 #include <sys/signal.h>
1758 #include <errno.h>
1760 /* Motorola forgot to put memctl.o in the libp version of libc881.a,
1761 so define it here, because we need it in __clear_insn_cache below */
1762 /* On older versions of this OS, no memctl or MCT_TEXT are defined;
1763 hence we enable this stuff only if MCT_TEXT is #define'd. */
1765 #ifdef MCT_TEXT
1766 asm("\n\
1767 global memctl\n\
1768 memctl:\n\
1769 movq &75,%d0\n\
1770 trap &0\n\
1771 bcc.b noerror\n\
1772 jmp cerror%\n\
1773 noerror:\n\
1774 movq &0,%d0\n\
1775 rts");
1776 #endif
1778 /* Clear instruction cache so we can call trampolines on stack.
1779 This is called from FINALIZE_TRAMPOLINE in mot3300.h. */
1781 void
1782 __clear_insn_cache (void)
1784 #ifdef MCT_TEXT
1785 int save_errno;
1787 /* Preserve errno, because users would be surprised to have
1788 errno changing without explicitly calling any system-call. */
1789 save_errno = errno;
1791 /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache.
1792 No need to use an address derived from _start or %sp, as 0 works also. */
1793 memctl(0, 4096, MCT_TEXT);
1794 errno = save_errno;
1795 #endif
1798 #endif /* __sysV68__ */
1800 #ifdef __pyr__
1802 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1803 #include <stdio.h>
1804 #include <sys/mman.h>
1805 #include <sys/types.h>
1806 #include <sys/param.h>
1807 #include <sys/vmmac.h>
1809 /* Modified from the convex -code above.
1810 mremap promises to clear the i-cache. */
1812 void
1813 __enable_execute_stack (void)
1815 int fp;
1816 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
1817 PROT_READ|PROT_WRITE|PROT_EXEC))
1819 perror ("mprotect in __enable_execute_stack");
1820 fflush (stderr);
1821 abort ();
1824 #endif /* __pyr__ */
1826 #if defined (sony_news) && defined (SYSTYPE_BSD)
1828 #include <stdio.h>
1829 #include <sys/types.h>
1830 #include <sys/param.h>
1831 #include <syscall.h>
1832 #include <machine/sysnews.h>
1834 /* cacheflush function for NEWS-OS 4.2.
1835 This function is called from trampoline-initialize code
1836 defined in config/mips/mips.h. */
1838 void
1839 cacheflush (char *beg, int size, int flag)
1841 if (syscall (SYS_sysnews, NEWS_CACHEFLUSH, beg, size, FLUSH_BCACHE))
1843 perror ("cache_flush");
1844 fflush (stderr);
1845 abort ();
1849 #endif /* sony_news */
1850 #endif /* L_trampoline */
1852 #ifndef __CYGWIN__
1853 #ifdef L__main
1855 #include "gbl-ctors.h"
1856 /* Some systems use __main in a way incompatible with its use in gcc, in these
1857 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
1858 give the same symbol without quotes for an alternative entry point. You
1859 must define both, or neither. */
1860 #ifndef NAME__MAIN
1861 #define NAME__MAIN "__main"
1862 #define SYMBOL__MAIN __main
1863 #endif
1865 #ifdef INIT_SECTION_ASM_OP
1866 #undef HAS_INIT_SECTION
1867 #define HAS_INIT_SECTION
1868 #endif
1870 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
1872 /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
1873 code to run constructors. In that case, we need to handle EH here, too. */
1875 #ifdef EH_FRAME_SECTION_NAME
1876 #include "unwind-dw2-fde.h"
1877 extern unsigned char __EH_FRAME_BEGIN__[];
1878 #endif
1880 /* Run all the global destructors on exit from the program. */
1882 void
1883 __do_global_dtors (void)
1885 #ifdef DO_GLOBAL_DTORS_BODY
1886 DO_GLOBAL_DTORS_BODY;
1887 #else
1888 static func_ptr *p = __DTOR_LIST__ + 1;
1889 while (*p)
1891 p++;
1892 (*(p-1)) ();
1894 #endif
1895 #if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION)
1897 static int completed = 0;
1898 if (! completed)
1900 completed = 1;
1901 __deregister_frame_info (__EH_FRAME_BEGIN__);
1904 #endif
1906 #endif
1908 #ifndef HAS_INIT_SECTION
1909 /* Run all the global constructors on entry to the program. */
1911 void
1912 __do_global_ctors (void)
1914 #ifdef EH_FRAME_SECTION_NAME
1916 static struct object object;
1917 __register_frame_info (__EH_FRAME_BEGIN__, &object);
1919 #endif
1920 DO_GLOBAL_CTORS_BODY;
1921 atexit (__do_global_dtors);
1923 #endif /* no HAS_INIT_SECTION */
1925 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
1926 /* Subroutine called automatically by `main'.
1927 Compiling a global function named `main'
1928 produces an automatic call to this function at the beginning.
1930 For many systems, this routine calls __do_global_ctors.
1931 For systems which support a .init section we use the .init section
1932 to run __do_global_ctors, so we need not do anything here. */
1934 void
1935 SYMBOL__MAIN ()
1937 /* Support recursive calls to `main': run initializers just once. */
1938 static int initialized;
1939 if (! initialized)
1941 initialized = 1;
1942 __do_global_ctors ();
1945 #endif /* no HAS_INIT_SECTION or INVOKE__main */
1947 #endif /* L__main */
1948 #endif /* __CYGWIN__ */
1950 #ifdef L_ctors
1952 #include "gbl-ctors.h"
1954 /* Provide default definitions for the lists of constructors and
1955 destructors, so that we don't get linker errors. These symbols are
1956 intentionally bss symbols, so that gld and/or collect will provide
1957 the right values. */
1959 /* We declare the lists here with two elements each,
1960 so that they are valid empty lists if no other definition is loaded.
1962 If we are using the old "set" extensions to have the gnu linker
1963 collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
1964 must be in the bss/common section.
1966 Long term no port should use those extensions. But many still do. */
1967 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
1968 #if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2)
1969 func_ptr __CTOR_LIST__[2] = {0, 0};
1970 func_ptr __DTOR_LIST__[2] = {0, 0};
1971 #else
1972 func_ptr __CTOR_LIST__[2];
1973 func_ptr __DTOR_LIST__[2];
1974 #endif
1975 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1976 #endif /* L_ctors */
1978 #ifdef L_exit
1980 #include "gbl-ctors.h"
1982 #ifdef NEED_ATEXIT
1984 #ifndef ON_EXIT
1986 # include <errno.h>
1988 static func_ptr *atexit_chain = 0;
1989 static long atexit_chain_length = 0;
1990 static volatile long last_atexit_chain_slot = -1;
1993 atexit (func_ptr func)
1995 if (++last_atexit_chain_slot == atexit_chain_length)
1997 atexit_chain_length += 32;
1998 if (atexit_chain)
1999 atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
2000 * sizeof (func_ptr));
2001 else
2002 atexit_chain = (func_ptr *) malloc (atexit_chain_length
2003 * sizeof (func_ptr));
2004 if (! atexit_chain)
2006 atexit_chain_length = 0;
2007 last_atexit_chain_slot = -1;
2008 errno = ENOMEM;
2009 return (-1);
2012 atexit_chain[last_atexit_chain_slot] = func;
2013 return (0);
2016 extern void _cleanup (void);
2017 extern void _exit (int) __attribute__ ((__noreturn__));
2019 void
2020 exit (int status)
2022 if (atexit_chain)
2024 for ( ; last_atexit_chain_slot-- >= 0; )
2026 (*atexit_chain[last_atexit_chain_slot + 1]) ();
2027 atexit_chain[last_atexit_chain_slot + 1] = 0;
2029 free (atexit_chain);
2030 atexit_chain = 0;
2032 #ifdef EXIT_BODY
2033 EXIT_BODY;
2034 #else
2035 _cleanup ();
2036 #endif
2037 _exit (status);
2040 #else /* ON_EXIT */
2042 /* Simple; we just need a wrapper for ON_EXIT. */
2044 atexit (func_ptr func)
2046 return ON_EXIT (func);
2049 #endif /* ON_EXIT */
2050 #endif /* NEED_ATEXIT */
2052 #endif /* L_exit */