Add x prefix to v850e case for handling --with-cpu=v850e.
[official-gcc.git] / gcc / libgcc2.c
blob8c10689f02c34b7cfcdfe0c1e36c672df8a313eb
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))
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 --profile-arcs */
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 /* Arc profile dumper. Requires atexit and stdio. */
1264 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1265 #include <stdio.h>
1267 #include "gcov-io.h"
1268 #include <string.h>
1269 #ifdef TARGET_HAS_F_SETLKW
1270 #include <fcntl.h>
1271 #include <errno.h>
1272 #endif
1274 /* Chain of per-object file bb structures. */
1275 static struct bb *bb_head;
1277 /* Dump the coverage counts. We merge with existing counts when
1278 possible, to avoid growing the .da files ad infinitum. */
1280 void
1281 __bb_exit_func (void)
1283 struct bb *ptr;
1284 int i;
1285 gcov_type program_sum = 0;
1286 gcov_type program_max = 0;
1287 long program_arcs = 0;
1288 gcov_type merged_sum = 0;
1289 gcov_type merged_max = 0;
1290 long merged_arcs = 0;
1292 #if defined (TARGET_HAS_F_SETLKW)
1293 struct flock s_flock;
1295 s_flock.l_type = F_WRLCK;
1296 s_flock.l_whence = SEEK_SET;
1297 s_flock.l_start = 0;
1298 s_flock.l_len = 0; /* Until EOF. */
1299 s_flock.l_pid = getpid ();
1300 #endif
1302 /* Non-merged stats for this program. */
1303 for (ptr = bb_head; ptr; ptr = ptr->next)
1305 for (i = 0; i < ptr->ncounts; i++)
1307 program_sum += ptr->counts[i];
1309 if (ptr->counts[i] > program_max)
1310 program_max = ptr->counts[i];
1312 program_arcs += ptr->ncounts;
1315 for (ptr = bb_head; ptr; ptr = ptr->next)
1317 FILE *da_file;
1318 gcov_type object_max = 0;
1319 gcov_type object_sum = 0;
1320 long object_functions = 0;
1321 int merging = 0;
1322 int error = 0;
1323 struct bb_function_info *fn_info;
1324 gcov_type *count_ptr;
1326 /* Open for modification */
1327 da_file = fopen (ptr->filename, "r+b");
1329 if (da_file)
1330 merging = 1;
1331 else
1333 /* Try for appending */
1334 da_file = fopen (ptr->filename, "ab");
1335 /* Some old systems might not allow the 'b' mode modifier.
1336 Therefore, try to open without it. This can lead to a
1337 race condition so that when you delete and re-create the
1338 file, the file might be opened in text mode, but then,
1339 you shouldn't delete the file in the first place. */
1340 if (!da_file)
1341 da_file = fopen (ptr->filename, "a");
1344 if (!da_file)
1346 fprintf (stderr, "arc profiling: Can't open output file %s.\n",
1347 ptr->filename);
1348 ptr->filename = 0;
1349 continue;
1352 #if defined (TARGET_HAS_F_SETLKW)
1353 /* After a fork, another process might try to read and/or write
1354 the same file simultanously. So if we can, lock the file to
1355 avoid race conditions. */
1356 while (fcntl (fileno (da_file), F_SETLKW, &s_flock)
1357 && errno == EINTR)
1358 continue;
1359 #endif
1360 for (fn_info = ptr->function_infos; fn_info->arc_count != -1; fn_info++)
1361 object_functions++;
1363 if (merging)
1365 /* Merge data from file. */
1366 long tmp_long;
1367 gcov_type tmp_gcov;
1369 if (/* magic */
1370 (__read_long (&tmp_long, da_file, 4) || tmp_long != -123l)
1371 /* functions in object file. */
1372 || (__read_long (&tmp_long, da_file, 4)
1373 || tmp_long != object_functions)
1374 /* extension block, skipped */
1375 || (__read_long (&tmp_long, da_file, 4)
1376 || fseek (da_file, tmp_long, SEEK_CUR)))
1378 read_error:;
1379 fprintf (stderr, "arc profiling: Error merging output file %s.\n",
1380 ptr->filename);
1381 clearerr (da_file);
1383 else
1385 /* Merge execution counts for each function. */
1386 count_ptr = ptr->counts;
1388 for (fn_info = ptr->function_infos; fn_info->arc_count != -1;
1389 fn_info++)
1391 if (/* function name delim */
1392 (__read_long (&tmp_long, da_file, 4)
1393 || tmp_long != -1)
1394 /* function name length */
1395 || (__read_long (&tmp_long, da_file, 4)
1396 || tmp_long != (long) strlen (fn_info->name))
1397 /* skip string */
1398 || fseek (da_file, ((tmp_long + 1) + 3) & ~3, SEEK_CUR)
1399 /* function name delim */
1400 || (__read_long (&tmp_long, da_file, 4)
1401 || tmp_long != -1))
1402 goto read_error;
1404 if (/* function checksum */
1405 (__read_long (&tmp_long, da_file, 4)
1406 || tmp_long != fn_info->checksum)
1407 /* arc count */
1408 || (__read_long (&tmp_long, da_file, 4)
1409 || tmp_long != fn_info->arc_count))
1410 goto read_error;
1412 for (i = fn_info->arc_count; i > 0; i--, count_ptr++)
1413 if (__read_gcov_type (&tmp_gcov, da_file, 8))
1414 goto read_error;
1415 else
1416 *count_ptr += tmp_gcov;
1419 fseek (da_file, 0, SEEK_SET);
1422 /* Calculate the per-object statistics. */
1423 for (i = 0; i < ptr->ncounts; i++)
1425 object_sum += ptr->counts[i];
1427 if (ptr->counts[i] > object_max)
1428 object_max = ptr->counts[i];
1430 merged_sum += object_sum;
1431 if (merged_max < object_max)
1432 merged_max = object_max;
1433 merged_arcs += ptr->ncounts;
1435 /* Write out the data. */
1436 if (/* magic */
1437 __write_long (-123, da_file, 4)
1438 /* number of functions in object file. */
1439 || __write_long (object_functions, da_file, 4)
1440 /* length of extra data in bytes. */
1441 || __write_long ((4 + 8 + 8) + (4 + 8 + 8), da_file, 4)
1443 /* whole program statistics. If merging write per-object
1444 now, rewrite later */
1445 /* number of instrumented arcs. */
1446 || __write_long (merging ? ptr->ncounts : program_arcs, da_file, 4)
1447 /* sum of counters. */
1448 || __write_gcov_type (merging ? object_sum : program_sum, da_file, 8)
1449 /* maximal counter. */
1450 || __write_gcov_type (merging ? object_max : program_max, da_file, 8)
1452 /* per-object statistics. */
1453 /* number of counters. */
1454 || __write_long (ptr->ncounts, da_file, 4)
1455 /* sum of counters. */
1456 || __write_gcov_type (object_sum, da_file, 8)
1457 /* maximal counter. */
1458 || __write_gcov_type (object_max, da_file, 8))
1460 write_error:;
1461 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1462 ptr->filename);
1463 error = 1;
1465 else
1467 /* Write execution counts for each function. */
1468 count_ptr = ptr->counts;
1470 for (fn_info = ptr->function_infos; fn_info->arc_count != -1;
1471 fn_info++)
1473 if (__write_gcov_string (fn_info->name,
1474 strlen (fn_info->name), da_file, -1)
1475 || __write_long (fn_info->checksum, da_file, 4)
1476 || __write_long (fn_info->arc_count, da_file, 4))
1477 goto write_error;
1479 for (i = fn_info->arc_count; i > 0; i--, count_ptr++)
1480 if (__write_gcov_type (*count_ptr, da_file, 8))
1481 goto write_error; /* RIP Edsger Dijkstra */
1485 if (fclose (da_file))
1487 fprintf (stderr, "arc profiling: Error closing output file %s.\n",
1488 ptr->filename);
1489 error = 1;
1491 if (error || !merging)
1492 ptr->filename = 0;
1495 /* Upate whole program statistics. */
1496 for (ptr = bb_head; ptr; ptr = ptr->next)
1497 if (ptr->filename)
1499 FILE *da_file;
1501 da_file = fopen (ptr->filename, "r+b");
1502 if (!da_file)
1504 fprintf (stderr, "arc profiling: Cannot reopen %s.\n",
1505 ptr->filename);
1506 continue;
1509 #if defined (TARGET_HAS_F_SETLKW)
1510 while (fcntl (fileno (da_file), F_SETLKW, &s_flock)
1511 && errno == EINTR)
1512 continue;
1513 #endif
1515 if (fseek (da_file, 4 * 3, SEEK_SET)
1516 /* number of instrumented arcs. */
1517 || __write_long (merged_arcs, da_file, 4)
1518 /* sum of counters. */
1519 || __write_gcov_type (merged_sum, da_file, 8)
1520 /* maximal counter. */
1521 || __write_gcov_type (merged_max, da_file, 8))
1522 fprintf (stderr, "arc profiling: Error updating program header %s.\n",
1523 ptr->filename);
1524 if (fclose (da_file))
1525 fprintf (stderr, "arc profiling: Error reclosing %s\n",
1526 ptr->filename);
1530 /* Add a new object file onto the bb chain. Invoked automatically
1531 when running an object file's global ctors. */
1533 void
1534 __bb_init_func (struct bb *blocks)
1536 if (blocks->zero_word)
1537 return;
1539 /* Initialize destructor and per-thread data. */
1540 if (!bb_head)
1541 atexit (__bb_exit_func);
1543 /* Set up linked list. */
1544 blocks->zero_word = 1;
1545 blocks->next = bb_head;
1546 bb_head = blocks;
1549 /* Called before fork or exec - write out profile information gathered so
1550 far and reset it to zero. This avoids duplication or loss of the
1551 profile information gathered so far. */
1553 void
1554 __bb_fork_func (void)
1556 struct bb *ptr;
1558 __bb_exit_func ();
1559 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1561 long i;
1562 for (i = ptr->ncounts - 1; i >= 0; i--)
1563 ptr->counts[i] = 0;
1567 #endif /* not inhibit_libc */
1568 #endif /* L_bb */
1570 #ifdef L_clear_cache
1571 /* Clear part of an instruction cache. */
1573 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1575 void
1576 __clear_cache (char *beg __attribute__((__unused__)),
1577 char *end __attribute__((__unused__)))
1579 #ifdef CLEAR_INSN_CACHE
1580 CLEAR_INSN_CACHE (beg, end);
1581 #else
1582 #ifdef INSN_CACHE_SIZE
1583 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1584 static int initialized;
1585 int offset;
1586 void *start_addr
1587 void *end_addr;
1588 typedef (*function_ptr) (void);
1590 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1591 /* It's cheaper to clear the whole cache.
1592 Put in a series of jump instructions so that calling the beginning
1593 of the cache will clear the whole thing. */
1595 if (! initialized)
1597 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1598 & -INSN_CACHE_LINE_WIDTH);
1599 int end_ptr = ptr + INSN_CACHE_SIZE;
1601 while (ptr < end_ptr)
1603 *(INSTRUCTION_TYPE *)ptr
1604 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1605 ptr += INSN_CACHE_LINE_WIDTH;
1607 *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1609 initialized = 1;
1612 /* Call the beginning of the sequence. */
1613 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1614 & -INSN_CACHE_LINE_WIDTH))
1615 ());
1617 #else /* Cache is large. */
1619 if (! initialized)
1621 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1622 & -INSN_CACHE_LINE_WIDTH);
1624 while (ptr < (int) array + sizeof array)
1626 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1627 ptr += INSN_CACHE_LINE_WIDTH;
1630 initialized = 1;
1633 /* Find the location in array that occupies the same cache line as BEG. */
1635 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1636 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1637 & -INSN_CACHE_PLANE_SIZE)
1638 + offset);
1640 /* Compute the cache alignment of the place to stop clearing. */
1641 #if 0 /* This is not needed for gcc's purposes. */
1642 /* If the block to clear is bigger than a cache plane,
1643 we clear the entire cache, and OFFSET is already correct. */
1644 if (end < beg + INSN_CACHE_PLANE_SIZE)
1645 #endif
1646 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1647 & -INSN_CACHE_LINE_WIDTH)
1648 & (INSN_CACHE_PLANE_SIZE - 1));
1650 #if INSN_CACHE_DEPTH > 1
1651 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1652 if (end_addr <= start_addr)
1653 end_addr += INSN_CACHE_PLANE_SIZE;
1655 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1657 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1658 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1660 while (addr != stop)
1662 /* Call the return instruction at ADDR. */
1663 ((function_ptr) addr) ();
1665 addr += INSN_CACHE_LINE_WIDTH;
1668 #else /* just one plane */
1671 /* Call the return instruction at START_ADDR. */
1672 ((function_ptr) start_addr) ();
1674 start_addr += INSN_CACHE_LINE_WIDTH;
1676 while ((start_addr % INSN_CACHE_SIZE) != offset);
1677 #endif /* just one plane */
1678 #endif /* Cache is large */
1679 #endif /* Cache exists */
1680 #endif /* CLEAR_INSN_CACHE */
1683 #endif /* L_clear_cache */
1685 #ifdef L_trampoline
1687 /* Jump to a trampoline, loading the static chain address. */
1689 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
1691 long
1692 getpagesize (void)
1694 #ifdef _ALPHA_
1695 return 8192;
1696 #else
1697 return 4096;
1698 #endif
1701 #ifdef __i386__
1702 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
1703 #endif
1706 mprotect (char *addr, int len, int prot)
1708 int np, op;
1710 if (prot == 7)
1711 np = 0x40;
1712 else if (prot == 5)
1713 np = 0x20;
1714 else if (prot == 4)
1715 np = 0x10;
1716 else if (prot == 3)
1717 np = 0x04;
1718 else if (prot == 1)
1719 np = 0x02;
1720 else if (prot == 0)
1721 np = 0x01;
1723 if (VirtualProtect (addr, len, np, &op))
1724 return 0;
1725 else
1726 return -1;
1729 #endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
1731 #ifdef TRANSFER_FROM_TRAMPOLINE
1732 TRANSFER_FROM_TRAMPOLINE
1733 #endif
1735 #ifdef __sysV68__
1737 #include <sys/signal.h>
1738 #include <errno.h>
1740 /* Motorola forgot to put memctl.o in the libp version of libc881.a,
1741 so define it here, because we need it in __clear_insn_cache below */
1742 /* On older versions of this OS, no memctl or MCT_TEXT are defined;
1743 hence we enable this stuff only if MCT_TEXT is #define'd. */
1745 #ifdef MCT_TEXT
1746 asm("\n\
1747 global memctl\n\
1748 memctl:\n\
1749 movq &75,%d0\n\
1750 trap &0\n\
1751 bcc.b noerror\n\
1752 jmp cerror%\n\
1753 noerror:\n\
1754 movq &0,%d0\n\
1755 rts");
1756 #endif
1758 /* Clear instruction cache so we can call trampolines on stack.
1759 This is called from FINALIZE_TRAMPOLINE in mot3300.h. */
1761 void
1762 __clear_insn_cache (void)
1764 #ifdef MCT_TEXT
1765 int save_errno;
1767 /* Preserve errno, because users would be surprised to have
1768 errno changing without explicitly calling any system-call. */
1769 save_errno = errno;
1771 /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache.
1772 No need to use an address derived from _start or %sp, as 0 works also. */
1773 memctl(0, 4096, MCT_TEXT);
1774 errno = save_errno;
1775 #endif
1778 #endif /* __sysV68__ */
1779 #endif /* L_trampoline */
1781 #ifndef __CYGWIN__
1782 #ifdef L__main
1784 #include "gbl-ctors.h"
1785 /* Some systems use __main in a way incompatible with its use in gcc, in these
1786 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
1787 give the same symbol without quotes for an alternative entry point. You
1788 must define both, or neither. */
1789 #ifndef NAME__MAIN
1790 #define NAME__MAIN "__main"
1791 #define SYMBOL__MAIN __main
1792 #endif
1794 #ifdef INIT_SECTION_ASM_OP
1795 #undef HAS_INIT_SECTION
1796 #define HAS_INIT_SECTION
1797 #endif
1799 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
1801 /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
1802 code to run constructors. In that case, we need to handle EH here, too. */
1804 #ifdef EH_FRAME_SECTION_NAME
1805 #include "unwind-dw2-fde.h"
1806 extern unsigned char __EH_FRAME_BEGIN__[];
1807 #endif
1809 /* Run all the global destructors on exit from the program. */
1811 void
1812 __do_global_dtors (void)
1814 #ifdef DO_GLOBAL_DTORS_BODY
1815 DO_GLOBAL_DTORS_BODY;
1816 #else
1817 static func_ptr *p = __DTOR_LIST__ + 1;
1818 while (*p)
1820 p++;
1821 (*(p-1)) ();
1823 #endif
1824 #if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION)
1826 static int completed = 0;
1827 if (! completed)
1829 completed = 1;
1830 __deregister_frame_info (__EH_FRAME_BEGIN__);
1833 #endif
1835 #endif
1837 #ifndef HAS_INIT_SECTION
1838 /* Run all the global constructors on entry to the program. */
1840 void
1841 __do_global_ctors (void)
1843 #ifdef EH_FRAME_SECTION_NAME
1845 static struct object object;
1846 __register_frame_info (__EH_FRAME_BEGIN__, &object);
1848 #endif
1849 DO_GLOBAL_CTORS_BODY;
1850 atexit (__do_global_dtors);
1852 #endif /* no HAS_INIT_SECTION */
1854 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
1855 /* Subroutine called automatically by `main'.
1856 Compiling a global function named `main'
1857 produces an automatic call to this function at the beginning.
1859 For many systems, this routine calls __do_global_ctors.
1860 For systems which support a .init section we use the .init section
1861 to run __do_global_ctors, so we need not do anything here. */
1863 void
1864 SYMBOL__MAIN ()
1866 /* Support recursive calls to `main': run initializers just once. */
1867 static int initialized;
1868 if (! initialized)
1870 initialized = 1;
1871 __do_global_ctors ();
1874 #endif /* no HAS_INIT_SECTION or INVOKE__main */
1876 #endif /* L__main */
1877 #endif /* __CYGWIN__ */
1879 #ifdef L_ctors
1881 #include "gbl-ctors.h"
1883 /* Provide default definitions for the lists of constructors and
1884 destructors, so that we don't get linker errors. These symbols are
1885 intentionally bss symbols, so that gld and/or collect will provide
1886 the right values. */
1888 /* We declare the lists here with two elements each,
1889 so that they are valid empty lists if no other definition is loaded.
1891 If we are using the old "set" extensions to have the gnu linker
1892 collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
1893 must be in the bss/common section.
1895 Long term no port should use those extensions. But many still do. */
1896 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
1897 #if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2)
1898 func_ptr __CTOR_LIST__[2] = {0, 0};
1899 func_ptr __DTOR_LIST__[2] = {0, 0};
1900 #else
1901 func_ptr __CTOR_LIST__[2];
1902 func_ptr __DTOR_LIST__[2];
1903 #endif
1904 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1905 #endif /* L_ctors */
1907 #ifdef L_exit
1909 #include "gbl-ctors.h"
1911 #ifdef NEED_ATEXIT
1913 #ifndef ON_EXIT
1915 # include <errno.h>
1917 static func_ptr *atexit_chain = 0;
1918 static long atexit_chain_length = 0;
1919 static volatile long last_atexit_chain_slot = -1;
1922 atexit (func_ptr func)
1924 if (++last_atexit_chain_slot == atexit_chain_length)
1926 atexit_chain_length += 32;
1927 if (atexit_chain)
1928 atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
1929 * sizeof (func_ptr));
1930 else
1931 atexit_chain = (func_ptr *) malloc (atexit_chain_length
1932 * sizeof (func_ptr));
1933 if (! atexit_chain)
1935 atexit_chain_length = 0;
1936 last_atexit_chain_slot = -1;
1937 errno = ENOMEM;
1938 return (-1);
1941 atexit_chain[last_atexit_chain_slot] = func;
1942 return (0);
1945 extern void _cleanup (void);
1946 extern void _exit (int) __attribute__ ((__noreturn__));
1948 void
1949 exit (int status)
1951 if (atexit_chain)
1953 for ( ; last_atexit_chain_slot-- >= 0; )
1955 (*atexit_chain[last_atexit_chain_slot + 1]) ();
1956 atexit_chain[last_atexit_chain_slot + 1] = 0;
1958 free (atexit_chain);
1959 atexit_chain = 0;
1961 #ifdef EXIT_BODY
1962 EXIT_BODY;
1963 #else
1964 _cleanup ();
1965 #endif
1966 _exit (status);
1969 #else /* ON_EXIT */
1971 /* Simple; we just need a wrapper for ON_EXIT. */
1973 atexit (func_ptr func)
1975 return ON_EXIT (func);
1978 #endif /* ON_EXIT */
1979 #endif /* NEED_ATEXIT */
1981 #endif /* L_exit */