* libgcc2.c (__floatdisf): Properly cure double rounding.
[official-gcc.git] / gcc / libgcc2.c
blobb1e9edc551c1ca00a81b84781d45f53b8ad27b2e
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, 2002 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))
1095 u &= ~ (REP_BIT - 1);
1096 u |= REP_BIT;
1100 f = (Wtype) (u >> WORD_SIZE);
1101 f *= HIGH_HALFWORD_COEFF;
1102 f *= HIGH_HALFWORD_COEFF;
1103 f += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1105 return (SFtype) f;
1107 #endif
1109 #if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
1110 /* Reenable the normal types, in case limits.h needs them. */
1111 #undef char
1112 #undef short
1113 #undef int
1114 #undef long
1115 #undef unsigned
1116 #undef float
1117 #undef double
1118 #undef MIN
1119 #undef MAX
1120 #include <limits.h>
1122 UWtype
1123 __fixunsxfSI (XFtype a)
1125 if (a >= - (DFtype) Wtype_MIN)
1126 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1127 return (Wtype) a;
1129 #endif
1131 #ifdef L_fixunsdfsi
1132 /* Reenable the normal types, in case limits.h needs them. */
1133 #undef char
1134 #undef short
1135 #undef int
1136 #undef long
1137 #undef unsigned
1138 #undef float
1139 #undef double
1140 #undef MIN
1141 #undef MAX
1142 #include <limits.h>
1144 UWtype
1145 __fixunsdfSI (DFtype a)
1147 if (a >= - (DFtype) Wtype_MIN)
1148 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1149 return (Wtype) a;
1151 #endif
1153 #ifdef L_fixunssfsi
1154 /* Reenable the normal types, in case limits.h needs them. */
1155 #undef char
1156 #undef short
1157 #undef int
1158 #undef long
1159 #undef unsigned
1160 #undef float
1161 #undef double
1162 #undef MIN
1163 #undef MAX
1164 #include <limits.h>
1166 UWtype
1167 __fixunssfSI (SFtype a)
1169 if (a >= - (SFtype) Wtype_MIN)
1170 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1171 return (Wtype) a;
1173 #endif
1175 /* From here on down, the routines use normal data types. */
1177 #define SItype bogus_type
1178 #define USItype bogus_type
1179 #define DItype bogus_type
1180 #define UDItype bogus_type
1181 #define SFtype bogus_type
1182 #define DFtype bogus_type
1183 #undef Wtype
1184 #undef UWtype
1185 #undef HWtype
1186 #undef UHWtype
1187 #undef DWtype
1188 #undef UDWtype
1190 #undef char
1191 #undef short
1192 #undef int
1193 #undef long
1194 #undef unsigned
1195 #undef float
1196 #undef double
1198 #ifdef L__gcc_bcmp
1200 /* Like bcmp except the sign is meaningful.
1201 Result is negative if S1 is less than S2,
1202 positive if S1 is greater, 0 if S1 and S2 are equal. */
1205 __gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
1207 while (size > 0)
1209 unsigned char c1 = *s1++, c2 = *s2++;
1210 if (c1 != c2)
1211 return c1 - c2;
1212 size--;
1214 return 0;
1217 #endif
1219 /* __eprintf used to be used by GCC's private version of <assert.h>.
1220 We no longer provide that header, but this routine remains in libgcc.a
1221 for binary backward compatibility. Note that it is not included in
1222 the shared version of libgcc. */
1223 #ifdef L_eprintf
1224 #ifndef inhibit_libc
1226 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1227 #include <stdio.h>
1229 void
1230 __eprintf (const char *string, const char *expression,
1231 unsigned int line, const char *filename)
1233 fprintf (stderr, string, expression, line, filename);
1234 fflush (stderr);
1235 abort ();
1238 #endif
1239 #endif
1241 #ifdef L_bb
1243 struct bb_function_info {
1244 long checksum;
1245 int arc_count;
1246 const char *name;
1249 /* Structure emitted by --profile-arcs */
1250 struct bb
1252 long zero_word;
1253 const char *filename;
1254 gcov_type *counts;
1255 long ncounts;
1256 struct bb *next;
1258 /* Older GCC's did not emit these fields. */
1259 long sizeof_bb;
1260 struct bb_function_info *function_infos;
1263 #ifndef inhibit_libc
1265 /* Arc profile dumper. Requires atexit and stdio. */
1267 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1268 #include <stdio.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 /* Chain of per-object file bb structures. */
1278 static struct bb *bb_head;
1280 /* Dump the coverage counts. We merge with existing counts when
1281 possible, to avoid growing the .da files ad infinitum. */
1283 void
1284 __bb_exit_func (void)
1286 struct bb *ptr;
1287 int i;
1288 gcov_type program_sum = 0;
1289 gcov_type program_max = 0;
1290 long program_arcs = 0;
1291 gcov_type merged_sum = 0;
1292 gcov_type merged_max = 0;
1293 long merged_arcs = 0;
1295 #if defined (TARGET_HAS_F_SETLKW)
1296 struct flock s_flock;
1298 s_flock.l_type = F_WRLCK;
1299 s_flock.l_whence = SEEK_SET;
1300 s_flock.l_start = 0;
1301 s_flock.l_len = 0; /* Until EOF. */
1302 s_flock.l_pid = getpid ();
1303 #endif
1305 /* Non-merged stats for this program. */
1306 for (ptr = bb_head; ptr; ptr = ptr->next)
1308 for (i = 0; i < ptr->ncounts; i++)
1310 program_sum += ptr->counts[i];
1312 if (ptr->counts[i] > program_max)
1313 program_max = ptr->counts[i];
1315 program_arcs += ptr->ncounts;
1318 for (ptr = bb_head; ptr; ptr = ptr->next)
1320 FILE *da_file;
1321 gcov_type object_max = 0;
1322 gcov_type object_sum = 0;
1323 long object_functions = 0;
1324 int merging = 0;
1325 int error = 0;
1326 struct bb_function_info *fn_info;
1327 gcov_type *count_ptr;
1329 /* Open for modification */
1330 da_file = fopen (ptr->filename, "r+b");
1332 if (da_file)
1333 merging = 1;
1334 else
1336 /* Try for appending */
1337 da_file = fopen (ptr->filename, "ab");
1338 /* Some old systems might not allow the 'b' mode modifier.
1339 Therefore, try to open without it. This can lead to a
1340 race condition so that when you delete and re-create the
1341 file, the file might be opened in text mode, but then,
1342 you shouldn't delete the file in the first place. */
1343 if (!da_file)
1344 da_file = fopen (ptr->filename, "a");
1347 if (!da_file)
1349 fprintf (stderr, "arc profiling: Can't open output file %s.\n",
1350 ptr->filename);
1351 ptr->filename = 0;
1352 continue;
1355 #if defined (TARGET_HAS_F_SETLKW)
1356 /* After a fork, another process might try to read and/or write
1357 the same file simultanously. So if we can, lock the file to
1358 avoid race conditions. */
1359 while (fcntl (fileno (da_file), F_SETLKW, &s_flock)
1360 && errno == EINTR)
1361 continue;
1362 #endif
1363 for (fn_info = ptr->function_infos; fn_info->arc_count != -1; fn_info++)
1364 object_functions++;
1366 if (merging)
1368 /* Merge data from file. */
1369 long tmp_long;
1370 gcov_type tmp_gcov;
1372 if (/* magic */
1373 (__read_long (&tmp_long, da_file, 4) || tmp_long != -123l)
1374 /* functions in object file. */
1375 || (__read_long (&tmp_long, da_file, 4)
1376 || tmp_long != object_functions)
1377 /* extension block, skipped */
1378 || (__read_long (&tmp_long, da_file, 4)
1379 || fseek (da_file, tmp_long, SEEK_CUR)))
1381 read_error:;
1382 fprintf (stderr, "arc profiling: Error merging output file %s.\n",
1383 ptr->filename);
1384 clearerr (da_file);
1386 else
1388 /* Merge execution counts for each function. */
1389 count_ptr = ptr->counts;
1391 for (fn_info = ptr->function_infos; fn_info->arc_count != -1;
1392 fn_info++)
1394 if (/* function name delim */
1395 (__read_long (&tmp_long, da_file, 4)
1396 || tmp_long != -1)
1397 /* function name length */
1398 || (__read_long (&tmp_long, da_file, 4)
1399 || tmp_long != (long) strlen (fn_info->name))
1400 /* skip string */
1401 || fseek (da_file, ((tmp_long + 1) + 3) & ~3, SEEK_CUR)
1402 /* function name delim */
1403 || (__read_long (&tmp_long, da_file, 4)
1404 || tmp_long != -1))
1405 goto read_error;
1407 if (/* function checksum */
1408 (__read_long (&tmp_long, da_file, 4)
1409 || tmp_long != fn_info->checksum)
1410 /* arc count */
1411 || (__read_long (&tmp_long, da_file, 4)
1412 || tmp_long != fn_info->arc_count))
1413 goto read_error;
1415 for (i = fn_info->arc_count; i > 0; i--, count_ptr++)
1416 if (__read_gcov_type (&tmp_gcov, da_file, 8))
1417 goto read_error;
1418 else
1419 *count_ptr += tmp_gcov;
1422 fseek (da_file, 0, SEEK_SET);
1425 /* Calculate the per-object statistics. */
1426 for (i = 0; i < ptr->ncounts; i++)
1428 object_sum += ptr->counts[i];
1430 if (ptr->counts[i] > object_max)
1431 object_max = ptr->counts[i];
1433 merged_sum += object_sum;
1434 if (merged_max < object_max)
1435 merged_max = object_max;
1436 merged_arcs += ptr->ncounts;
1438 /* Write out the data. */
1439 if (/* magic */
1440 __write_long (-123, da_file, 4)
1441 /* number of functions in object file. */
1442 || __write_long (object_functions, da_file, 4)
1443 /* length of extra data in bytes. */
1444 || __write_long ((4 + 8 + 8) + (4 + 8 + 8), da_file, 4)
1446 /* whole program statistics. If merging write per-object
1447 now, rewrite later */
1448 /* number of instrumented arcs. */
1449 || __write_long (merging ? ptr->ncounts : program_arcs, da_file, 4)
1450 /* sum of counters. */
1451 || __write_gcov_type (merging ? object_sum : program_sum, da_file, 8)
1452 /* maximal counter. */
1453 || __write_gcov_type (merging ? object_max : program_max, da_file, 8)
1455 /* per-object statistics. */
1456 /* number of counters. */
1457 || __write_long (ptr->ncounts, da_file, 4)
1458 /* sum of counters. */
1459 || __write_gcov_type (object_sum, da_file, 8)
1460 /* maximal counter. */
1461 || __write_gcov_type (object_max, da_file, 8))
1463 write_error:;
1464 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1465 ptr->filename);
1466 error = 1;
1468 else
1470 /* Write execution counts for each function. */
1471 count_ptr = ptr->counts;
1473 for (fn_info = ptr->function_infos; fn_info->arc_count != -1;
1474 fn_info++)
1476 if (__write_gcov_string (fn_info->name,
1477 strlen (fn_info->name), da_file, -1)
1478 || __write_long (fn_info->checksum, da_file, 4)
1479 || __write_long (fn_info->arc_count, da_file, 4))
1480 goto write_error;
1482 for (i = fn_info->arc_count; i > 0; i--, count_ptr++)
1483 if (__write_gcov_type (*count_ptr, da_file, 8))
1484 goto write_error; /* RIP Edsger Dijkstra */
1488 if (fclose (da_file))
1490 fprintf (stderr, "arc profiling: Error closing output file %s.\n",
1491 ptr->filename);
1492 error = 1;
1494 if (error || !merging)
1495 ptr->filename = 0;
1498 /* Upate whole program statistics. */
1499 for (ptr = bb_head; ptr; ptr = ptr->next)
1500 if (ptr->filename)
1502 FILE *da_file;
1504 da_file = fopen (ptr->filename, "r+b");
1505 if (!da_file)
1507 fprintf (stderr, "arc profiling: Cannot reopen %s.\n",
1508 ptr->filename);
1509 continue;
1512 #if defined (TARGET_HAS_F_SETLKW)
1513 while (fcntl (fileno (da_file), F_SETLKW, &s_flock)
1514 && errno == EINTR)
1515 continue;
1516 #endif
1518 if (fseek (da_file, 4 * 3, SEEK_SET)
1519 /* number of instrumented arcs. */
1520 || __write_long (merged_arcs, da_file, 4)
1521 /* sum of counters. */
1522 || __write_gcov_type (merged_sum, da_file, 8)
1523 /* maximal counter. */
1524 || __write_gcov_type (merged_max, da_file, 8))
1525 fprintf (stderr, "arc profiling: Error updating program header %s.\n",
1526 ptr->filename);
1527 if (fclose (da_file))
1528 fprintf (stderr, "arc profiling: Error reclosing %s\n",
1529 ptr->filename);
1533 /* Add a new object file onto the bb chain. Invoked automatically
1534 when running an object file's global ctors. */
1536 void
1537 __bb_init_func (struct bb *blocks)
1539 if (blocks->zero_word)
1540 return;
1542 /* Initialize destructor and per-thread data. */
1543 if (!bb_head)
1544 atexit (__bb_exit_func);
1546 /* Set up linked list. */
1547 blocks->zero_word = 1;
1548 blocks->next = bb_head;
1549 bb_head = blocks;
1552 /* Called before fork or exec - write out profile information gathered so
1553 far and reset it to zero. This avoids duplication or loss of the
1554 profile information gathered so far. */
1556 void
1557 __bb_fork_func (void)
1559 struct bb *ptr;
1561 __bb_exit_func ();
1562 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1564 long i;
1565 for (i = ptr->ncounts - 1; i >= 0; i--)
1566 ptr->counts[i] = 0;
1570 #endif /* not inhibit_libc */
1571 #endif /* L_bb */
1573 #ifdef L_clear_cache
1574 /* Clear part of an instruction cache. */
1576 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1578 void
1579 __clear_cache (char *beg __attribute__((__unused__)),
1580 char *end __attribute__((__unused__)))
1582 #ifdef CLEAR_INSN_CACHE
1583 CLEAR_INSN_CACHE (beg, end);
1584 #else
1585 #ifdef INSN_CACHE_SIZE
1586 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1587 static int initialized;
1588 int offset;
1589 void *start_addr
1590 void *end_addr;
1591 typedef (*function_ptr) (void);
1593 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1594 /* It's cheaper to clear the whole cache.
1595 Put in a series of jump instructions so that calling the beginning
1596 of the cache will clear the whole thing. */
1598 if (! initialized)
1600 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1601 & -INSN_CACHE_LINE_WIDTH);
1602 int end_ptr = ptr + INSN_CACHE_SIZE;
1604 while (ptr < end_ptr)
1606 *(INSTRUCTION_TYPE *)ptr
1607 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1608 ptr += INSN_CACHE_LINE_WIDTH;
1610 *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1612 initialized = 1;
1615 /* Call the beginning of the sequence. */
1616 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1617 & -INSN_CACHE_LINE_WIDTH))
1618 ());
1620 #else /* Cache is large. */
1622 if (! initialized)
1624 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1625 & -INSN_CACHE_LINE_WIDTH);
1627 while (ptr < (int) array + sizeof array)
1629 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1630 ptr += INSN_CACHE_LINE_WIDTH;
1633 initialized = 1;
1636 /* Find the location in array that occupies the same cache line as BEG. */
1638 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1639 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1640 & -INSN_CACHE_PLANE_SIZE)
1641 + offset);
1643 /* Compute the cache alignment of the place to stop clearing. */
1644 #if 0 /* This is not needed for gcc's purposes. */
1645 /* If the block to clear is bigger than a cache plane,
1646 we clear the entire cache, and OFFSET is already correct. */
1647 if (end < beg + INSN_CACHE_PLANE_SIZE)
1648 #endif
1649 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1650 & -INSN_CACHE_LINE_WIDTH)
1651 & (INSN_CACHE_PLANE_SIZE - 1));
1653 #if INSN_CACHE_DEPTH > 1
1654 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1655 if (end_addr <= start_addr)
1656 end_addr += INSN_CACHE_PLANE_SIZE;
1658 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1660 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1661 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1663 while (addr != stop)
1665 /* Call the return instruction at ADDR. */
1666 ((function_ptr) addr) ();
1668 addr += INSN_CACHE_LINE_WIDTH;
1671 #else /* just one plane */
1674 /* Call the return instruction at START_ADDR. */
1675 ((function_ptr) start_addr) ();
1677 start_addr += INSN_CACHE_LINE_WIDTH;
1679 while ((start_addr % INSN_CACHE_SIZE) != offset);
1680 #endif /* just one plane */
1681 #endif /* Cache is large */
1682 #endif /* Cache exists */
1683 #endif /* CLEAR_INSN_CACHE */
1686 #endif /* L_clear_cache */
1688 #ifdef L_trampoline
1690 /* Jump to a trampoline, loading the static chain address. */
1692 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
1694 long
1695 getpagesize (void)
1697 #ifdef _ALPHA_
1698 return 8192;
1699 #else
1700 return 4096;
1701 #endif
1704 #ifdef __i386__
1705 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
1706 #endif
1709 mprotect (char *addr, int len, int prot)
1711 int np, op;
1713 if (prot == 7)
1714 np = 0x40;
1715 else if (prot == 5)
1716 np = 0x20;
1717 else if (prot == 4)
1718 np = 0x10;
1719 else if (prot == 3)
1720 np = 0x04;
1721 else if (prot == 1)
1722 np = 0x02;
1723 else if (prot == 0)
1724 np = 0x01;
1726 if (VirtualProtect (addr, len, np, &op))
1727 return 0;
1728 else
1729 return -1;
1732 #endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
1734 #ifdef TRANSFER_FROM_TRAMPOLINE
1735 TRANSFER_FROM_TRAMPOLINE
1736 #endif
1738 #ifdef __sysV68__
1740 #include <sys/signal.h>
1741 #include <errno.h>
1743 /* Motorola forgot to put memctl.o in the libp version of libc881.a,
1744 so define it here, because we need it in __clear_insn_cache below */
1745 /* On older versions of this OS, no memctl or MCT_TEXT are defined;
1746 hence we enable this stuff only if MCT_TEXT is #define'd. */
1748 #ifdef MCT_TEXT
1749 asm("\n\
1750 global memctl\n\
1751 memctl:\n\
1752 movq &75,%d0\n\
1753 trap &0\n\
1754 bcc.b noerror\n\
1755 jmp cerror%\n\
1756 noerror:\n\
1757 movq &0,%d0\n\
1758 rts");
1759 #endif
1761 /* Clear instruction cache so we can call trampolines on stack.
1762 This is called from FINALIZE_TRAMPOLINE in mot3300.h. */
1764 void
1765 __clear_insn_cache (void)
1767 #ifdef MCT_TEXT
1768 int save_errno;
1770 /* Preserve errno, because users would be surprised to have
1771 errno changing without explicitly calling any system-call. */
1772 save_errno = errno;
1774 /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache.
1775 No need to use an address derived from _start or %sp, as 0 works also. */
1776 memctl(0, 4096, MCT_TEXT);
1777 errno = save_errno;
1778 #endif
1781 #endif /* __sysV68__ */
1782 #endif /* L_trampoline */
1784 #ifndef __CYGWIN__
1785 #ifdef L__main
1787 #include "gbl-ctors.h"
1788 /* Some systems use __main in a way incompatible with its use in gcc, in these
1789 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
1790 give the same symbol without quotes for an alternative entry point. You
1791 must define both, or neither. */
1792 #ifndef NAME__MAIN
1793 #define NAME__MAIN "__main"
1794 #define SYMBOL__MAIN __main
1795 #endif
1797 #ifdef INIT_SECTION_ASM_OP
1798 #undef HAS_INIT_SECTION
1799 #define HAS_INIT_SECTION
1800 #endif
1802 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
1804 /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
1805 code to run constructors. In that case, we need to handle EH here, too. */
1807 #ifdef EH_FRAME_SECTION_NAME
1808 #include "unwind-dw2-fde.h"
1809 extern unsigned char __EH_FRAME_BEGIN__[];
1810 #endif
1812 /* Run all the global destructors on exit from the program. */
1814 void
1815 __do_global_dtors (void)
1817 #ifdef DO_GLOBAL_DTORS_BODY
1818 DO_GLOBAL_DTORS_BODY;
1819 #else
1820 static func_ptr *p = __DTOR_LIST__ + 1;
1821 while (*p)
1823 p++;
1824 (*(p-1)) ();
1826 #endif
1827 #if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION)
1829 static int completed = 0;
1830 if (! completed)
1832 completed = 1;
1833 __deregister_frame_info (__EH_FRAME_BEGIN__);
1836 #endif
1838 #endif
1840 #ifndef HAS_INIT_SECTION
1841 /* Run all the global constructors on entry to the program. */
1843 void
1844 __do_global_ctors (void)
1846 #ifdef EH_FRAME_SECTION_NAME
1848 static struct object object;
1849 __register_frame_info (__EH_FRAME_BEGIN__, &object);
1851 #endif
1852 DO_GLOBAL_CTORS_BODY;
1853 atexit (__do_global_dtors);
1855 #endif /* no HAS_INIT_SECTION */
1857 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
1858 /* Subroutine called automatically by `main'.
1859 Compiling a global function named `main'
1860 produces an automatic call to this function at the beginning.
1862 For many systems, this routine calls __do_global_ctors.
1863 For systems which support a .init section we use the .init section
1864 to run __do_global_ctors, so we need not do anything here. */
1866 void
1867 SYMBOL__MAIN ()
1869 /* Support recursive calls to `main': run initializers just once. */
1870 static int initialized;
1871 if (! initialized)
1873 initialized = 1;
1874 __do_global_ctors ();
1877 #endif /* no HAS_INIT_SECTION or INVOKE__main */
1879 #endif /* L__main */
1880 #endif /* __CYGWIN__ */
1882 #ifdef L_ctors
1884 #include "gbl-ctors.h"
1886 /* Provide default definitions for the lists of constructors and
1887 destructors, so that we don't get linker errors. These symbols are
1888 intentionally bss symbols, so that gld and/or collect will provide
1889 the right values. */
1891 /* We declare the lists here with two elements each,
1892 so that they are valid empty lists if no other definition is loaded.
1894 If we are using the old "set" extensions to have the gnu linker
1895 collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
1896 must be in the bss/common section.
1898 Long term no port should use those extensions. But many still do. */
1899 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
1900 #if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2)
1901 func_ptr __CTOR_LIST__[2] = {0, 0};
1902 func_ptr __DTOR_LIST__[2] = {0, 0};
1903 #else
1904 func_ptr __CTOR_LIST__[2];
1905 func_ptr __DTOR_LIST__[2];
1906 #endif
1907 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1908 #endif /* L_ctors */
1910 #ifdef L_exit
1912 #include "gbl-ctors.h"
1914 #ifdef NEED_ATEXIT
1916 #ifndef ON_EXIT
1918 # include <errno.h>
1920 static func_ptr *atexit_chain = 0;
1921 static long atexit_chain_length = 0;
1922 static volatile long last_atexit_chain_slot = -1;
1925 atexit (func_ptr func)
1927 if (++last_atexit_chain_slot == atexit_chain_length)
1929 atexit_chain_length += 32;
1930 if (atexit_chain)
1931 atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
1932 * sizeof (func_ptr));
1933 else
1934 atexit_chain = (func_ptr *) malloc (atexit_chain_length
1935 * sizeof (func_ptr));
1936 if (! atexit_chain)
1938 atexit_chain_length = 0;
1939 last_atexit_chain_slot = -1;
1940 errno = ENOMEM;
1941 return (-1);
1944 atexit_chain[last_atexit_chain_slot] = func;
1945 return (0);
1948 extern void _cleanup (void);
1949 extern void _exit (int) __attribute__ ((__noreturn__));
1951 void
1952 exit (int status)
1954 if (atexit_chain)
1956 for ( ; last_atexit_chain_slot-- >= 0; )
1958 (*atexit_chain[last_atexit_chain_slot + 1]) ();
1959 atexit_chain[last_atexit_chain_slot + 1] = 0;
1961 free (atexit_chain);
1962 atexit_chain = 0;
1964 #ifdef EXIT_BODY
1965 EXIT_BODY;
1966 #else
1967 _cleanup ();
1968 #endif
1969 _exit (status);
1972 #else /* ON_EXIT */
1974 /* Simple; we just need a wrapper for ON_EXIT. */
1976 atexit (func_ptr func)
1978 return ON_EXIT (func);
1981 #endif /* ON_EXIT */
1982 #endif /* NEED_ATEXIT */
1984 #endif /* L_exit */