Mark ChangeLog
[official-gcc.git] / gcc / libgcc2.c
blobdd5eee7dbb520617a4ef19e99297be4332501e8f
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 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
47 #if defined (L_divdi3) || defined (L_moddi3)
48 static inline
49 #endif
50 DWtype
51 __negdi2 (DWtype u)
53 DWunion w;
54 DWunion uu;
56 uu.ll = u;
58 w.s.low = -uu.s.low;
59 w.s.high = -uu.s.high - ((UWtype) w.s.low > 0);
61 return w.ll;
63 #endif
65 #ifdef L_addvsi3
66 Wtype
67 __addvsi3 (Wtype a, Wtype b)
69 Wtype w;
71 w = a + b;
73 if (b >= 0 ? w < a : w > a)
74 abort ();
76 return w;
78 #endif
80 #ifdef L_addvdi3
81 DWtype
82 __addvdi3 (DWtype a, DWtype b)
84 DWtype w;
86 w = a + b;
88 if (b >= 0 ? w < a : w > a)
89 abort ();
91 return w;
93 #endif
95 #ifdef L_subvsi3
96 Wtype
97 __subvsi3 (Wtype a, Wtype b)
99 #ifdef L_addvsi3
100 return __addvsi3 (a, (-b));
101 #else
102 DWtype w;
104 w = a - b;
106 if (b >= 0 ? w > a : w < a)
107 abort ();
109 return w;
110 #endif
112 #endif
114 #ifdef L_subvdi3
115 DWtype
116 __subvdi3 (DWtype a, DWtype b)
118 #ifdef L_addvdi3
119 return (a, (-b));
120 #else
121 DWtype w;
123 w = a - b;
125 if (b >= 0 ? w > a : w < a)
126 abort ();
128 return w;
129 #endif
131 #endif
133 #ifdef L_mulvsi3
134 Wtype
135 __mulvsi3 (Wtype a, Wtype b)
137 DWtype w;
139 w = a * b;
141 if (((a >= 0) == (b >= 0)) ? w < 0 : w > 0)
142 abort ();
144 return w;
146 #endif
148 #ifdef L_negvsi2
149 Wtype
150 __negvsi2 (Wtype a)
152 Wtype w;
154 w = -a;
156 if (a >= 0 ? w > 0 : w < 0)
157 abort ();
159 return w;
161 #endif
163 #ifdef L_negvdi2
164 DWtype
165 __negvdi2 (DWtype a)
167 DWtype w;
169 w = -a;
171 if (a >= 0 ? w > 0 : w < 0)
172 abort ();
174 return w;
176 #endif
178 #ifdef L_absvsi2
179 Wtype
180 __absvsi2 (Wtype a)
182 Wtype w = a;
184 if (a < 0)
185 #ifdef L_negvsi2
186 w = __negvsi2 (a);
187 #else
188 w = -a;
190 if (w < 0)
191 abort ();
192 #endif
194 return w;
196 #endif
198 #ifdef L_absvdi2
199 DWtype
200 __absvdi2 (DWtype a)
202 DWtype w = a;
204 if (a < 0)
205 #ifdef L_negvsi2
206 w = __negvsi2 (a);
207 #else
208 w = -a;
210 if (w < 0)
211 abort ();
212 #endif
214 return w;
216 #endif
218 #ifdef L_mulvdi3
219 DWtype
220 __mulvdi3 (DWtype u, DWtype v)
222 DWtype w;
224 w = u * v;
226 if (((u >= 0) == (v >= 0)) ? w < 0 : w > 0)
227 abort ();
229 return w;
231 #endif
234 /* Unless shift functions are defined whith full ANSI prototypes,
235 parameter b will be promoted to int if word_type is smaller than an int. */
236 #ifdef L_lshrdi3
237 DWtype
238 __lshrdi3 (DWtype u, word_type b)
240 DWunion w;
241 word_type bm;
242 DWunion uu;
244 if (b == 0)
245 return u;
247 uu.ll = u;
249 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
250 if (bm <= 0)
252 w.s.high = 0;
253 w.s.low = (UWtype) uu.s.high >> -bm;
255 else
257 UWtype carries = (UWtype) uu.s.high << bm;
259 w.s.high = (UWtype) uu.s.high >> b;
260 w.s.low = ((UWtype) uu.s.low >> b) | carries;
263 return w.ll;
265 #endif
267 #ifdef L_ashldi3
268 DWtype
269 __ashldi3 (DWtype u, word_type b)
271 DWunion w;
272 word_type bm;
273 DWunion uu;
275 if (b == 0)
276 return u;
278 uu.ll = u;
280 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
281 if (bm <= 0)
283 w.s.low = 0;
284 w.s.high = (UWtype) uu.s.low << -bm;
286 else
288 UWtype carries = (UWtype) uu.s.low >> bm;
290 w.s.low = (UWtype) uu.s.low << b;
291 w.s.high = ((UWtype) uu.s.high << b) | carries;
294 return w.ll;
296 #endif
298 #ifdef L_ashrdi3
299 DWtype
300 __ashrdi3 (DWtype u, word_type b)
302 DWunion w;
303 word_type bm;
304 DWunion uu;
306 if (b == 0)
307 return u;
309 uu.ll = u;
311 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
312 if (bm <= 0)
314 /* w.s.high = 1..1 or 0..0 */
315 w.s.high = uu.s.high >> (sizeof (Wtype) * BITS_PER_UNIT - 1);
316 w.s.low = uu.s.high >> -bm;
318 else
320 UWtype carries = (UWtype) uu.s.high << bm;
322 w.s.high = uu.s.high >> b;
323 w.s.low = ((UWtype) uu.s.low >> b) | carries;
326 return w.ll;
328 #endif
330 #ifdef L_ffsdi2
331 DWtype
332 __ffsdi2 (DWtype u)
334 DWunion uu;
335 UWtype word, count, add;
337 uu.ll = u;
338 if (uu.s.low != 0)
339 word = uu.s.low, add = 0;
340 else if (uu.s.high != 0)
341 word = uu.s.high, add = BITS_PER_UNIT * sizeof (Wtype);
342 else
343 return 0;
345 count_trailing_zeros (count, word);
346 return count + add + 1;
348 #endif
350 #ifdef L_muldi3
351 DWtype
352 __muldi3 (DWtype u, DWtype v)
354 DWunion w;
355 DWunion uu, vv;
357 uu.ll = u,
358 vv.ll = v;
360 w.ll = __umulsidi3 (uu.s.low, vv.s.low);
361 w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
362 + (UWtype) uu.s.high * (UWtype) vv.s.low);
364 return w.ll;
366 #endif
368 #ifdef L_udiv_w_sdiv
369 #if defined (sdiv_qrnnd)
370 UWtype
371 __udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d)
373 UWtype q, r;
374 UWtype c0, c1, b1;
376 if ((Wtype) d >= 0)
378 if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1)))
380 /* dividend, divisor, and quotient are nonnegative */
381 sdiv_qrnnd (q, r, a1, a0, d);
383 else
385 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
386 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1));
387 /* Divide (c1*2^32 + c0) by d */
388 sdiv_qrnnd (q, r, c1, c0, d);
389 /* Add 2^31 to quotient */
390 q += (UWtype) 1 << (W_TYPE_SIZE - 1);
393 else
395 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
396 c1 = a1 >> 1; /* A/2 */
397 c0 = (a1 << (W_TYPE_SIZE - 1)) + (a0 >> 1);
399 if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
401 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
403 r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
404 if ((d & 1) != 0)
406 if (r >= q)
407 r = r - q;
408 else if (q - r <= d)
410 r = r - q + d;
411 q--;
413 else
415 r = r - q + 2*d;
416 q -= 2;
420 else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
422 c1 = (b1 - 1) - c1;
423 c0 = ~c0; /* logical NOT */
425 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
427 q = ~q; /* (A/2)/b1 */
428 r = (b1 - 1) - r;
430 r = 2*r + (a0 & 1); /* A/(2*b1) */
432 if ((d & 1) != 0)
434 if (r >= q)
435 r = r - q;
436 else if (q - r <= d)
438 r = r - q + d;
439 q--;
441 else
443 r = r - q + 2*d;
444 q -= 2;
448 else /* Implies c1 = b1 */
449 { /* Hence a1 = d - 1 = 2*b1 - 1 */
450 if (a0 >= -d)
452 q = -1;
453 r = a0 + d;
455 else
457 q = -2;
458 r = a0 + 2*d;
463 *rp = r;
464 return q;
466 #else
467 /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */
468 UWtype
469 __udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)),
470 UWtype a1 __attribute__ ((__unused__)),
471 UWtype a0 __attribute__ ((__unused__)),
472 UWtype d __attribute__ ((__unused__)))
474 return 0;
476 #endif
477 #endif
479 #if (defined (L_udivdi3) || defined (L_divdi3) || \
480 defined (L_umoddi3) || defined (L_moddi3))
481 #define L_udivmoddi4
482 #endif
484 #ifdef L_clz
485 const UQItype __clz_tab[] =
487 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
488 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
489 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
490 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
491 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
492 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
493 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
494 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
496 #endif
498 #ifdef L_udivmoddi4
500 #if (defined (L_udivdi3) || defined (L_divdi3) || \
501 defined (L_umoddi3) || defined (L_moddi3))
502 static inline
503 #endif
504 UDWtype
505 __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
507 DWunion ww;
508 DWunion nn, dd;
509 DWunion rr;
510 UWtype d0, d1, n0, n1, n2;
511 UWtype q0, q1;
512 UWtype b, bm;
514 nn.ll = n;
515 dd.ll = d;
517 d0 = dd.s.low;
518 d1 = dd.s.high;
519 n0 = nn.s.low;
520 n1 = nn.s.high;
522 #if !UDIV_NEEDS_NORMALIZATION
523 if (d1 == 0)
525 if (d0 > n1)
527 /* 0q = nn / 0D */
529 udiv_qrnnd (q0, n0, n1, n0, d0);
530 q1 = 0;
532 /* Remainder in n0. */
534 else
536 /* qq = NN / 0d */
538 if (d0 == 0)
539 d0 = 1 / d0; /* Divide intentionally by zero. */
541 udiv_qrnnd (q1, n1, 0, n1, d0);
542 udiv_qrnnd (q0, n0, n1, n0, d0);
544 /* Remainder in n0. */
547 if (rp != 0)
549 rr.s.low = n0;
550 rr.s.high = 0;
551 *rp = rr.ll;
555 #else /* UDIV_NEEDS_NORMALIZATION */
557 if (d1 == 0)
559 if (d0 > n1)
561 /* 0q = nn / 0D */
563 count_leading_zeros (bm, d0);
565 if (bm != 0)
567 /* Normalize, i.e. make the most significant bit of the
568 denominator set. */
570 d0 = d0 << bm;
571 n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
572 n0 = n0 << bm;
575 udiv_qrnnd (q0, n0, n1, n0, d0);
576 q1 = 0;
578 /* Remainder in n0 >> bm. */
580 else
582 /* qq = NN / 0d */
584 if (d0 == 0)
585 d0 = 1 / d0; /* Divide intentionally by zero. */
587 count_leading_zeros (bm, d0);
589 if (bm == 0)
591 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
592 conclude (the most significant bit of n1 is set) /\ (the
593 leading quotient digit q1 = 1).
595 This special case is necessary, not an optimization.
596 (Shifts counts of W_TYPE_SIZE are undefined.) */
598 n1 -= d0;
599 q1 = 1;
601 else
603 /* Normalize. */
605 b = W_TYPE_SIZE - bm;
607 d0 = d0 << bm;
608 n2 = n1 >> b;
609 n1 = (n1 << bm) | (n0 >> b);
610 n0 = n0 << bm;
612 udiv_qrnnd (q1, n1, n2, n1, d0);
615 /* n1 != d0... */
617 udiv_qrnnd (q0, n0, n1, n0, d0);
619 /* Remainder in n0 >> bm. */
622 if (rp != 0)
624 rr.s.low = n0 >> bm;
625 rr.s.high = 0;
626 *rp = rr.ll;
629 #endif /* UDIV_NEEDS_NORMALIZATION */
631 else
633 if (d1 > n1)
635 /* 00 = nn / DD */
637 q0 = 0;
638 q1 = 0;
640 /* Remainder in n1n0. */
641 if (rp != 0)
643 rr.s.low = n0;
644 rr.s.high = n1;
645 *rp = rr.ll;
648 else
650 /* 0q = NN / dd */
652 count_leading_zeros (bm, d1);
653 if (bm == 0)
655 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
656 conclude (the most significant bit of n1 is set) /\ (the
657 quotient digit q0 = 0 or 1).
659 This special case is necessary, not an optimization. */
661 /* The condition on the next line takes advantage of that
662 n1 >= d1 (true due to program flow). */
663 if (n1 > d1 || n0 >= d0)
665 q0 = 1;
666 sub_ddmmss (n1, n0, n1, n0, d1, d0);
668 else
669 q0 = 0;
671 q1 = 0;
673 if (rp != 0)
675 rr.s.low = n0;
676 rr.s.high = n1;
677 *rp = rr.ll;
680 else
682 UWtype m1, m0;
683 /* Normalize. */
685 b = W_TYPE_SIZE - bm;
687 d1 = (d1 << bm) | (d0 >> b);
688 d0 = d0 << bm;
689 n2 = n1 >> b;
690 n1 = (n1 << bm) | (n0 >> b);
691 n0 = n0 << bm;
693 udiv_qrnnd (q0, n1, n2, n1, d1);
694 umul_ppmm (m1, m0, q0, d0);
696 if (m1 > n1 || (m1 == n1 && m0 > n0))
698 q0--;
699 sub_ddmmss (m1, m0, m1, m0, d1, d0);
702 q1 = 0;
704 /* Remainder in (n1n0 - m1m0) >> bm. */
705 if (rp != 0)
707 sub_ddmmss (n1, n0, n1, n0, m1, m0);
708 rr.s.low = (n1 << b) | (n0 >> bm);
709 rr.s.high = n1 >> bm;
710 *rp = rr.ll;
716 ww.s.low = q0;
717 ww.s.high = q1;
718 return ww.ll;
720 #endif
722 #ifdef L_divdi3
723 DWtype
724 __divdi3 (DWtype u, DWtype v)
726 word_type c = 0;
727 DWunion uu, vv;
728 DWtype w;
730 uu.ll = u;
731 vv.ll = v;
733 if (uu.s.high < 0)
734 c = ~c,
735 uu.ll = __negdi2 (uu.ll);
736 if (vv.s.high < 0)
737 c = ~c,
738 vv.ll = __negdi2 (vv.ll);
740 w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
741 if (c)
742 w = __negdi2 (w);
744 return w;
746 #endif
748 #ifdef L_moddi3
749 DWtype
750 __moddi3 (DWtype u, DWtype v)
752 word_type c = 0;
753 DWunion uu, vv;
754 DWtype w;
756 uu.ll = u;
757 vv.ll = v;
759 if (uu.s.high < 0)
760 c = ~c,
761 uu.ll = __negdi2 (uu.ll);
762 if (vv.s.high < 0)
763 vv.ll = __negdi2 (vv.ll);
765 (void) __udivmoddi4 (uu.ll, vv.ll, &w);
766 if (c)
767 w = __negdi2 (w);
769 return w;
771 #endif
773 #ifdef L_umoddi3
774 UDWtype
775 __umoddi3 (UDWtype u, UDWtype v)
777 UDWtype w;
779 (void) __udivmoddi4 (u, v, &w);
781 return w;
783 #endif
785 #ifdef L_udivdi3
786 UDWtype
787 __udivdi3 (UDWtype n, UDWtype d)
789 return __udivmoddi4 (n, d, (UDWtype *) 0);
791 #endif
793 #ifdef L_cmpdi2
794 word_type
795 __cmpdi2 (DWtype a, DWtype b)
797 DWunion au, bu;
799 au.ll = a, bu.ll = b;
801 if (au.s.high < bu.s.high)
802 return 0;
803 else if (au.s.high > bu.s.high)
804 return 2;
805 if ((UWtype) au.s.low < (UWtype) bu.s.low)
806 return 0;
807 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
808 return 2;
809 return 1;
811 #endif
813 #ifdef L_ucmpdi2
814 word_type
815 __ucmpdi2 (DWtype a, DWtype b)
817 DWunion au, bu;
819 au.ll = a, bu.ll = b;
821 if ((UWtype) au.s.high < (UWtype) bu.s.high)
822 return 0;
823 else if ((UWtype) au.s.high > (UWtype) bu.s.high)
824 return 2;
825 if ((UWtype) au.s.low < (UWtype) bu.s.low)
826 return 0;
827 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
828 return 2;
829 return 1;
831 #endif
833 #if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
834 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
835 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
837 DWtype
838 __fixunstfDI (TFtype a)
840 TFtype b;
841 UDWtype v;
843 if (a < 0)
844 return 0;
846 /* Compute high word of result, as a flonum. */
847 b = (a / HIGH_WORD_COEFF);
848 /* Convert that to fixed (but not to DWtype!),
849 and shift it into the high word. */
850 v = (UWtype) b;
851 v <<= WORD_SIZE;
852 /* Remove high part from the TFtype, leaving the low part as flonum. */
853 a -= (TFtype)v;
854 /* Convert that to fixed (but not to DWtype!) and add it in.
855 Sometimes A comes out negative. This is significant, since
856 A has more bits than a long int does. */
857 if (a < 0)
858 v -= (UWtype) (- a);
859 else
860 v += (UWtype) a;
861 return v;
863 #endif
865 #if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
866 DWtype
867 __fixtfdi (TFtype a)
869 if (a < 0)
870 return - __fixunstfDI (-a);
871 return __fixunstfDI (a);
873 #endif
875 #if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
876 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
877 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
879 DWtype
880 __fixunsxfDI (XFtype a)
882 XFtype b;
883 UDWtype v;
885 if (a < 0)
886 return 0;
888 /* Compute high word of result, as a flonum. */
889 b = (a / HIGH_WORD_COEFF);
890 /* Convert that to fixed (but not to DWtype!),
891 and shift it into the high word. */
892 v = (UWtype) b;
893 v <<= WORD_SIZE;
894 /* Remove high part from the XFtype, leaving the low part as flonum. */
895 a -= (XFtype)v;
896 /* Convert that to fixed (but not to DWtype!) and add it in.
897 Sometimes A comes out negative. This is significant, since
898 A has more bits than a long int does. */
899 if (a < 0)
900 v -= (UWtype) (- a);
901 else
902 v += (UWtype) a;
903 return v;
905 #endif
907 #if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
908 DWtype
909 __fixxfdi (XFtype a)
911 if (a < 0)
912 return - __fixunsxfDI (-a);
913 return __fixunsxfDI (a);
915 #endif
917 #ifdef L_fixunsdfdi
918 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
919 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
921 DWtype
922 __fixunsdfDI (DFtype a)
924 DFtype b;
925 UDWtype v;
927 if (a < 0)
928 return 0;
930 /* Compute high word of result, as a flonum. */
931 b = (a / HIGH_WORD_COEFF);
932 /* Convert that to fixed (but not to DWtype!),
933 and shift it into the high word. */
934 v = (UWtype) b;
935 v <<= WORD_SIZE;
936 /* Remove high part from the DFtype, leaving the low part as flonum. */
937 a -= (DFtype)v;
938 /* Convert that to fixed (but not to DWtype!) and add it in.
939 Sometimes A comes out negative. This is significant, since
940 A has more bits than a long int does. */
941 if (a < 0)
942 v -= (UWtype) (- a);
943 else
944 v += (UWtype) a;
945 return v;
947 #endif
949 #ifdef L_fixdfdi
950 DWtype
951 __fixdfdi (DFtype a)
953 if (a < 0)
954 return - __fixunsdfDI (-a);
955 return __fixunsdfDI (a);
957 #endif
959 #ifdef L_fixunssfdi
960 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
961 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
963 DWtype
964 __fixunssfDI (SFtype original_a)
966 /* Convert the SFtype to a DFtype, because that is surely not going
967 to lose any bits. Some day someone else can write a faster version
968 that avoids converting to DFtype, and verify it really works right. */
969 DFtype a = original_a;
970 DFtype b;
971 UDWtype v;
973 if (a < 0)
974 return 0;
976 /* Compute high word of result, as a flonum. */
977 b = (a / HIGH_WORD_COEFF);
978 /* Convert that to fixed (but not to DWtype!),
979 and shift it into the high word. */
980 v = (UWtype) b;
981 v <<= WORD_SIZE;
982 /* Remove high part from the DFtype, leaving the low part as flonum. */
983 a -= (DFtype) v;
984 /* Convert that to fixed (but not to DWtype!) and add it in.
985 Sometimes A comes out negative. This is significant, since
986 A has more bits than a long int does. */
987 if (a < 0)
988 v -= (UWtype) (- a);
989 else
990 v += (UWtype) a;
991 return v;
993 #endif
995 #ifdef L_fixsfdi
996 DWtype
997 __fixsfdi (SFtype a)
999 if (a < 0)
1000 return - __fixunssfDI (-a);
1001 return __fixunssfDI (a);
1003 #endif
1005 #if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
1006 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1007 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1008 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1010 XFtype
1011 __floatdixf (DWtype u)
1013 XFtype d;
1015 d = (Wtype) (u >> WORD_SIZE);
1016 d *= HIGH_HALFWORD_COEFF;
1017 d *= HIGH_HALFWORD_COEFF;
1018 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1020 return d;
1022 #endif
1024 #if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
1025 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1026 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1027 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1029 TFtype
1030 __floatditf (DWtype u)
1032 TFtype d;
1034 d = (Wtype) (u >> WORD_SIZE);
1035 d *= HIGH_HALFWORD_COEFF;
1036 d *= HIGH_HALFWORD_COEFF;
1037 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1039 return d;
1041 #endif
1043 #ifdef L_floatdidf
1044 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1045 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1046 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1048 DFtype
1049 __floatdidf (DWtype u)
1051 DFtype d;
1053 d = (Wtype) (u >> WORD_SIZE);
1054 d *= HIGH_HALFWORD_COEFF;
1055 d *= HIGH_HALFWORD_COEFF;
1056 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1058 return d;
1060 #endif
1062 #ifdef L_floatdisf
1063 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1064 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1065 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1066 #define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT)
1068 /* Define codes for all the float formats that we know of. Note
1069 that this is copied from real.h. */
1071 #define UNKNOWN_FLOAT_FORMAT 0
1072 #define IEEE_FLOAT_FORMAT 1
1073 #define VAX_FLOAT_FORMAT 2
1074 #define IBM_FLOAT_FORMAT 3
1076 /* Default to IEEE float if not specified. Nearly all machines use it. */
1077 #ifndef HOST_FLOAT_FORMAT
1078 #define HOST_FLOAT_FORMAT IEEE_FLOAT_FORMAT
1079 #endif
1081 #if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1082 #define DF_SIZE 53
1083 #define SF_SIZE 24
1084 #endif
1086 #if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
1087 #define DF_SIZE 56
1088 #define SF_SIZE 24
1089 #endif
1091 #if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
1092 #define DF_SIZE 56
1093 #define SF_SIZE 24
1094 #endif
1096 SFtype
1097 __floatdisf (DWtype u)
1099 /* Do the calculation in DFmode
1100 so that we don't lose any of the precision of the high word
1101 while multiplying it. */
1102 DFtype f;
1104 /* Protect against double-rounding error.
1105 Represent any low-order bits, that might be truncated in DFmode,
1106 by a bit that won't be lost. The bit can go in anywhere below the
1107 rounding position of the SFmode. A fixed mask and bit position
1108 handles all usual configurations. It doesn't handle the case
1109 of 128-bit DImode, however. */
1110 if (DF_SIZE < DI_SIZE
1111 && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1113 #define REP_BIT ((UDWtype) 1 << (DI_SIZE - DF_SIZE))
1114 if (! (- ((DWtype) 1 << DF_SIZE) < u
1115 && u < ((DWtype) 1 << DF_SIZE)))
1117 if ((UDWtype) u & (REP_BIT - 1))
1119 u &= ~ (REP_BIT - 1);
1120 u |= REP_BIT;
1124 f = (Wtype) (u >> WORD_SIZE);
1125 f *= HIGH_HALFWORD_COEFF;
1126 f *= HIGH_HALFWORD_COEFF;
1127 f += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1129 return (SFtype) f;
1131 #endif
1133 #if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
1134 /* Reenable the normal types, in case limits.h needs them. */
1135 #undef char
1136 #undef short
1137 #undef int
1138 #undef long
1139 #undef unsigned
1140 #undef float
1141 #undef double
1142 #undef MIN
1143 #undef MAX
1144 #include <limits.h>
1146 UWtype
1147 __fixunsxfSI (XFtype a)
1149 if (a >= - (DFtype) Wtype_MIN)
1150 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1151 return (Wtype) a;
1153 #endif
1155 #ifdef L_fixunsdfsi
1156 /* Reenable the normal types, in case limits.h needs them. */
1157 #undef char
1158 #undef short
1159 #undef int
1160 #undef long
1161 #undef unsigned
1162 #undef float
1163 #undef double
1164 #undef MIN
1165 #undef MAX
1166 #include <limits.h>
1168 UWtype
1169 __fixunsdfSI (DFtype a)
1171 if (a >= - (DFtype) Wtype_MIN)
1172 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1173 return (Wtype) a;
1175 #endif
1177 #ifdef L_fixunssfsi
1178 /* Reenable the normal types, in case limits.h needs them. */
1179 #undef char
1180 #undef short
1181 #undef int
1182 #undef long
1183 #undef unsigned
1184 #undef float
1185 #undef double
1186 #undef MIN
1187 #undef MAX
1188 #include <limits.h>
1190 UWtype
1191 __fixunssfSI (SFtype a)
1193 if (a >= - (SFtype) Wtype_MIN)
1194 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1195 return (Wtype) a;
1197 #endif
1199 /* From here on down, the routines use normal data types. */
1201 #define SItype bogus_type
1202 #define USItype bogus_type
1203 #define DItype bogus_type
1204 #define UDItype bogus_type
1205 #define SFtype bogus_type
1206 #define DFtype bogus_type
1207 #undef Wtype
1208 #undef UWtype
1209 #undef HWtype
1210 #undef UHWtype
1211 #undef DWtype
1212 #undef UDWtype
1214 #undef char
1215 #undef short
1216 #undef int
1217 #undef long
1218 #undef unsigned
1219 #undef float
1220 #undef double
1222 #ifdef L__gcc_bcmp
1224 /* Like bcmp except the sign is meaningful.
1225 Result is negative if S1 is less than S2,
1226 positive if S1 is greater, 0 if S1 and S2 are equal. */
1229 __gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
1231 while (size > 0)
1233 unsigned char c1 = *s1++, c2 = *s2++;
1234 if (c1 != c2)
1235 return c1 - c2;
1236 size--;
1238 return 0;
1241 #endif
1243 /* __eprintf used to be used by GCC's private version of <assert.h>.
1244 We no longer provide that header, but this routine remains in libgcc.a
1245 for binary backward compatibility. Note that it is not included in
1246 the shared version of libgcc. */
1247 #ifdef L_eprintf
1248 #ifndef inhibit_libc
1250 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1251 #include <stdio.h>
1253 void
1254 __eprintf (const char *string, const char *expression,
1255 unsigned int line, const char *filename)
1257 fprintf (stderr, string, expression, line, filename);
1258 fflush (stderr);
1259 abort ();
1262 #endif
1263 #endif
1265 #ifdef L_bb
1267 #if LONG_TYPE_SIZE == GCOV_TYPE_SIZE
1268 typedef long gcov_type;
1269 #else
1270 typedef long long gcov_type;
1271 #endif
1274 /* Structure emitted by -a */
1275 struct bb
1277 long zero_word;
1278 const char *filename;
1279 gcov_type *counts;
1280 long ncounts;
1281 struct bb *next;
1282 const unsigned long *addresses;
1284 /* Older GCC's did not emit these fields. */
1285 long nwords;
1286 const char **functions;
1287 const long *line_nums;
1288 const char **filenames;
1289 char *flags;
1292 #ifndef inhibit_libc
1294 /* Simple minded basic block profiling output dumper for
1295 systems that don't provide tcov support. At present,
1296 it requires atexit and stdio. */
1298 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1299 #include <stdio.h>
1301 #include "gbl-ctors.h"
1302 #include "gcov-io.h"
1303 #include <string.h>
1304 #ifdef TARGET_HAS_F_SETLKW
1305 #include <fcntl.h>
1306 #include <errno.h>
1307 #endif
1309 static struct bb *bb_head;
1311 void
1312 __bb_exit_func (void)
1314 FILE *da_file;
1315 int i;
1316 struct bb *ptr;
1318 if (bb_head == 0)
1319 return;
1321 i = strlen (bb_head->filename) - 3;
1324 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1326 int firstchar;
1328 /* Make sure the output file exists -
1329 but don't clobber exiting data. */
1330 if ((da_file = fopen (ptr->filename, "a")) != 0)
1331 fclose (da_file);
1333 /* Need to re-open in order to be able to write from the start. */
1334 da_file = fopen (ptr->filename, "r+b");
1335 /* Some old systems might not allow the 'b' mode modifier.
1336 Therefore, try to open without it. This can lead to a race
1337 condition so that when you delete and re-create the file, the
1338 file might be opened in text mode, but then, you shouldn't
1339 delete the file in the first place. */
1340 if (da_file == 0)
1341 da_file = fopen (ptr->filename, "r+");
1342 if (da_file == 0)
1344 fprintf (stderr, "arc profiling: Can't open output file %s.\n",
1345 ptr->filename);
1346 continue;
1349 /* After a fork, another process might try to read and/or write
1350 the same file simultanously. So if we can, lock the file to
1351 avoid race conditions. */
1352 #if defined (TARGET_HAS_F_SETLKW)
1354 struct flock s_flock;
1356 s_flock.l_type = F_WRLCK;
1357 s_flock.l_whence = SEEK_SET;
1358 s_flock.l_start = 0;
1359 s_flock.l_len = 1;
1360 s_flock.l_pid = getpid ();
1362 while (fcntl (fileno (da_file), F_SETLKW, &s_flock)
1363 && errno == EINTR);
1365 #endif
1367 /* If the file is not empty, and the number of counts in it is the
1368 same, then merge them in. */
1369 firstchar = fgetc (da_file);
1370 if (firstchar == EOF)
1372 if (ferror (da_file))
1374 fprintf (stderr, "arc profiling: Can't read output file ");
1375 perror (ptr->filename);
1378 else
1380 long n_counts = 0;
1382 if (ungetc (firstchar, da_file) == EOF)
1383 rewind (da_file);
1384 if (__read_long (&n_counts, da_file, 8) != 0)
1386 fprintf (stderr, "arc profiling: Can't read output file %s.\n",
1387 ptr->filename);
1388 continue;
1391 if (n_counts == ptr->ncounts)
1393 int i;
1395 for (i = 0; i < n_counts; i++)
1397 gcov_type v = 0;
1399 if (__read_gcov_type (&v, da_file, 8) != 0)
1401 fprintf (stderr,
1402 "arc profiling: Can't read output file %s.\n",
1403 ptr->filename);
1404 break;
1406 ptr->counts[i] += v;
1412 rewind (da_file);
1414 /* ??? Should first write a header to the file. Preferably, a 4 byte
1415 magic number, 4 bytes containing the time the program was
1416 compiled, 4 bytes containing the last modification time of the
1417 source file, and 4 bytes indicating the compiler options used.
1419 That way we can easily verify that the proper source/executable/
1420 data file combination is being used from gcov. */
1422 if (__write_gcov_type (ptr->ncounts, da_file, 8) != 0)
1425 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1426 ptr->filename);
1428 else
1430 int j;
1431 gcov_type *count_ptr = ptr->counts;
1432 int ret = 0;
1433 for (j = ptr->ncounts; j > 0; j--)
1435 if (__write_gcov_type (*count_ptr, da_file, 8) != 0)
1437 ret = 1;
1438 break;
1440 count_ptr++;
1442 if (ret)
1443 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1444 ptr->filename);
1447 if (fclose (da_file) == EOF)
1448 fprintf (stderr, "arc profiling: Error closing output file %s.\n",
1449 ptr->filename);
1452 return;
1455 void
1456 __bb_init_func (struct bb *blocks)
1458 /* User is supposed to check whether the first word is non-0,
1459 but just in case.... */
1461 if (blocks->zero_word)
1462 return;
1464 /* Initialize destructor. */
1465 if (!bb_head)
1466 atexit (__bb_exit_func);
1468 /* Set up linked list. */
1469 blocks->zero_word = 1;
1470 blocks->next = bb_head;
1471 bb_head = blocks;
1474 /* Called before fork or exec - write out profile information gathered so
1475 far and reset it to zero. This avoids duplication or loss of the
1476 profile information gathered so far. */
1477 void
1478 __bb_fork_func (void)
1480 struct bb *ptr;
1482 __bb_exit_func ();
1483 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1485 long i;
1486 for (i = ptr->ncounts - 1; i >= 0; i--)
1487 ptr->counts[i] = 0;
1491 #endif /* not inhibit_libc */
1492 #endif /* L_bb */
1494 #ifdef L_clear_cache
1495 /* Clear part of an instruction cache. */
1497 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1499 void
1500 __clear_cache (char *beg __attribute__((__unused__)),
1501 char *end __attribute__((__unused__)))
1503 #ifdef CLEAR_INSN_CACHE
1504 CLEAR_INSN_CACHE (beg, end);
1505 #else
1506 #ifdef INSN_CACHE_SIZE
1507 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1508 static int initialized;
1509 int offset;
1510 void *start_addr
1511 void *end_addr;
1512 typedef (*function_ptr) (void);
1514 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1515 /* It's cheaper to clear the whole cache.
1516 Put in a series of jump instructions so that calling the beginning
1517 of the cache will clear the whole thing. */
1519 if (! initialized)
1521 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1522 & -INSN_CACHE_LINE_WIDTH);
1523 int end_ptr = ptr + INSN_CACHE_SIZE;
1525 while (ptr < end_ptr)
1527 *(INSTRUCTION_TYPE *)ptr
1528 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1529 ptr += INSN_CACHE_LINE_WIDTH;
1531 *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1533 initialized = 1;
1536 /* Call the beginning of the sequence. */
1537 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1538 & -INSN_CACHE_LINE_WIDTH))
1539 ());
1541 #else /* Cache is large. */
1543 if (! initialized)
1545 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1546 & -INSN_CACHE_LINE_WIDTH);
1548 while (ptr < (int) array + sizeof array)
1550 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1551 ptr += INSN_CACHE_LINE_WIDTH;
1554 initialized = 1;
1557 /* Find the location in array that occupies the same cache line as BEG. */
1559 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1560 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1561 & -INSN_CACHE_PLANE_SIZE)
1562 + offset);
1564 /* Compute the cache alignment of the place to stop clearing. */
1565 #if 0 /* This is not needed for gcc's purposes. */
1566 /* If the block to clear is bigger than a cache plane,
1567 we clear the entire cache, and OFFSET is already correct. */
1568 if (end < beg + INSN_CACHE_PLANE_SIZE)
1569 #endif
1570 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1571 & -INSN_CACHE_LINE_WIDTH)
1572 & (INSN_CACHE_PLANE_SIZE - 1));
1574 #if INSN_CACHE_DEPTH > 1
1575 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1576 if (end_addr <= start_addr)
1577 end_addr += INSN_CACHE_PLANE_SIZE;
1579 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1581 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1582 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1584 while (addr != stop)
1586 /* Call the return instruction at ADDR. */
1587 ((function_ptr) addr) ();
1589 addr += INSN_CACHE_LINE_WIDTH;
1592 #else /* just one plane */
1595 /* Call the return instruction at START_ADDR. */
1596 ((function_ptr) start_addr) ();
1598 start_addr += INSN_CACHE_LINE_WIDTH;
1600 while ((start_addr % INSN_CACHE_SIZE) != offset);
1601 #endif /* just one plane */
1602 #endif /* Cache is large */
1603 #endif /* Cache exists */
1604 #endif /* CLEAR_INSN_CACHE */
1607 #endif /* L_clear_cache */
1609 #ifdef L_trampoline
1611 /* Jump to a trampoline, loading the static chain address. */
1613 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
1615 long
1616 getpagesize (void)
1618 #ifdef _ALPHA_
1619 return 8192;
1620 #else
1621 return 4096;
1622 #endif
1625 #ifdef __i386__
1626 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
1627 #endif
1630 mprotect (char *addr, int len, int prot)
1632 int np, op;
1634 if (prot == 7)
1635 np = 0x40;
1636 else if (prot == 5)
1637 np = 0x20;
1638 else if (prot == 4)
1639 np = 0x10;
1640 else if (prot == 3)
1641 np = 0x04;
1642 else if (prot == 1)
1643 np = 0x02;
1644 else if (prot == 0)
1645 np = 0x01;
1647 if (VirtualProtect (addr, len, np, &op))
1648 return 0;
1649 else
1650 return -1;
1653 #endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
1655 #ifdef TRANSFER_FROM_TRAMPOLINE
1656 TRANSFER_FROM_TRAMPOLINE
1657 #endif
1659 #if defined (NeXT) && defined (__MACH__)
1661 /* Make stack executable so we can call trampolines on stack.
1662 This is called from INITIALIZE_TRAMPOLINE in next.h. */
1663 #ifdef NeXTStep21
1664 #include <mach.h>
1665 #else
1666 #include <mach/mach.h>
1667 #endif
1669 void
1670 __enable_execute_stack (char *addr)
1672 kern_return_t r;
1673 char *eaddr = addr + TRAMPOLINE_SIZE;
1674 vm_address_t a = (vm_address_t) addr;
1676 /* turn on execute access on stack */
1677 r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
1678 if (r != KERN_SUCCESS)
1680 mach_error("vm_protect VM_PROT_ALL", r);
1681 exit(1);
1684 /* We inline the i-cache invalidation for speed */
1686 #ifdef CLEAR_INSN_CACHE
1687 CLEAR_INSN_CACHE (addr, eaddr);
1688 #else
1689 __clear_cache ((int) addr, (int) eaddr);
1690 #endif
1693 #endif /* defined (NeXT) && defined (__MACH__) */
1695 #ifdef __convex__
1697 /* Make stack executable so we can call trampolines on stack.
1698 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
1700 #include <sys/mman.h>
1701 #include <sys/vmparam.h>
1702 #include <machine/machparam.h>
1704 void
1705 __enable_execute_stack (void)
1707 int fp;
1708 static unsigned lowest = USRSTACK;
1709 unsigned current = (unsigned) &fp & -NBPG;
1711 if (lowest > current)
1713 unsigned len = lowest - current;
1714 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
1715 lowest = current;
1718 /* Clear instruction cache in case an old trampoline is in it. */
1719 asm ("pich");
1721 #endif /* __convex__ */
1723 #ifdef __sysV88__
1725 /* Modified from the convex -code above. */
1727 #include <sys/param.h>
1728 #include <errno.h>
1729 #include <sys/m88kbcs.h>
1731 void
1732 __enable_execute_stack (void)
1734 int save_errno;
1735 static unsigned long lowest = USRSTACK;
1736 unsigned long current = (unsigned long) &save_errno & -NBPC;
1738 /* Ignore errno being set. memctl sets errno to EINVAL whenever the
1739 address is seen as 'negative'. That is the case with the stack. */
1741 save_errno=errno;
1742 if (lowest > current)
1744 unsigned len=lowest-current;
1745 memctl(current,len,MCT_TEXT);
1746 lowest = current;
1748 else
1749 memctl(current,NBPC,MCT_TEXT);
1750 errno=save_errno;
1753 #endif /* __sysV88__ */
1755 #ifdef __sysV68__
1757 #include <sys/signal.h>
1758 #include <errno.h>
1760 /* Motorola forgot to put memctl.o in the libp version of libc881.a,
1761 so define it here, because we need it in __clear_insn_cache below */
1762 /* On older versions of this OS, no memctl or MCT_TEXT are defined;
1763 hence we enable this stuff only if MCT_TEXT is #define'd. */
1765 #ifdef MCT_TEXT
1766 asm("\n\
1767 global memctl\n\
1768 memctl:\n\
1769 movq &75,%d0\n\
1770 trap &0\n\
1771 bcc.b noerror\n\
1772 jmp cerror%\n\
1773 noerror:\n\
1774 movq &0,%d0\n\
1775 rts");
1776 #endif
1778 /* Clear instruction cache so we can call trampolines on stack.
1779 This is called from FINALIZE_TRAMPOLINE in mot3300.h. */
1781 void
1782 __clear_insn_cache (void)
1784 #ifdef MCT_TEXT
1785 int save_errno;
1787 /* Preserve errno, because users would be surprised to have
1788 errno changing without explicitly calling any system-call. */
1789 save_errno = errno;
1791 /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache.
1792 No need to use an address derived from _start or %sp, as 0 works also. */
1793 memctl(0, 4096, MCT_TEXT);
1794 errno = save_errno;
1795 #endif
1798 #endif /* __sysV68__ */
1800 #ifdef __pyr__
1802 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1803 #include <stdio.h>
1804 #include <sys/mman.h>
1805 #include <sys/types.h>
1806 #include <sys/param.h>
1807 #include <sys/vmmac.h>
1809 /* Modified from the convex -code above.
1810 mremap promises to clear the i-cache. */
1812 void
1813 __enable_execute_stack (void)
1815 int fp;
1816 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
1817 PROT_READ|PROT_WRITE|PROT_EXEC))
1819 perror ("mprotect in __enable_execute_stack");
1820 fflush (stderr);
1821 abort ();
1824 #endif /* __pyr__ */
1826 #if defined (sony_news) && defined (SYSTYPE_BSD)
1828 #include <stdio.h>
1829 #include <sys/types.h>
1830 #include <sys/param.h>
1831 #include <syscall.h>
1832 #include <machine/sysnews.h>
1834 /* cacheflush function for NEWS-OS 4.2.
1835 This function is called from trampoline-initialize code
1836 defined in config/mips/mips.h. */
1838 void
1839 cacheflush (char *beg, int size, int flag)
1841 if (syscall (SYS_sysnews, NEWS_CACHEFLUSH, beg, size, FLUSH_BCACHE))
1843 perror ("cache_flush");
1844 fflush (stderr);
1845 abort ();
1849 #endif /* sony_news */
1850 #endif /* L_trampoline */
1852 #ifndef __CYGWIN__
1853 #ifdef L__main
1855 #include "gbl-ctors.h"
1856 /* Some systems use __main in a way incompatible with its use in gcc, in these
1857 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
1858 give the same symbol without quotes for an alternative entry point. You
1859 must define both, or neither. */
1860 #ifndef NAME__MAIN
1861 #define NAME__MAIN "__main"
1862 #define SYMBOL__MAIN __main
1863 #endif
1865 #ifdef INIT_SECTION_ASM_OP
1866 #undef HAS_INIT_SECTION
1867 #define HAS_INIT_SECTION
1868 #endif
1870 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
1872 /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
1873 code to run constructors. In that case, we need to handle EH here, too. */
1875 #ifdef EH_FRAME_SECTION_NAME
1876 #include "unwind-dw2-fde.h"
1877 extern unsigned char __EH_FRAME_BEGIN__[];
1878 #endif
1880 /* Run all the global destructors on exit from the program. */
1882 void
1883 __do_global_dtors (void)
1885 #ifdef DO_GLOBAL_DTORS_BODY
1886 DO_GLOBAL_DTORS_BODY;
1887 #else
1888 static func_ptr *p = __DTOR_LIST__ + 1;
1889 while (*p)
1891 p++;
1892 (*(p-1)) ();
1894 #endif
1895 #if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION)
1897 static int completed = 0;
1898 if (! completed)
1900 completed = 1;
1901 __deregister_frame_info (__EH_FRAME_BEGIN__);
1904 #endif
1906 #endif
1908 #ifndef HAS_INIT_SECTION
1909 /* Run all the global constructors on entry to the program. */
1911 void
1912 __do_global_ctors (void)
1914 #ifdef EH_FRAME_SECTION_NAME
1916 static struct object object;
1917 __register_frame_info (__EH_FRAME_BEGIN__, &object);
1919 #endif
1920 DO_GLOBAL_CTORS_BODY;
1921 atexit (__do_global_dtors);
1923 #endif /* no HAS_INIT_SECTION */
1925 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
1926 /* Subroutine called automatically by `main'.
1927 Compiling a global function named `main'
1928 produces an automatic call to this function at the beginning.
1930 For many systems, this routine calls __do_global_ctors.
1931 For systems which support a .init section we use the .init section
1932 to run __do_global_ctors, so we need not do anything here. */
1934 void
1935 SYMBOL__MAIN ()
1937 /* Support recursive calls to `main': run initializers just once. */
1938 static int initialized;
1939 if (! initialized)
1941 initialized = 1;
1942 __do_global_ctors ();
1945 #endif /* no HAS_INIT_SECTION or INVOKE__main */
1947 #endif /* L__main */
1948 #endif /* __CYGWIN__ */
1950 #ifdef L_ctors
1952 #include "gbl-ctors.h"
1954 /* Provide default definitions for the lists of constructors and
1955 destructors, so that we don't get linker errors. These symbols are
1956 intentionally bss symbols, so that gld and/or collect will provide
1957 the right values. */
1959 /* We declare the lists here with two elements each,
1960 so that they are valid empty lists if no other definition is loaded.
1962 If we are using the old "set" extensions to have the gnu linker
1963 collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
1964 must be in the bss/common section.
1966 Long term no port should use those extensions. But many still do. */
1967 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
1968 #if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2)
1969 func_ptr __CTOR_LIST__[2] = {0, 0};
1970 func_ptr __DTOR_LIST__[2] = {0, 0};
1971 #else
1972 func_ptr __CTOR_LIST__[2];
1973 func_ptr __DTOR_LIST__[2];
1974 #endif
1975 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1976 #endif /* L_ctors */
1978 #ifdef L_exit
1980 #include "gbl-ctors.h"
1982 #ifdef NEED_ATEXIT
1984 #ifndef ON_EXIT
1986 # include <errno.h>
1988 static func_ptr *atexit_chain = 0;
1989 static long atexit_chain_length = 0;
1990 static volatile long last_atexit_chain_slot = -1;
1993 atexit (func_ptr func)
1995 if (++last_atexit_chain_slot == atexit_chain_length)
1997 atexit_chain_length += 32;
1998 if (atexit_chain)
1999 atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
2000 * sizeof (func_ptr));
2001 else
2002 atexit_chain = (func_ptr *) malloc (atexit_chain_length
2003 * sizeof (func_ptr));
2004 if (! atexit_chain)
2006 atexit_chain_length = 0;
2007 last_atexit_chain_slot = -1;
2008 errno = ENOMEM;
2009 return (-1);
2012 atexit_chain[last_atexit_chain_slot] = func;
2013 return (0);
2016 extern void _cleanup (void);
2017 extern void _exit (int) __attribute__ ((__noreturn__));
2019 void
2020 exit (int status)
2022 if (atexit_chain)
2024 for ( ; last_atexit_chain_slot-- >= 0; )
2026 (*atexit_chain[last_atexit_chain_slot + 1]) ();
2027 atexit_chain[last_atexit_chain_slot + 1] = 0;
2029 free (atexit_chain);
2030 atexit_chain = 0;
2032 #ifdef EXIT_BODY
2033 EXIT_BODY;
2034 #else
2035 _cleanup ();
2036 #endif
2037 _exit (status);
2040 #else /* ON_EXIT */
2042 /* Simple; we just need a wrapper for ON_EXIT. */
2044 atexit (func_ptr func)
2046 return ON_EXIT (func);
2049 #endif /* ON_EXIT */
2050 #endif /* NEED_ATEXIT */
2052 #endif /* L_exit */