* config/rs6000/rs6000.c (spe_init_builtins,
[official-gcc.git] / gcc / libgcc2.c
blob46b2f9c8c27ee1828b5b3f34ef5f83283bb15824
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 #ifdef DECLARE_LIBRARY_RENAMES
47 DECLARE_LIBRARY_RENAMES
48 #endif
50 #if defined (L_negdi2)
51 DWtype
52 __negdi2 (DWtype u)
54 DWunion w;
55 DWunion uu;
57 uu.ll = u;
59 w.s.low = -uu.s.low;
60 w.s.high = -uu.s.high - ((UWtype) w.s.low > 0);
62 return w.ll;
64 #endif
66 #ifdef L_addvsi3
67 Wtype
68 __addvsi3 (Wtype a, Wtype b)
70 Wtype w;
72 w = a + b;
74 if (b >= 0 ? w < a : w > a)
75 abort ();
77 return w;
79 #endif
81 #ifdef L_addvdi3
82 DWtype
83 __addvdi3 (DWtype a, DWtype b)
85 DWtype w;
87 w = a + b;
89 if (b >= 0 ? w < a : w > a)
90 abort ();
92 return w;
94 #endif
96 #ifdef L_subvsi3
97 Wtype
98 __subvsi3 (Wtype a, Wtype b)
100 #ifdef L_addvsi3
101 return __addvsi3 (a, (-b));
102 #else
103 DWtype w;
105 w = a - b;
107 if (b >= 0 ? w > a : w < a)
108 abort ();
110 return w;
111 #endif
113 #endif
115 #ifdef L_subvdi3
116 DWtype
117 __subvdi3 (DWtype a, DWtype b)
119 #ifdef L_addvdi3
120 return (a, (-b));
121 #else
122 DWtype w;
124 w = a - b;
126 if (b >= 0 ? w > a : w < a)
127 abort ();
129 return w;
130 #endif
132 #endif
134 #ifdef L_mulvsi3
135 Wtype
136 __mulvsi3 (Wtype a, Wtype b)
138 DWtype w;
140 w = a * b;
142 if (((a >= 0) == (b >= 0)) ? w < 0 : w > 0)
143 abort ();
145 return w;
147 #endif
149 #ifdef L_negvsi2
150 Wtype
151 __negvsi2 (Wtype a)
153 Wtype w;
155 w = -a;
157 if (a >= 0 ? w > 0 : w < 0)
158 abort ();
160 return w;
162 #endif
164 #ifdef L_negvdi2
165 DWtype
166 __negvdi2 (DWtype a)
168 DWtype w;
170 w = -a;
172 if (a >= 0 ? w > 0 : w < 0)
173 abort ();
175 return w;
177 #endif
179 #ifdef L_absvsi2
180 Wtype
181 __absvsi2 (Wtype a)
183 Wtype w = a;
185 if (a < 0)
186 #ifdef L_negvsi2
187 w = __negvsi2 (a);
188 #else
189 w = -a;
191 if (w < 0)
192 abort ();
193 #endif
195 return w;
197 #endif
199 #ifdef L_absvdi2
200 DWtype
201 __absvdi2 (DWtype a)
203 DWtype w = a;
205 if (a < 0)
206 #ifdef L_negvsi2
207 w = __negvsi2 (a);
208 #else
209 w = -a;
211 if (w < 0)
212 abort ();
213 #endif
215 return w;
217 #endif
219 #ifdef L_mulvdi3
220 DWtype
221 __mulvdi3 (DWtype u, DWtype v)
223 DWtype w;
225 w = u * v;
227 if (((u >= 0) == (v >= 0)) ? w < 0 : w > 0)
228 abort ();
230 return w;
232 #endif
235 /* Unless shift functions are defined whith full ANSI prototypes,
236 parameter b will be promoted to int if word_type is smaller than an int. */
237 #ifdef L_lshrdi3
238 DWtype
239 __lshrdi3 (DWtype u, word_type b)
241 DWunion w;
242 word_type bm;
243 DWunion uu;
245 if (b == 0)
246 return u;
248 uu.ll = u;
250 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
251 if (bm <= 0)
253 w.s.high = 0;
254 w.s.low = (UWtype) uu.s.high >> -bm;
256 else
258 UWtype carries = (UWtype) uu.s.high << bm;
260 w.s.high = (UWtype) uu.s.high >> b;
261 w.s.low = ((UWtype) uu.s.low >> b) | carries;
264 return w.ll;
266 #endif
268 #ifdef L_ashldi3
269 DWtype
270 __ashldi3 (DWtype u, word_type b)
272 DWunion w;
273 word_type bm;
274 DWunion uu;
276 if (b == 0)
277 return u;
279 uu.ll = u;
281 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
282 if (bm <= 0)
284 w.s.low = 0;
285 w.s.high = (UWtype) uu.s.low << -bm;
287 else
289 UWtype carries = (UWtype) uu.s.low >> bm;
291 w.s.low = (UWtype) uu.s.low << b;
292 w.s.high = ((UWtype) uu.s.high << b) | carries;
295 return w.ll;
297 #endif
299 #ifdef L_ashrdi3
300 DWtype
301 __ashrdi3 (DWtype u, word_type b)
303 DWunion w;
304 word_type bm;
305 DWunion uu;
307 if (b == 0)
308 return u;
310 uu.ll = u;
312 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
313 if (bm <= 0)
315 /* w.s.high = 1..1 or 0..0 */
316 w.s.high = uu.s.high >> (sizeof (Wtype) * BITS_PER_UNIT - 1);
317 w.s.low = uu.s.high >> -bm;
319 else
321 UWtype carries = (UWtype) uu.s.high << bm;
323 w.s.high = uu.s.high >> b;
324 w.s.low = ((UWtype) uu.s.low >> b) | carries;
327 return w.ll;
329 #endif
331 #ifdef L_ffsdi2
332 DWtype
333 __ffsdi2 (DWtype u)
335 DWunion uu;
336 UWtype word, count, add;
338 uu.ll = u;
339 if (uu.s.low != 0)
340 word = uu.s.low, add = 0;
341 else if (uu.s.high != 0)
342 word = uu.s.high, add = BITS_PER_UNIT * sizeof (Wtype);
343 else
344 return 0;
346 count_trailing_zeros (count, word);
347 return count + add + 1;
349 #endif
351 #ifdef L_muldi3
352 DWtype
353 __muldi3 (DWtype u, DWtype v)
355 DWunion w;
356 DWunion uu, vv;
358 uu.ll = u,
359 vv.ll = v;
361 w.ll = __umulsidi3 (uu.s.low, vv.s.low);
362 w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
363 + (UWtype) uu.s.high * (UWtype) vv.s.low);
365 return w.ll;
367 #endif
369 #ifdef L_udiv_w_sdiv
370 #if defined (sdiv_qrnnd)
371 UWtype
372 __udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d)
374 UWtype q, r;
375 UWtype c0, c1, b1;
377 if ((Wtype) d >= 0)
379 if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1)))
381 /* dividend, divisor, and quotient are nonnegative */
382 sdiv_qrnnd (q, r, a1, a0, d);
384 else
386 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
387 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1));
388 /* Divide (c1*2^32 + c0) by d */
389 sdiv_qrnnd (q, r, c1, c0, d);
390 /* Add 2^31 to quotient */
391 q += (UWtype) 1 << (W_TYPE_SIZE - 1);
394 else
396 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
397 c1 = a1 >> 1; /* A/2 */
398 c0 = (a1 << (W_TYPE_SIZE - 1)) + (a0 >> 1);
400 if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
402 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
404 r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
405 if ((d & 1) != 0)
407 if (r >= q)
408 r = r - q;
409 else if (q - r <= d)
411 r = r - q + d;
412 q--;
414 else
416 r = r - q + 2*d;
417 q -= 2;
421 else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
423 c1 = (b1 - 1) - c1;
424 c0 = ~c0; /* logical NOT */
426 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
428 q = ~q; /* (A/2)/b1 */
429 r = (b1 - 1) - r;
431 r = 2*r + (a0 & 1); /* A/(2*b1) */
433 if ((d & 1) != 0)
435 if (r >= q)
436 r = r - q;
437 else if (q - r <= d)
439 r = r - q + d;
440 q--;
442 else
444 r = r - q + 2*d;
445 q -= 2;
449 else /* Implies c1 = b1 */
450 { /* Hence a1 = d - 1 = 2*b1 - 1 */
451 if (a0 >= -d)
453 q = -1;
454 r = a0 + d;
456 else
458 q = -2;
459 r = a0 + 2*d;
464 *rp = r;
465 return q;
467 #else
468 /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */
469 UWtype
470 __udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)),
471 UWtype a1 __attribute__ ((__unused__)),
472 UWtype a0 __attribute__ ((__unused__)),
473 UWtype d __attribute__ ((__unused__)))
475 return 0;
477 #endif
478 #endif
480 #if (defined (L_udivdi3) || defined (L_divdi3) || \
481 defined (L_umoddi3) || defined (L_moddi3))
482 #define L_udivmoddi4
483 #endif
485 #ifdef L_clz
486 const UQItype __clz_tab[] =
488 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,
489 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,
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 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 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,
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,
497 #endif
499 #ifdef L_udivmoddi4
501 #if (defined (L_udivdi3) || defined (L_divdi3) || \
502 defined (L_umoddi3) || defined (L_moddi3))
503 static inline
504 #endif
505 UDWtype
506 __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
508 DWunion ww;
509 DWunion nn, dd;
510 DWunion rr;
511 UWtype d0, d1, n0, n1, n2;
512 UWtype q0, q1;
513 UWtype b, bm;
515 nn.ll = n;
516 dd.ll = d;
518 d0 = dd.s.low;
519 d1 = dd.s.high;
520 n0 = nn.s.low;
521 n1 = nn.s.high;
523 #if !UDIV_NEEDS_NORMALIZATION
524 if (d1 == 0)
526 if (d0 > n1)
528 /* 0q = nn / 0D */
530 udiv_qrnnd (q0, n0, n1, n0, d0);
531 q1 = 0;
533 /* Remainder in n0. */
535 else
537 /* qq = NN / 0d */
539 if (d0 == 0)
540 d0 = 1 / d0; /* Divide intentionally by zero. */
542 udiv_qrnnd (q1, n1, 0, n1, d0);
543 udiv_qrnnd (q0, n0, n1, n0, d0);
545 /* Remainder in n0. */
548 if (rp != 0)
550 rr.s.low = n0;
551 rr.s.high = 0;
552 *rp = rr.ll;
556 #else /* UDIV_NEEDS_NORMALIZATION */
558 if (d1 == 0)
560 if (d0 > n1)
562 /* 0q = nn / 0D */
564 count_leading_zeros (bm, d0);
566 if (bm != 0)
568 /* Normalize, i.e. make the most significant bit of the
569 denominator set. */
571 d0 = d0 << bm;
572 n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
573 n0 = n0 << bm;
576 udiv_qrnnd (q0, n0, n1, n0, d0);
577 q1 = 0;
579 /* Remainder in n0 >> bm. */
581 else
583 /* qq = NN / 0d */
585 if (d0 == 0)
586 d0 = 1 / d0; /* Divide intentionally by zero. */
588 count_leading_zeros (bm, d0);
590 if (bm == 0)
592 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
593 conclude (the most significant bit of n1 is set) /\ (the
594 leading quotient digit q1 = 1).
596 This special case is necessary, not an optimization.
597 (Shifts counts of W_TYPE_SIZE are undefined.) */
599 n1 -= d0;
600 q1 = 1;
602 else
604 /* Normalize. */
606 b = W_TYPE_SIZE - bm;
608 d0 = d0 << bm;
609 n2 = n1 >> b;
610 n1 = (n1 << bm) | (n0 >> b);
611 n0 = n0 << bm;
613 udiv_qrnnd (q1, n1, n2, n1, d0);
616 /* n1 != d0... */
618 udiv_qrnnd (q0, n0, n1, n0, d0);
620 /* Remainder in n0 >> bm. */
623 if (rp != 0)
625 rr.s.low = n0 >> bm;
626 rr.s.high = 0;
627 *rp = rr.ll;
630 #endif /* UDIV_NEEDS_NORMALIZATION */
632 else
634 if (d1 > n1)
636 /* 00 = nn / DD */
638 q0 = 0;
639 q1 = 0;
641 /* Remainder in n1n0. */
642 if (rp != 0)
644 rr.s.low = n0;
645 rr.s.high = n1;
646 *rp = rr.ll;
649 else
651 /* 0q = NN / dd */
653 count_leading_zeros (bm, d1);
654 if (bm == 0)
656 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
657 conclude (the most significant bit of n1 is set) /\ (the
658 quotient digit q0 = 0 or 1).
660 This special case is necessary, not an optimization. */
662 /* The condition on the next line takes advantage of that
663 n1 >= d1 (true due to program flow). */
664 if (n1 > d1 || n0 >= d0)
666 q0 = 1;
667 sub_ddmmss (n1, n0, n1, n0, d1, d0);
669 else
670 q0 = 0;
672 q1 = 0;
674 if (rp != 0)
676 rr.s.low = n0;
677 rr.s.high = n1;
678 *rp = rr.ll;
681 else
683 UWtype m1, m0;
684 /* Normalize. */
686 b = W_TYPE_SIZE - bm;
688 d1 = (d1 << bm) | (d0 >> b);
689 d0 = d0 << bm;
690 n2 = n1 >> b;
691 n1 = (n1 << bm) | (n0 >> b);
692 n0 = n0 << bm;
694 udiv_qrnnd (q0, n1, n2, n1, d1);
695 umul_ppmm (m1, m0, q0, d0);
697 if (m1 > n1 || (m1 == n1 && m0 > n0))
699 q0--;
700 sub_ddmmss (m1, m0, m1, m0, d1, d0);
703 q1 = 0;
705 /* Remainder in (n1n0 - m1m0) >> bm. */
706 if (rp != 0)
708 sub_ddmmss (n1, n0, n1, n0, m1, m0);
709 rr.s.low = (n1 << b) | (n0 >> bm);
710 rr.s.high = n1 >> bm;
711 *rp = rr.ll;
717 ww.s.low = q0;
718 ww.s.high = q1;
719 return ww.ll;
721 #endif
723 #ifdef L_divdi3
724 DWtype
725 __divdi3 (DWtype u, DWtype v)
727 word_type c = 0;
728 DWunion uu, vv;
729 DWtype w;
731 uu.ll = u;
732 vv.ll = v;
734 if (uu.s.high < 0)
735 c = ~c,
736 uu.ll = -uu.ll;
737 if (vv.s.high < 0)
738 c = ~c,
739 vv.ll = -vv.ll;
741 w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
742 if (c)
743 w = -w;
745 return w;
747 #endif
749 #ifdef L_moddi3
750 DWtype
751 __moddi3 (DWtype u, DWtype v)
753 word_type c = 0;
754 DWunion uu, vv;
755 DWtype w;
757 uu.ll = u;
758 vv.ll = v;
760 if (uu.s.high < 0)
761 c = ~c,
762 uu.ll = -uu.ll;
763 if (vv.s.high < 0)
764 vv.ll = -vv.ll;
766 (void) __udivmoddi4 (uu.ll, vv.ll, &w);
767 if (c)
768 w = -w;
770 return w;
772 #endif
774 #ifdef L_umoddi3
775 UDWtype
776 __umoddi3 (UDWtype u, UDWtype v)
778 UDWtype w;
780 (void) __udivmoddi4 (u, v, &w);
782 return w;
784 #endif
786 #ifdef L_udivdi3
787 UDWtype
788 __udivdi3 (UDWtype n, UDWtype d)
790 return __udivmoddi4 (n, d, (UDWtype *) 0);
792 #endif
794 #ifdef L_cmpdi2
795 word_type
796 __cmpdi2 (DWtype a, DWtype b)
798 DWunion au, bu;
800 au.ll = a, bu.ll = b;
802 if (au.s.high < bu.s.high)
803 return 0;
804 else if (au.s.high > bu.s.high)
805 return 2;
806 if ((UWtype) au.s.low < (UWtype) bu.s.low)
807 return 0;
808 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
809 return 2;
810 return 1;
812 #endif
814 #ifdef L_ucmpdi2
815 word_type
816 __ucmpdi2 (DWtype a, DWtype b)
818 DWunion au, bu;
820 au.ll = a, bu.ll = b;
822 if ((UWtype) au.s.high < (UWtype) bu.s.high)
823 return 0;
824 else if ((UWtype) au.s.high > (UWtype) bu.s.high)
825 return 2;
826 if ((UWtype) au.s.low < (UWtype) bu.s.low)
827 return 0;
828 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
829 return 2;
830 return 1;
832 #endif
834 #if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
835 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
836 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
838 DWtype
839 __fixunstfDI (TFtype a)
841 TFtype b;
842 UDWtype v;
844 if (a < 0)
845 return 0;
847 /* Compute high word of result, as a flonum. */
848 b = (a / HIGH_WORD_COEFF);
849 /* Convert that to fixed (but not to DWtype!),
850 and shift it into the high word. */
851 v = (UWtype) b;
852 v <<= WORD_SIZE;
853 /* Remove high part from the TFtype, leaving the low part as flonum. */
854 a -= (TFtype)v;
855 /* Convert that to fixed (but not to DWtype!) and add it in.
856 Sometimes A comes out negative. This is significant, since
857 A has more bits than a long int does. */
858 if (a < 0)
859 v -= (UWtype) (- a);
860 else
861 v += (UWtype) a;
862 return v;
864 #endif
866 #if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
867 DWtype
868 __fixtfdi (TFtype a)
870 if (a < 0)
871 return - __fixunstfDI (-a);
872 return __fixunstfDI (a);
874 #endif
876 #if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
877 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
878 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
880 DWtype
881 __fixunsxfDI (XFtype a)
883 XFtype b;
884 UDWtype v;
886 if (a < 0)
887 return 0;
889 /* Compute high word of result, as a flonum. */
890 b = (a / HIGH_WORD_COEFF);
891 /* Convert that to fixed (but not to DWtype!),
892 and shift it into the high word. */
893 v = (UWtype) b;
894 v <<= WORD_SIZE;
895 /* Remove high part from the XFtype, leaving the low part as flonum. */
896 a -= (XFtype)v;
897 /* Convert that to fixed (but not to DWtype!) and add it in.
898 Sometimes A comes out negative. This is significant, since
899 A has more bits than a long int does. */
900 if (a < 0)
901 v -= (UWtype) (- a);
902 else
903 v += (UWtype) a;
904 return v;
906 #endif
908 #if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
909 DWtype
910 __fixxfdi (XFtype a)
912 if (a < 0)
913 return - __fixunsxfDI (-a);
914 return __fixunsxfDI (a);
916 #endif
918 #ifdef L_fixunsdfdi
919 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
920 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
922 DWtype
923 __fixunsdfDI (DFtype a)
925 DFtype b;
926 UDWtype v;
928 if (a < 0)
929 return 0;
931 /* Compute high word of result, as a flonum. */
932 b = (a / HIGH_WORD_COEFF);
933 /* Convert that to fixed (but not to DWtype!),
934 and shift it into the high word. */
935 v = (UWtype) b;
936 v <<= WORD_SIZE;
937 /* Remove high part from the DFtype, leaving the low part as flonum. */
938 a -= (DFtype)v;
939 /* Convert that to fixed (but not to DWtype!) and add it in.
940 Sometimes A comes out negative. This is significant, since
941 A has more bits than a long int does. */
942 if (a < 0)
943 v -= (UWtype) (- a);
944 else
945 v += (UWtype) a;
946 return v;
948 #endif
950 #ifdef L_fixdfdi
951 DWtype
952 __fixdfdi (DFtype a)
954 if (a < 0)
955 return - __fixunsdfDI (-a);
956 return __fixunsdfDI (a);
958 #endif
960 #ifdef L_fixunssfdi
961 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
962 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
964 DWtype
965 __fixunssfDI (SFtype original_a)
967 /* Convert the SFtype to a DFtype, because that is surely not going
968 to lose any bits. Some day someone else can write a faster version
969 that avoids converting to DFtype, and verify it really works right. */
970 DFtype a = original_a;
971 DFtype b;
972 UDWtype v;
974 if (a < 0)
975 return 0;
977 /* Compute high word of result, as a flonum. */
978 b = (a / HIGH_WORD_COEFF);
979 /* Convert that to fixed (but not to DWtype!),
980 and shift it into the high word. */
981 v = (UWtype) b;
982 v <<= WORD_SIZE;
983 /* Remove high part from the DFtype, leaving the low part as flonum. */
984 a -= (DFtype) v;
985 /* Convert that to fixed (but not to DWtype!) and add it in.
986 Sometimes A comes out negative. This is significant, since
987 A has more bits than a long int does. */
988 if (a < 0)
989 v -= (UWtype) (- a);
990 else
991 v += (UWtype) a;
992 return v;
994 #endif
996 #ifdef L_fixsfdi
997 DWtype
998 __fixsfdi (SFtype a)
1000 if (a < 0)
1001 return - __fixunssfDI (-a);
1002 return __fixunssfDI (a);
1004 #endif
1006 #if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
1007 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1008 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1009 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1011 XFtype
1012 __floatdixf (DWtype u)
1014 XFtype d;
1016 d = (Wtype) (u >> WORD_SIZE);
1017 d *= HIGH_HALFWORD_COEFF;
1018 d *= HIGH_HALFWORD_COEFF;
1019 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1021 return d;
1023 #endif
1025 #if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
1026 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1027 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1028 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1030 TFtype
1031 __floatditf (DWtype u)
1033 TFtype d;
1035 d = (Wtype) (u >> WORD_SIZE);
1036 d *= HIGH_HALFWORD_COEFF;
1037 d *= HIGH_HALFWORD_COEFF;
1038 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1040 return d;
1042 #endif
1044 #ifdef L_floatdidf
1045 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1046 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1047 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1049 DFtype
1050 __floatdidf (DWtype u)
1052 DFtype d;
1054 d = (Wtype) (u >> WORD_SIZE);
1055 d *= HIGH_HALFWORD_COEFF;
1056 d *= HIGH_HALFWORD_COEFF;
1057 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1059 return d;
1061 #endif
1063 #ifdef L_floatdisf
1064 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1065 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1066 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1068 #define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT)
1069 #define DF_SIZE DBL_MANT_DIG
1070 #define SF_SIZE FLT_MANT_DIG
1072 SFtype
1073 __floatdisf (DWtype u)
1075 /* Do the calculation in DFmode
1076 so that we don't lose any of the precision of the high word
1077 while multiplying it. */
1078 DFtype f;
1080 /* Protect against double-rounding error.
1081 Represent any low-order bits, that might be truncated in DFmode,
1082 by a bit that won't be lost. The bit can go in anywhere below the
1083 rounding position of the SFmode. A fixed mask and bit position
1084 handles all usual configurations. It doesn't handle the case
1085 of 128-bit DImode, however. */
1086 if (DF_SIZE < DI_SIZE
1087 && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1089 #define REP_BIT ((UDWtype) 1 << (DI_SIZE - DF_SIZE))
1090 if (! (- ((DWtype) 1 << DF_SIZE) < u
1091 && u < ((DWtype) 1 << DF_SIZE)))
1093 if ((UDWtype) u & (REP_BIT - 1))
1094 u |= REP_BIT;
1097 f = (Wtype) (u >> WORD_SIZE);
1098 f *= HIGH_HALFWORD_COEFF;
1099 f *= HIGH_HALFWORD_COEFF;
1100 f += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1102 return (SFtype) f;
1104 #endif
1106 #if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
1107 /* Reenable the normal types, in case limits.h needs them. */
1108 #undef char
1109 #undef short
1110 #undef int
1111 #undef long
1112 #undef unsigned
1113 #undef float
1114 #undef double
1115 #undef MIN
1116 #undef MAX
1117 #include <limits.h>
1119 UWtype
1120 __fixunsxfSI (XFtype a)
1122 if (a >= - (DFtype) Wtype_MIN)
1123 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1124 return (Wtype) a;
1126 #endif
1128 #ifdef L_fixunsdfsi
1129 /* Reenable the normal types, in case limits.h needs them. */
1130 #undef char
1131 #undef short
1132 #undef int
1133 #undef long
1134 #undef unsigned
1135 #undef float
1136 #undef double
1137 #undef MIN
1138 #undef MAX
1139 #include <limits.h>
1141 UWtype
1142 __fixunsdfSI (DFtype a)
1144 if (a >= - (DFtype) Wtype_MIN)
1145 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1146 return (Wtype) a;
1148 #endif
1150 #ifdef L_fixunssfsi
1151 /* Reenable the normal types, in case limits.h needs them. */
1152 #undef char
1153 #undef short
1154 #undef int
1155 #undef long
1156 #undef unsigned
1157 #undef float
1158 #undef double
1159 #undef MIN
1160 #undef MAX
1161 #include <limits.h>
1163 UWtype
1164 __fixunssfSI (SFtype a)
1166 if (a >= - (SFtype) Wtype_MIN)
1167 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1168 return (Wtype) a;
1170 #endif
1172 /* From here on down, the routines use normal data types. */
1174 #define SItype bogus_type
1175 #define USItype bogus_type
1176 #define DItype bogus_type
1177 #define UDItype bogus_type
1178 #define SFtype bogus_type
1179 #define DFtype bogus_type
1180 #undef Wtype
1181 #undef UWtype
1182 #undef HWtype
1183 #undef UHWtype
1184 #undef DWtype
1185 #undef UDWtype
1187 #undef char
1188 #undef short
1189 #undef int
1190 #undef long
1191 #undef unsigned
1192 #undef float
1193 #undef double
1195 #ifdef L__gcc_bcmp
1197 /* Like bcmp except the sign is meaningful.
1198 Result is negative if S1 is less than S2,
1199 positive if S1 is greater, 0 if S1 and S2 are equal. */
1202 __gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
1204 while (size > 0)
1206 unsigned char c1 = *s1++, c2 = *s2++;
1207 if (c1 != c2)
1208 return c1 - c2;
1209 size--;
1211 return 0;
1214 #endif
1216 /* __eprintf used to be used by GCC's private version of <assert.h>.
1217 We no longer provide that header, but this routine remains in libgcc.a
1218 for binary backward compatibility. Note that it is not included in
1219 the shared version of libgcc. */
1220 #ifdef L_eprintf
1221 #ifndef inhibit_libc
1223 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1224 #include <stdio.h>
1226 void
1227 __eprintf (const char *string, const char *expression,
1228 unsigned int line, const char *filename)
1230 fprintf (stderr, string, expression, line, filename);
1231 fflush (stderr);
1232 abort ();
1235 #endif
1236 #endif
1238 #ifdef L_bb
1240 struct bb_function_info {
1241 long checksum;
1242 int arc_count;
1243 const char *name;
1246 /* Structure emitted by -a */
1247 struct bb
1249 long zero_word;
1250 const char *filename;
1251 gcov_type *counts;
1252 long ncounts;
1253 struct bb *next;
1255 /* Older GCC's did not emit these fields. */
1256 long sizeof_bb;
1257 struct bb_function_info *function_infos;
1260 #ifndef inhibit_libc
1262 /* Simple minded basic block profiling output dumper for
1263 systems that don't provide tcov support. At present,
1264 it requires atexit and stdio. */
1266 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1267 #include <stdio.h>
1269 #include "gbl-ctors.h"
1270 #include "gcov-io.h"
1271 #include <string.h>
1272 #ifdef TARGET_HAS_F_SETLKW
1273 #include <fcntl.h>
1274 #include <errno.h>
1275 #endif
1277 #include <gthr.h>
1279 static struct bb *bb_head;
1281 int __global_counters = 0, __gthreads_active = 0;
1283 void
1284 __bb_exit_func (void)
1286 FILE *da_file;
1287 struct bb *ptr;
1288 long n_counters_p = 0;
1289 gcov_type max_counter_p = 0;
1290 gcov_type sum_counters_p = 0;
1292 if (bb_head == 0)
1293 return;
1295 /* Calculate overall "statistics". */
1297 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1299 int i;
1301 n_counters_p += ptr->ncounts;
1303 for (i = 0; i < ptr->ncounts; i++)
1305 sum_counters_p += ptr->counts[i];
1307 if (ptr->counts[i] > max_counter_p)
1308 max_counter_p = ptr->counts[i];
1312 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1314 gcov_type max_counter_o = 0;
1315 gcov_type sum_counters_o = 0;
1316 int i;
1318 /* Calculate the per-object statistics. */
1320 for (i = 0; i < ptr->ncounts; i++)
1322 sum_counters_o += ptr->counts[i];
1324 if (ptr->counts[i] > max_counter_o)
1325 max_counter_o = ptr->counts[i];
1328 /* open the file for appending, creating it if necessary. */
1329 da_file = fopen (ptr->filename, "ab");
1330 /* Some old systems might not allow the 'b' mode modifier.
1331 Therefore, try to open without it. This can lead to a race
1332 condition so that when you delete and re-create the file, the
1333 file might be opened in text mode, but then, you shouldn't
1334 delete the file in the first place. */
1335 if (da_file == 0)
1336 da_file = fopen (ptr->filename, "a");
1337 if (da_file == 0)
1339 fprintf (stderr, "arc profiling: Can't open output file %s.\n",
1340 ptr->filename);
1341 continue;
1344 /* After a fork, another process might try to read and/or write
1345 the same file simultanously. So if we can, lock the file to
1346 avoid race conditions. */
1347 #if defined (TARGET_HAS_F_SETLKW)
1349 struct flock s_flock;
1351 s_flock.l_type = F_WRLCK;
1352 s_flock.l_whence = SEEK_SET;
1353 s_flock.l_start = 0;
1354 s_flock.l_len = 1;
1355 s_flock.l_pid = getpid ();
1357 while (fcntl (fileno (da_file), F_SETLKW, &s_flock)
1358 && errno == EINTR);
1360 #endif
1362 if (__write_long (-123, da_file, 4) != 0) /* magic */
1364 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1365 ptr->filename);
1367 else
1370 struct bb_function_info *fn_info;
1371 gcov_type *count_ptr = ptr->counts;
1372 int i;
1373 int count_functions = 0;
1375 for (fn_info = ptr->function_infos; fn_info->arc_count != -1;
1376 fn_info++)
1377 count_functions++;
1379 /* number of functions in this block. */
1380 __write_long (count_functions, da_file, 4);
1382 /* length of extra data in bytes. */
1383 __write_long ((4 + 8 + 8) + (4 + 8 + 8), da_file, 4);
1385 /* overall statistics. */
1386 /* number of counters. */
1387 __write_long (n_counters_p, da_file, 4);
1388 /* sum of counters. */
1389 __write_gcov_type (sum_counters_p, da_file, 8);
1390 /* maximal counter. */
1391 __write_gcov_type (max_counter_p, da_file, 8);
1393 /* per-object statistics. */
1394 /* number of counters. */
1395 __write_long (ptr->ncounts, da_file, 4);
1396 /* sum of counters. */
1397 __write_gcov_type (sum_counters_o, da_file, 8);
1398 /* maximal counter. */
1399 __write_gcov_type (max_counter_o, da_file, 8);
1401 /* write execution counts for each function. */
1403 for (fn_info = ptr->function_infos; fn_info->arc_count != -1;
1404 fn_info++)
1406 /* new function. */
1407 if (__write_gcov_string
1408 (fn_info->name, strlen (fn_info->name), da_file, -1) != 0)
1410 fprintf (stderr,
1411 "arc profiling: Error writing output file %s.\n",
1412 ptr->filename);
1413 break;
1416 if (__write_long (fn_info->checksum, da_file, 4) != 0)
1418 fprintf (stderr,
1419 "arc profiling: Error writing output file %s.\n",
1420 ptr->filename);
1421 break;
1424 if (__write_long (fn_info->arc_count, da_file, 4) != 0)
1426 fprintf (stderr,
1427 "arc profiling: Error writing output file %s.\n",
1428 ptr->filename);
1429 break;
1432 for (i = fn_info->arc_count; i > 0; i--, count_ptr++)
1434 if (__write_gcov_type (*count_ptr, da_file, 8) != 0)
1435 break;
1438 if (i) /* there was an error */
1440 fprintf (stderr,
1441 "arc profiling: Error writing output file %s.\n",
1442 ptr->filename);
1443 break;
1448 if (fclose (da_file) != 0)
1449 fprintf (stderr, "arc profiling: Error closing output file %s.\n",
1450 ptr->filename);
1454 void
1455 __bb_init_func (struct bb *blocks)
1457 /* User is supposed to check whether the first word is non-0,
1458 but just in case.... */
1460 if (blocks->zero_word)
1461 return;
1463 /* Initialize destructor and per-thread data. */
1464 if (!bb_head)
1465 atexit (__bb_exit_func);
1467 /* Set up linked list. */
1468 blocks->zero_word = 1;
1469 blocks->next = bb_head;
1470 bb_head = blocks;
1473 /* Called before fork or exec - write out profile information gathered so
1474 far and reset it to zero. This avoids duplication or loss of the
1475 profile information gathered so far. */
1476 void
1477 __bb_fork_func (void)
1479 struct bb *ptr;
1481 __bb_exit_func ();
1482 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1484 long i;
1485 for (i = ptr->ncounts - 1; i >= 0; i--)
1486 ptr->counts[i] = 0;
1490 #endif /* not inhibit_libc */
1491 #endif /* L_bb */
1493 #ifdef L_clear_cache
1494 /* Clear part of an instruction cache. */
1496 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1498 void
1499 __clear_cache (char *beg __attribute__((__unused__)),
1500 char *end __attribute__((__unused__)))
1502 #ifdef CLEAR_INSN_CACHE
1503 CLEAR_INSN_CACHE (beg, end);
1504 #else
1505 #ifdef INSN_CACHE_SIZE
1506 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1507 static int initialized;
1508 int offset;
1509 void *start_addr
1510 void *end_addr;
1511 typedef (*function_ptr) (void);
1513 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1514 /* It's cheaper to clear the whole cache.
1515 Put in a series of jump instructions so that calling the beginning
1516 of the cache will clear the whole thing. */
1518 if (! initialized)
1520 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1521 & -INSN_CACHE_LINE_WIDTH);
1522 int end_ptr = ptr + INSN_CACHE_SIZE;
1524 while (ptr < end_ptr)
1526 *(INSTRUCTION_TYPE *)ptr
1527 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1528 ptr += INSN_CACHE_LINE_WIDTH;
1530 *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1532 initialized = 1;
1535 /* Call the beginning of the sequence. */
1536 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1537 & -INSN_CACHE_LINE_WIDTH))
1538 ());
1540 #else /* Cache is large. */
1542 if (! initialized)
1544 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1545 & -INSN_CACHE_LINE_WIDTH);
1547 while (ptr < (int) array + sizeof array)
1549 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1550 ptr += INSN_CACHE_LINE_WIDTH;
1553 initialized = 1;
1556 /* Find the location in array that occupies the same cache line as BEG. */
1558 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1559 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1560 & -INSN_CACHE_PLANE_SIZE)
1561 + offset);
1563 /* Compute the cache alignment of the place to stop clearing. */
1564 #if 0 /* This is not needed for gcc's purposes. */
1565 /* If the block to clear is bigger than a cache plane,
1566 we clear the entire cache, and OFFSET is already correct. */
1567 if (end < beg + INSN_CACHE_PLANE_SIZE)
1568 #endif
1569 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1570 & -INSN_CACHE_LINE_WIDTH)
1571 & (INSN_CACHE_PLANE_SIZE - 1));
1573 #if INSN_CACHE_DEPTH > 1
1574 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1575 if (end_addr <= start_addr)
1576 end_addr += INSN_CACHE_PLANE_SIZE;
1578 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1580 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1581 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1583 while (addr != stop)
1585 /* Call the return instruction at ADDR. */
1586 ((function_ptr) addr) ();
1588 addr += INSN_CACHE_LINE_WIDTH;
1591 #else /* just one plane */
1594 /* Call the return instruction at START_ADDR. */
1595 ((function_ptr) start_addr) ();
1597 start_addr += INSN_CACHE_LINE_WIDTH;
1599 while ((start_addr % INSN_CACHE_SIZE) != offset);
1600 #endif /* just one plane */
1601 #endif /* Cache is large */
1602 #endif /* Cache exists */
1603 #endif /* CLEAR_INSN_CACHE */
1606 #endif /* L_clear_cache */
1608 #ifdef L_trampoline
1610 /* Jump to a trampoline, loading the static chain address. */
1612 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
1614 long
1615 getpagesize (void)
1617 #ifdef _ALPHA_
1618 return 8192;
1619 #else
1620 return 4096;
1621 #endif
1624 #ifdef __i386__
1625 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
1626 #endif
1629 mprotect (char *addr, int len, int prot)
1631 int np, op;
1633 if (prot == 7)
1634 np = 0x40;
1635 else if (prot == 5)
1636 np = 0x20;
1637 else if (prot == 4)
1638 np = 0x10;
1639 else if (prot == 3)
1640 np = 0x04;
1641 else if (prot == 1)
1642 np = 0x02;
1643 else if (prot == 0)
1644 np = 0x01;
1646 if (VirtualProtect (addr, len, np, &op))
1647 return 0;
1648 else
1649 return -1;
1652 #endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
1654 #ifdef TRANSFER_FROM_TRAMPOLINE
1655 TRANSFER_FROM_TRAMPOLINE
1656 #endif
1658 #if defined (NeXT) && defined (__MACH__)
1660 /* Make stack executable so we can call trampolines on stack.
1661 This is called from INITIALIZE_TRAMPOLINE in next.h. */
1662 #ifdef NeXTStep21
1663 #include <mach.h>
1664 #else
1665 #include <mach/mach.h>
1666 #endif
1668 void
1669 __enable_execute_stack (char *addr)
1671 kern_return_t r;
1672 char *eaddr = addr + TRAMPOLINE_SIZE;
1673 vm_address_t a = (vm_address_t) addr;
1675 /* turn on execute access on stack */
1676 r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
1677 if (r != KERN_SUCCESS)
1679 mach_error("vm_protect VM_PROT_ALL", r);
1680 exit(1);
1683 /* We inline the i-cache invalidation for speed */
1685 #ifdef CLEAR_INSN_CACHE
1686 CLEAR_INSN_CACHE (addr, eaddr);
1687 #else
1688 __clear_cache ((int) addr, (int) eaddr);
1689 #endif
1692 #endif /* defined (NeXT) && defined (__MACH__) */
1694 #ifdef __convex__
1696 /* Make stack executable so we can call trampolines on stack.
1697 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
1699 #include <sys/mman.h>
1700 #include <sys/vmparam.h>
1701 #include <machine/machparam.h>
1703 void
1704 __enable_execute_stack (void)
1706 int fp;
1707 static unsigned lowest = USRSTACK;
1708 unsigned current = (unsigned) &fp & -NBPG;
1710 if (lowest > current)
1712 unsigned len = lowest - current;
1713 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
1714 lowest = current;
1717 /* Clear instruction cache in case an old trampoline is in it. */
1718 asm ("pich");
1720 #endif /* __convex__ */
1722 #ifdef __sysV88__
1724 /* Modified from the convex -code above. */
1726 #include <sys/param.h>
1727 #include <errno.h>
1728 #include <sys/m88kbcs.h>
1730 void
1731 __enable_execute_stack (void)
1733 int save_errno;
1734 static unsigned long lowest = USRSTACK;
1735 unsigned long current = (unsigned long) &save_errno & -NBPC;
1737 /* Ignore errno being set. memctl sets errno to EINVAL whenever the
1738 address is seen as 'negative'. That is the case with the stack. */
1740 save_errno=errno;
1741 if (lowest > current)
1743 unsigned len=lowest-current;
1744 memctl(current,len,MCT_TEXT);
1745 lowest = current;
1747 else
1748 memctl(current,NBPC,MCT_TEXT);
1749 errno=save_errno;
1752 #endif /* __sysV88__ */
1754 #ifdef __sysV68__
1756 #include <sys/signal.h>
1757 #include <errno.h>
1759 /* Motorola forgot to put memctl.o in the libp version of libc881.a,
1760 so define it here, because we need it in __clear_insn_cache below */
1761 /* On older versions of this OS, no memctl or MCT_TEXT are defined;
1762 hence we enable this stuff only if MCT_TEXT is #define'd. */
1764 #ifdef MCT_TEXT
1765 asm("\n\
1766 global memctl\n\
1767 memctl:\n\
1768 movq &75,%d0\n\
1769 trap &0\n\
1770 bcc.b noerror\n\
1771 jmp cerror%\n\
1772 noerror:\n\
1773 movq &0,%d0\n\
1774 rts");
1775 #endif
1777 /* Clear instruction cache so we can call trampolines on stack.
1778 This is called from FINALIZE_TRAMPOLINE in mot3300.h. */
1780 void
1781 __clear_insn_cache (void)
1783 #ifdef MCT_TEXT
1784 int save_errno;
1786 /* Preserve errno, because users would be surprised to have
1787 errno changing without explicitly calling any system-call. */
1788 save_errno = errno;
1790 /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache.
1791 No need to use an address derived from _start or %sp, as 0 works also. */
1792 memctl(0, 4096, MCT_TEXT);
1793 errno = save_errno;
1794 #endif
1797 #endif /* __sysV68__ */
1799 #ifdef __pyr__
1801 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1802 #include <stdio.h>
1803 #include <sys/mman.h>
1804 #include <sys/types.h>
1805 #include <sys/param.h>
1806 #include <sys/vmmac.h>
1808 /* Modified from the convex -code above.
1809 mremap promises to clear the i-cache. */
1811 void
1812 __enable_execute_stack (void)
1814 int fp;
1815 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
1816 PROT_READ|PROT_WRITE|PROT_EXEC))
1818 perror ("mprotect in __enable_execute_stack");
1819 fflush (stderr);
1820 abort ();
1823 #endif /* __pyr__ */
1825 #if defined (sony_news) && defined (SYSTYPE_BSD)
1827 #include <stdio.h>
1828 #include <sys/types.h>
1829 #include <sys/param.h>
1830 #include <syscall.h>
1831 #include <machine/sysnews.h>
1833 /* cacheflush function for NEWS-OS 4.2.
1834 This function is called from trampoline-initialize code
1835 defined in config/mips/mips.h. */
1837 void
1838 cacheflush (char *beg, int size, int flag)
1840 if (syscall (SYS_sysnews, NEWS_CACHEFLUSH, beg, size, FLUSH_BCACHE))
1842 perror ("cache_flush");
1843 fflush (stderr);
1844 abort ();
1848 #endif /* sony_news */
1849 #endif /* L_trampoline */
1851 #ifndef __CYGWIN__
1852 #ifdef L__main
1854 #include "gbl-ctors.h"
1855 /* Some systems use __main in a way incompatible with its use in gcc, in these
1856 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
1857 give the same symbol without quotes for an alternative entry point. You
1858 must define both, or neither. */
1859 #ifndef NAME__MAIN
1860 #define NAME__MAIN "__main"
1861 #define SYMBOL__MAIN __main
1862 #endif
1864 #ifdef INIT_SECTION_ASM_OP
1865 #undef HAS_INIT_SECTION
1866 #define HAS_INIT_SECTION
1867 #endif
1869 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
1871 /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
1872 code to run constructors. In that case, we need to handle EH here, too. */
1874 #ifdef EH_FRAME_SECTION_NAME
1875 #include "unwind-dw2-fde.h"
1876 extern unsigned char __EH_FRAME_BEGIN__[];
1877 #endif
1879 /* Run all the global destructors on exit from the program. */
1881 void
1882 __do_global_dtors (void)
1884 #ifdef DO_GLOBAL_DTORS_BODY
1885 DO_GLOBAL_DTORS_BODY;
1886 #else
1887 static func_ptr *p = __DTOR_LIST__ + 1;
1888 while (*p)
1890 p++;
1891 (*(p-1)) ();
1893 #endif
1894 #if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION)
1896 static int completed = 0;
1897 if (! completed)
1899 completed = 1;
1900 __deregister_frame_info (__EH_FRAME_BEGIN__);
1903 #endif
1905 #endif
1907 #ifndef HAS_INIT_SECTION
1908 /* Run all the global constructors on entry to the program. */
1910 void
1911 __do_global_ctors (void)
1913 #ifdef EH_FRAME_SECTION_NAME
1915 static struct object object;
1916 __register_frame_info (__EH_FRAME_BEGIN__, &object);
1918 #endif
1919 DO_GLOBAL_CTORS_BODY;
1920 atexit (__do_global_dtors);
1922 #endif /* no HAS_INIT_SECTION */
1924 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
1925 /* Subroutine called automatically by `main'.
1926 Compiling a global function named `main'
1927 produces an automatic call to this function at the beginning.
1929 For many systems, this routine calls __do_global_ctors.
1930 For systems which support a .init section we use the .init section
1931 to run __do_global_ctors, so we need not do anything here. */
1933 void
1934 SYMBOL__MAIN ()
1936 /* Support recursive calls to `main': run initializers just once. */
1937 static int initialized;
1938 if (! initialized)
1940 initialized = 1;
1941 __do_global_ctors ();
1944 #endif /* no HAS_INIT_SECTION or INVOKE__main */
1946 #endif /* L__main */
1947 #endif /* __CYGWIN__ */
1949 #ifdef L_ctors
1951 #include "gbl-ctors.h"
1953 /* Provide default definitions for the lists of constructors and
1954 destructors, so that we don't get linker errors. These symbols are
1955 intentionally bss symbols, so that gld and/or collect will provide
1956 the right values. */
1958 /* We declare the lists here with two elements each,
1959 so that they are valid empty lists if no other definition is loaded.
1961 If we are using the old "set" extensions to have the gnu linker
1962 collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
1963 must be in the bss/common section.
1965 Long term no port should use those extensions. But many still do. */
1966 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
1967 #if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2)
1968 func_ptr __CTOR_LIST__[2] = {0, 0};
1969 func_ptr __DTOR_LIST__[2] = {0, 0};
1970 #else
1971 func_ptr __CTOR_LIST__[2];
1972 func_ptr __DTOR_LIST__[2];
1973 #endif
1974 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1975 #endif /* L_ctors */
1977 #ifdef L_exit
1979 #include "gbl-ctors.h"
1981 #ifdef NEED_ATEXIT
1983 #ifndef ON_EXIT
1985 # include <errno.h>
1987 static func_ptr *atexit_chain = 0;
1988 static long atexit_chain_length = 0;
1989 static volatile long last_atexit_chain_slot = -1;
1992 atexit (func_ptr func)
1994 if (++last_atexit_chain_slot == atexit_chain_length)
1996 atexit_chain_length += 32;
1997 if (atexit_chain)
1998 atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
1999 * sizeof (func_ptr));
2000 else
2001 atexit_chain = (func_ptr *) malloc (atexit_chain_length
2002 * sizeof (func_ptr));
2003 if (! atexit_chain)
2005 atexit_chain_length = 0;
2006 last_atexit_chain_slot = -1;
2007 errno = ENOMEM;
2008 return (-1);
2011 atexit_chain[last_atexit_chain_slot] = func;
2012 return (0);
2015 extern void _cleanup (void);
2016 extern void _exit (int) __attribute__ ((__noreturn__));
2018 void
2019 exit (int status)
2021 if (atexit_chain)
2023 for ( ; last_atexit_chain_slot-- >= 0; )
2025 (*atexit_chain[last_atexit_chain_slot + 1]) ();
2026 atexit_chain[last_atexit_chain_slot + 1] = 0;
2028 free (atexit_chain);
2029 atexit_chain = 0;
2031 #ifdef EXIT_BODY
2032 EXIT_BODY;
2033 #else
2034 _cleanup ();
2035 #endif
2036 _exit (status);
2039 #else /* ON_EXIT */
2041 /* Simple; we just need a wrapper for ON_EXIT. */
2043 atexit (func_ptr func)
2045 return ON_EXIT (func);
2048 #endif /* ON_EXIT */
2049 #endif /* NEED_ATEXIT */
2051 #endif /* L_exit */