index.html: Correct link to libg++ information.
[official-gcc.git] / gcc / libgcc2.c
blob4260e25d66cecf0de34d6cb302e2aa412c54f192
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. */
33 /* We include auto-host.h here to get HAVE_GAS_HIDDEN. This is
34 supposedly valid even though this is a "target" file. */
35 #include "auto-host.h"
37 /* It is incorrect to include config.h here, because this file is being
38 compiled for the target, and hence definitions concerning only the host
39 do not apply. */
40 #include "tconfig.h"
41 #include "tsystem.h"
42 #include "coretypes.h"
43 #include "tm.h"
45 /* Don't use `fancy_abort' here even if config.h says to use it. */
46 #ifdef abort
47 #undef abort
48 #endif
50 #ifdef HAVE_GAS_HIDDEN
51 #define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
52 #else
53 #define ATTRIBUTE_HIDDEN
54 #endif
56 #include "libgcc2.h"
58 #ifdef DECLARE_LIBRARY_RENAMES
59 DECLARE_LIBRARY_RENAMES
60 #endif
62 #if defined (L_negdi2)
63 DWtype
64 __negdi2 (DWtype u)
66 DWunion w;
67 DWunion uu;
69 uu.ll = u;
71 w.s.low = -uu.s.low;
72 w.s.high = -uu.s.high - ((UWtype) w.s.low > 0);
74 return w.ll;
76 #endif
78 #ifdef L_addvsi3
79 Wtype
80 __addvsi3 (Wtype a, Wtype b)
82 Wtype w;
84 w = a + b;
86 if (b >= 0 ? w < a : w > a)
87 abort ();
89 return w;
91 #endif
93 #ifdef L_addvdi3
94 DWtype
95 __addvdi3 (DWtype a, DWtype b)
97 DWtype w;
99 w = a + b;
101 if (b >= 0 ? w < a : w > a)
102 abort ();
104 return w;
106 #endif
108 #ifdef L_subvsi3
109 Wtype
110 __subvsi3 (Wtype a, Wtype b)
112 #ifdef L_addvsi3
113 return __addvsi3 (a, (-b));
114 #else
115 DWtype w;
117 w = a - b;
119 if (b >= 0 ? w > a : w < a)
120 abort ();
122 return w;
123 #endif
125 #endif
127 #ifdef L_subvdi3
128 DWtype
129 __subvdi3 (DWtype a, DWtype b)
131 #ifdef L_addvdi3
132 return (a, (-b));
133 #else
134 DWtype w;
136 w = a - b;
138 if (b >= 0 ? w > a : w < a)
139 abort ();
141 return w;
142 #endif
144 #endif
146 #ifdef L_mulvsi3
147 Wtype
148 __mulvsi3 (Wtype a, Wtype b)
150 DWtype w;
152 w = a * b;
154 if (((a >= 0) == (b >= 0)) ? w < 0 : w > 0)
155 abort ();
157 return w;
159 #endif
161 #ifdef L_negvsi2
162 Wtype
163 __negvsi2 (Wtype a)
165 Wtype w;
167 w = -a;
169 if (a >= 0 ? w > 0 : w < 0)
170 abort ();
172 return w;
174 #endif
176 #ifdef L_negvdi2
177 DWtype
178 __negvdi2 (DWtype a)
180 DWtype w;
182 w = -a;
184 if (a >= 0 ? w > 0 : w < 0)
185 abort ();
187 return w;
189 #endif
191 #ifdef L_absvsi2
192 Wtype
193 __absvsi2 (Wtype a)
195 Wtype w = a;
197 if (a < 0)
198 #ifdef L_negvsi2
199 w = __negvsi2 (a);
200 #else
201 w = -a;
203 if (w < 0)
204 abort ();
205 #endif
207 return w;
209 #endif
211 #ifdef L_absvdi2
212 DWtype
213 __absvdi2 (DWtype a)
215 DWtype w = a;
217 if (a < 0)
218 #ifdef L_negvsi2
219 w = __negvsi2 (a);
220 #else
221 w = -a;
223 if (w < 0)
224 abort ();
225 #endif
227 return w;
229 #endif
231 #ifdef L_mulvdi3
232 DWtype
233 __mulvdi3 (DWtype u, DWtype v)
235 DWtype w;
237 w = u * v;
239 if (((u >= 0) == (v >= 0)) ? w < 0 : w > 0)
240 abort ();
242 return w;
244 #endif
247 /* Unless shift functions are defined with full ANSI prototypes,
248 parameter b will be promoted to int if word_type is smaller than an int. */
249 #ifdef L_lshrdi3
250 DWtype
251 __lshrdi3 (DWtype u, word_type b)
253 DWunion w;
254 word_type bm;
255 DWunion uu;
257 if (b == 0)
258 return u;
260 uu.ll = u;
262 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
263 if (bm <= 0)
265 w.s.high = 0;
266 w.s.low = (UWtype) uu.s.high >> -bm;
268 else
270 UWtype carries = (UWtype) uu.s.high << bm;
272 w.s.high = (UWtype) uu.s.high >> b;
273 w.s.low = ((UWtype) uu.s.low >> b) | carries;
276 return w.ll;
278 #endif
280 #ifdef L_ashldi3
281 DWtype
282 __ashldi3 (DWtype u, word_type b)
284 DWunion w;
285 word_type bm;
286 DWunion uu;
288 if (b == 0)
289 return u;
291 uu.ll = u;
293 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
294 if (bm <= 0)
296 w.s.low = 0;
297 w.s.high = (UWtype) uu.s.low << -bm;
299 else
301 UWtype carries = (UWtype) uu.s.low >> bm;
303 w.s.low = (UWtype) uu.s.low << b;
304 w.s.high = ((UWtype) uu.s.high << b) | carries;
307 return w.ll;
309 #endif
311 #ifdef L_ashrdi3
312 DWtype
313 __ashrdi3 (DWtype u, word_type b)
315 DWunion w;
316 word_type bm;
317 DWunion uu;
319 if (b == 0)
320 return u;
322 uu.ll = u;
324 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
325 if (bm <= 0)
327 /* w.s.high = 1..1 or 0..0 */
328 w.s.high = uu.s.high >> (sizeof (Wtype) * BITS_PER_UNIT - 1);
329 w.s.low = uu.s.high >> -bm;
331 else
333 UWtype carries = (UWtype) uu.s.high << bm;
335 w.s.high = uu.s.high >> b;
336 w.s.low = ((UWtype) uu.s.low >> b) | carries;
339 return w.ll;
341 #endif
343 #ifdef L_ffsdi2
344 Wtype
345 __ffsdi2 (DWtype u)
347 DWunion uu;
348 UWtype word, count, add;
350 uu.ll = u;
351 if (uu.s.low != 0)
352 word = uu.s.low, add = 0;
353 else if (uu.s.high != 0)
354 word = uu.s.high, add = BITS_PER_UNIT * sizeof (Wtype);
355 else
356 return 0;
358 count_trailing_zeros (count, word);
359 return count + add + 1;
361 #endif
363 #ifdef L_muldi3
364 DWtype
365 __muldi3 (DWtype u, DWtype v)
367 DWunion w;
368 DWunion uu, vv;
370 uu.ll = u,
371 vv.ll = v;
373 w.ll = __umulsidi3 (uu.s.low, vv.s.low);
374 w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
375 + (UWtype) uu.s.high * (UWtype) vv.s.low);
377 return w.ll;
379 #endif
381 #if (defined (L_udivdi3) || defined (L_divdi3) || \
382 defined (L_umoddi3) || defined (L_moddi3))
383 #if defined (sdiv_qrnnd)
384 #define L_udiv_w_sdiv
385 #endif
386 #endif
388 #ifdef L_udiv_w_sdiv
389 #if defined (sdiv_qrnnd)
390 #if (defined (L_udivdi3) || defined (L_divdi3) || \
391 defined (L_umoddi3) || defined (L_moddi3))
392 static inline __attribute__ ((__always_inline__))
393 #endif
394 UWtype
395 __udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d)
397 UWtype q, r;
398 UWtype c0, c1, b1;
400 if ((Wtype) d >= 0)
402 if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1)))
404 /* dividend, divisor, and quotient are nonnegative */
405 sdiv_qrnnd (q, r, a1, a0, d);
407 else
409 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
410 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1));
411 /* Divide (c1*2^32 + c0) by d */
412 sdiv_qrnnd (q, r, c1, c0, d);
413 /* Add 2^31 to quotient */
414 q += (UWtype) 1 << (W_TYPE_SIZE - 1);
417 else
419 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
420 c1 = a1 >> 1; /* A/2 */
421 c0 = (a1 << (W_TYPE_SIZE - 1)) + (a0 >> 1);
423 if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
425 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
427 r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
428 if ((d & 1) != 0)
430 if (r >= q)
431 r = r - q;
432 else if (q - r <= d)
434 r = r - q + d;
435 q--;
437 else
439 r = r - q + 2*d;
440 q -= 2;
444 else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
446 c1 = (b1 - 1) - c1;
447 c0 = ~c0; /* logical NOT */
449 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
451 q = ~q; /* (A/2)/b1 */
452 r = (b1 - 1) - r;
454 r = 2*r + (a0 & 1); /* A/(2*b1) */
456 if ((d & 1) != 0)
458 if (r >= q)
459 r = r - q;
460 else if (q - r <= d)
462 r = r - q + d;
463 q--;
465 else
467 r = r - q + 2*d;
468 q -= 2;
472 else /* Implies c1 = b1 */
473 { /* Hence a1 = d - 1 = 2*b1 - 1 */
474 if (a0 >= -d)
476 q = -1;
477 r = a0 + d;
479 else
481 q = -2;
482 r = a0 + 2*d;
487 *rp = r;
488 return q;
490 #else
491 /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */
492 UWtype
493 __udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)),
494 UWtype a1 __attribute__ ((__unused__)),
495 UWtype a0 __attribute__ ((__unused__)),
496 UWtype d __attribute__ ((__unused__)))
498 return 0;
500 #endif
501 #endif
503 #if (defined (L_udivdi3) || defined (L_divdi3) || \
504 defined (L_umoddi3) || defined (L_moddi3))
505 #define L_udivmoddi4
506 #endif
508 #ifdef L_clz
509 const UQItype __clz_tab[] =
511 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,
512 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,
513 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,
514 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,
515 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,
516 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,
517 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,
518 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,
520 #endif
522 #ifdef L_clzsi2
523 Wtype
524 __clzsi2 (USItype x)
526 UWtype w = x;
527 Wtype ret;
529 count_leading_zeros (ret, w);
530 ret -= (sizeof(w) - sizeof(x)) * BITS_PER_UNIT;
532 return ret;
534 #endif
536 #ifdef L_clzdi2
537 Wtype
538 __clzdi2 (UDItype x)
540 UWtype word;
541 Wtype ret, add;
543 if (sizeof(x) > sizeof(word))
545 DWunion uu;
547 uu.ll = x;
548 if (uu.s.high)
549 word = uu.s.high, add = 0;
550 else
551 word = uu.s.low, add = W_TYPE_SIZE;
553 else
554 word = x, add = (Wtype)(sizeof(x) - sizeof(word)) * BITS_PER_UNIT;
556 count_leading_zeros (ret, word);
557 return ret + add;
559 #endif
561 #ifdef L_ctzsi2
562 Wtype
563 __ctzsi2 (USItype x)
565 Wtype ret;
567 count_trailing_zeros (ret, x);
569 return ret;
571 #endif
573 #ifdef L_ctzdi2
574 Wtype
575 __ctzdi2 (UDItype x)
577 UWtype word;
578 Wtype ret, add;
580 if (sizeof(x) > sizeof(word))
582 DWunion uu;
584 uu.ll = x;
585 if (uu.s.low)
586 word = uu.s.low, add = 0;
587 else
588 word = uu.s.high, add = W_TYPE_SIZE;
590 else
591 word = x, add = 0;
593 count_trailing_zeros (ret, word);
594 return ret + add;
596 #endif
598 #if (defined (L_popcountsi2) || defined (L_popcountdi2) \
599 || defined (L_popcount_tab))
600 extern const UQItype __popcount_tab[] ATTRIBUTE_HIDDEN;
601 #endif
603 #ifdef L_popcount_tab
604 const UQItype __popcount_tab[] =
606 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
607 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
608 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
609 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
610 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
611 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
612 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
613 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
615 #endif
617 #ifdef L_popcountsi2
618 Wtype
619 __popcountsi2 (USItype x)
621 return __popcount_tab[(x >> 0) & 0xff]
622 + __popcount_tab[(x >> 8) & 0xff]
623 + __popcount_tab[(x >> 16) & 0xff]
624 + __popcount_tab[(x >> 24) & 0xff];
626 #endif
628 #ifdef L_popcountdi2
629 Wtype
630 __popcountdi2 (UDItype x)
632 return __popcount_tab[(x >> 0) & 0xff]
633 + __popcount_tab[(x >> 8) & 0xff]
634 + __popcount_tab[(x >> 16) & 0xff]
635 + __popcount_tab[(x >> 24) & 0xff]
636 + __popcount_tab[(x >> 32) & 0xff]
637 + __popcount_tab[(x >> 40) & 0xff]
638 + __popcount_tab[(x >> 48) & 0xff]
639 + __popcount_tab[(x >> 56) & 0xff];
641 #endif
643 #ifdef L_paritysi2
644 Wtype
645 __paritysi2 (USItype x)
647 UWtype nx = x;
648 nx ^= nx >> 16;
649 nx ^= nx >> 8;
650 nx ^= nx >> 4;
651 nx ^= nx >> 2;
652 nx ^= nx >> 1;
653 return nx & 1;
655 #endif
657 #ifdef L_paritydi2
658 Wtype
659 __paritydi2 (UDItype x)
661 UWtype nx = x ^ (x >> 32);
662 nx ^= nx >> 16;
663 nx ^= nx >> 8;
664 nx ^= nx >> 4;
665 nx ^= nx >> 2;
666 nx ^= nx >> 1;
667 return nx & 1;
669 #endif
671 #ifdef L_udivmoddi4
673 #if (defined (L_udivdi3) || defined (L_divdi3) || \
674 defined (L_umoddi3) || defined (L_moddi3))
675 static inline __attribute__ ((__always_inline__))
676 #endif
677 UDWtype
678 __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
680 DWunion ww;
681 DWunion nn, dd;
682 DWunion rr;
683 UWtype d0, d1, n0, n1, n2;
684 UWtype q0, q1;
685 UWtype b, bm;
687 nn.ll = n;
688 dd.ll = d;
690 d0 = dd.s.low;
691 d1 = dd.s.high;
692 n0 = nn.s.low;
693 n1 = nn.s.high;
695 #if !UDIV_NEEDS_NORMALIZATION
696 if (d1 == 0)
698 if (d0 > n1)
700 /* 0q = nn / 0D */
702 udiv_qrnnd (q0, n0, n1, n0, d0);
703 q1 = 0;
705 /* Remainder in n0. */
707 else
709 /* qq = NN / 0d */
711 if (d0 == 0)
712 d0 = 1 / d0; /* Divide intentionally by zero. */
714 udiv_qrnnd (q1, n1, 0, n1, d0);
715 udiv_qrnnd (q0, n0, n1, n0, d0);
717 /* Remainder in n0. */
720 if (rp != 0)
722 rr.s.low = n0;
723 rr.s.high = 0;
724 *rp = rr.ll;
728 #else /* UDIV_NEEDS_NORMALIZATION */
730 if (d1 == 0)
732 if (d0 > n1)
734 /* 0q = nn / 0D */
736 count_leading_zeros (bm, d0);
738 if (bm != 0)
740 /* Normalize, i.e. make the most significant bit of the
741 denominator set. */
743 d0 = d0 << bm;
744 n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
745 n0 = n0 << bm;
748 udiv_qrnnd (q0, n0, n1, n0, d0);
749 q1 = 0;
751 /* Remainder in n0 >> bm. */
753 else
755 /* qq = NN / 0d */
757 if (d0 == 0)
758 d0 = 1 / d0; /* Divide intentionally by zero. */
760 count_leading_zeros (bm, d0);
762 if (bm == 0)
764 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
765 conclude (the most significant bit of n1 is set) /\ (the
766 leading quotient digit q1 = 1).
768 This special case is necessary, not an optimization.
769 (Shifts counts of W_TYPE_SIZE are undefined.) */
771 n1 -= d0;
772 q1 = 1;
774 else
776 /* Normalize. */
778 b = W_TYPE_SIZE - bm;
780 d0 = d0 << bm;
781 n2 = n1 >> b;
782 n1 = (n1 << bm) | (n0 >> b);
783 n0 = n0 << bm;
785 udiv_qrnnd (q1, n1, n2, n1, d0);
788 /* n1 != d0... */
790 udiv_qrnnd (q0, n0, n1, n0, d0);
792 /* Remainder in n0 >> bm. */
795 if (rp != 0)
797 rr.s.low = n0 >> bm;
798 rr.s.high = 0;
799 *rp = rr.ll;
802 #endif /* UDIV_NEEDS_NORMALIZATION */
804 else
806 if (d1 > n1)
808 /* 00 = nn / DD */
810 q0 = 0;
811 q1 = 0;
813 /* Remainder in n1n0. */
814 if (rp != 0)
816 rr.s.low = n0;
817 rr.s.high = n1;
818 *rp = rr.ll;
821 else
823 /* 0q = NN / dd */
825 count_leading_zeros (bm, d1);
826 if (bm == 0)
828 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
829 conclude (the most significant bit of n1 is set) /\ (the
830 quotient digit q0 = 0 or 1).
832 This special case is necessary, not an optimization. */
834 /* The condition on the next line takes advantage of that
835 n1 >= d1 (true due to program flow). */
836 if (n1 > d1 || n0 >= d0)
838 q0 = 1;
839 sub_ddmmss (n1, n0, n1, n0, d1, d0);
841 else
842 q0 = 0;
844 q1 = 0;
846 if (rp != 0)
848 rr.s.low = n0;
849 rr.s.high = n1;
850 *rp = rr.ll;
853 else
855 UWtype m1, m0;
856 /* Normalize. */
858 b = W_TYPE_SIZE - bm;
860 d1 = (d1 << bm) | (d0 >> b);
861 d0 = d0 << bm;
862 n2 = n1 >> b;
863 n1 = (n1 << bm) | (n0 >> b);
864 n0 = n0 << bm;
866 udiv_qrnnd (q0, n1, n2, n1, d1);
867 umul_ppmm (m1, m0, q0, d0);
869 if (m1 > n1 || (m1 == n1 && m0 > n0))
871 q0--;
872 sub_ddmmss (m1, m0, m1, m0, d1, d0);
875 q1 = 0;
877 /* Remainder in (n1n0 - m1m0) >> bm. */
878 if (rp != 0)
880 sub_ddmmss (n1, n0, n1, n0, m1, m0);
881 rr.s.low = (n1 << b) | (n0 >> bm);
882 rr.s.high = n1 >> bm;
883 *rp = rr.ll;
889 ww.s.low = q0;
890 ww.s.high = q1;
891 return ww.ll;
893 #endif
895 #ifdef L_divdi3
896 DWtype
897 __divdi3 (DWtype u, DWtype v)
899 word_type c = 0;
900 DWunion uu, vv;
901 DWtype w;
903 uu.ll = u;
904 vv.ll = v;
906 if (uu.s.high < 0)
907 c = ~c,
908 uu.ll = -uu.ll;
909 if (vv.s.high < 0)
910 c = ~c,
911 vv.ll = -vv.ll;
913 w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
914 if (c)
915 w = -w;
917 return w;
919 #endif
921 #ifdef L_moddi3
922 DWtype
923 __moddi3 (DWtype u, DWtype v)
925 word_type c = 0;
926 DWunion uu, vv;
927 DWtype w;
929 uu.ll = u;
930 vv.ll = v;
932 if (uu.s.high < 0)
933 c = ~c,
934 uu.ll = -uu.ll;
935 if (vv.s.high < 0)
936 vv.ll = -vv.ll;
938 (void) __udivmoddi4 (uu.ll, vv.ll, &w);
939 if (c)
940 w = -w;
942 return w;
944 #endif
946 #ifdef L_umoddi3
947 UDWtype
948 __umoddi3 (UDWtype u, UDWtype v)
950 UDWtype w;
952 (void) __udivmoddi4 (u, v, &w);
954 return w;
956 #endif
958 #ifdef L_udivdi3
959 UDWtype
960 __udivdi3 (UDWtype n, UDWtype d)
962 return __udivmoddi4 (n, d, (UDWtype *) 0);
964 #endif
966 #ifdef L_cmpdi2
967 word_type
968 __cmpdi2 (DWtype a, DWtype b)
970 DWunion au, bu;
972 au.ll = a, bu.ll = b;
974 if (au.s.high < bu.s.high)
975 return 0;
976 else if (au.s.high > bu.s.high)
977 return 2;
978 if ((UWtype) au.s.low < (UWtype) bu.s.low)
979 return 0;
980 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
981 return 2;
982 return 1;
984 #endif
986 #ifdef L_ucmpdi2
987 word_type
988 __ucmpdi2 (DWtype a, DWtype b)
990 DWunion au, bu;
992 au.ll = a, bu.ll = b;
994 if ((UWtype) au.s.high < (UWtype) bu.s.high)
995 return 0;
996 else if ((UWtype) au.s.high > (UWtype) bu.s.high)
997 return 2;
998 if ((UWtype) au.s.low < (UWtype) bu.s.low)
999 return 0;
1000 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
1001 return 2;
1002 return 1;
1004 #endif
1006 #if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
1007 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1008 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1010 DWtype
1011 __fixunstfDI (TFtype a)
1013 TFtype b;
1014 UDWtype v;
1016 if (a < 0)
1017 return 0;
1019 /* Compute high word of result, as a flonum. */
1020 b = (a / HIGH_WORD_COEFF);
1021 /* Convert that to fixed (but not to DWtype!),
1022 and shift it into the high word. */
1023 v = (UWtype) b;
1024 v <<= WORD_SIZE;
1025 /* Remove high part from the TFtype, leaving the low part as flonum. */
1026 a -= (TFtype)v;
1027 /* Convert that to fixed (but not to DWtype!) and add it in.
1028 Sometimes A comes out negative. This is significant, since
1029 A has more bits than a long int does. */
1030 if (a < 0)
1031 v -= (UWtype) (- a);
1032 else
1033 v += (UWtype) a;
1034 return v;
1036 #endif
1038 #if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
1039 DWtype
1040 __fixtfdi (TFtype a)
1042 if (a < 0)
1043 return - __fixunstfDI (-a);
1044 return __fixunstfDI (a);
1046 #endif
1048 #if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
1049 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1050 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1052 DWtype
1053 __fixunsxfDI (XFtype a)
1055 XFtype b;
1056 UDWtype v;
1058 if (a < 0)
1059 return 0;
1061 /* Compute high word of result, as a flonum. */
1062 b = (a / HIGH_WORD_COEFF);
1063 /* Convert that to fixed (but not to DWtype!),
1064 and shift it into the high word. */
1065 v = (UWtype) b;
1066 v <<= WORD_SIZE;
1067 /* Remove high part from the XFtype, leaving the low part as flonum. */
1068 a -= (XFtype)v;
1069 /* Convert that to fixed (but not to DWtype!) and add it in.
1070 Sometimes A comes out negative. This is significant, since
1071 A has more bits than a long int does. */
1072 if (a < 0)
1073 v -= (UWtype) (- a);
1074 else
1075 v += (UWtype) a;
1076 return v;
1078 #endif
1080 #if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
1081 DWtype
1082 __fixxfdi (XFtype a)
1084 if (a < 0)
1085 return - __fixunsxfDI (-a);
1086 return __fixunsxfDI (a);
1088 #endif
1090 #ifdef L_fixunsdfdi
1091 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1092 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1094 DWtype
1095 __fixunsdfDI (DFtype a)
1097 UWtype hi, lo;
1099 /* Get high part of result. The division here will just moves the radix
1100 point and will not cause any rounding. Then the conversion to integral
1101 type chops result as desired. */
1102 hi = a / HIGH_WORD_COEFF;
1104 /* Get low part of result. Convert `hi' to floating type and scale it back,
1105 then subtract this from the number being converted. This leaves the low
1106 part. Convert that to integral type. */
1107 lo = (a - ((DFtype) hi) * HIGH_WORD_COEFF);
1109 /* Assemble result from the two parts. */
1110 return ((UDWtype) hi << WORD_SIZE) | lo;
1112 #endif
1114 #ifdef L_fixdfdi
1115 DWtype
1116 __fixdfdi (DFtype a)
1118 if (a < 0)
1119 return - __fixunsdfDI (-a);
1120 return __fixunsdfDI (a);
1122 #endif
1124 #ifdef L_fixunssfdi
1125 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1126 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1128 DWtype
1129 __fixunssfDI (SFtype original_a)
1131 /* Convert the SFtype to a DFtype, because that is surely not going
1132 to lose any bits. Some day someone else can write a faster version
1133 that avoids converting to DFtype, and verify it really works right. */
1134 DFtype a = original_a;
1135 UWtype hi, lo;
1137 /* Get high part of result. The division here will just moves the radix
1138 point and will not cause any rounding. Then the conversion to integral
1139 type chops result as desired. */
1140 hi = a / HIGH_WORD_COEFF;
1142 /* Get low part of result. Convert `hi' to floating type and scale it back,
1143 then subtract this from the number being converted. This leaves the low
1144 part. Convert that to integral type. */
1145 lo = (a - ((DFtype) hi) * HIGH_WORD_COEFF);
1147 /* Assemble result from the two parts. */
1148 return ((UDWtype) hi << WORD_SIZE) | lo;
1150 #endif
1152 #ifdef L_fixsfdi
1153 DWtype
1154 __fixsfdi (SFtype a)
1156 if (a < 0)
1157 return - __fixunssfDI (-a);
1158 return __fixunssfDI (a);
1160 #endif
1162 #if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
1163 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1164 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1165 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1167 XFtype
1168 __floatdixf (DWtype u)
1170 XFtype d;
1172 d = (Wtype) (u >> WORD_SIZE);
1173 d *= HIGH_HALFWORD_COEFF;
1174 d *= HIGH_HALFWORD_COEFF;
1175 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1177 return d;
1179 #endif
1181 #if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
1182 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1183 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1184 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1186 TFtype
1187 __floatditf (DWtype u)
1189 TFtype d;
1191 d = (Wtype) (u >> WORD_SIZE);
1192 d *= HIGH_HALFWORD_COEFF;
1193 d *= HIGH_HALFWORD_COEFF;
1194 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1196 return d;
1198 #endif
1200 #ifdef L_floatdidf
1201 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1202 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1203 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1205 DFtype
1206 __floatdidf (DWtype u)
1208 DFtype d;
1210 d = (Wtype) (u >> WORD_SIZE);
1211 d *= HIGH_HALFWORD_COEFF;
1212 d *= HIGH_HALFWORD_COEFF;
1213 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1215 return d;
1217 #endif
1219 #ifdef L_floatdisf
1220 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1221 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1222 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1224 #define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT)
1225 #define DF_SIZE DBL_MANT_DIG
1226 #define SF_SIZE FLT_MANT_DIG
1228 SFtype
1229 __floatdisf (DWtype u)
1231 /* Do the calculation in DFmode
1232 so that we don't lose any of the precision of the high word
1233 while multiplying it. */
1234 DFtype f;
1236 /* Protect against double-rounding error.
1237 Represent any low-order bits, that might be truncated in DFmode,
1238 by a bit that won't be lost. The bit can go in anywhere below the
1239 rounding position of the SFmode. A fixed mask and bit position
1240 handles all usual configurations. It doesn't handle the case
1241 of 128-bit DImode, however. */
1242 if (DF_SIZE < DI_SIZE
1243 && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1245 #define REP_BIT ((UDWtype) 1 << (DI_SIZE - DF_SIZE))
1246 if (! (- ((DWtype) 1 << DF_SIZE) < u
1247 && u < ((DWtype) 1 << DF_SIZE)))
1249 if ((UDWtype) u & (REP_BIT - 1))
1251 u &= ~ (REP_BIT - 1);
1252 u |= REP_BIT;
1256 f = (Wtype) (u >> WORD_SIZE);
1257 f *= HIGH_HALFWORD_COEFF;
1258 f *= HIGH_HALFWORD_COEFF;
1259 f += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1261 return (SFtype) f;
1263 #endif
1265 #if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
1266 /* Reenable the normal types, in case limits.h needs them. */
1267 #undef char
1268 #undef short
1269 #undef int
1270 #undef long
1271 #undef unsigned
1272 #undef float
1273 #undef double
1274 #undef MIN
1275 #undef MAX
1276 #include <limits.h>
1278 UWtype
1279 __fixunsxfSI (XFtype a)
1281 if (a >= - (DFtype) Wtype_MIN)
1282 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1283 return (Wtype) a;
1285 #endif
1287 #ifdef L_fixunsdfsi
1288 /* Reenable the normal types, in case limits.h needs them. */
1289 #undef char
1290 #undef short
1291 #undef int
1292 #undef long
1293 #undef unsigned
1294 #undef float
1295 #undef double
1296 #undef MIN
1297 #undef MAX
1298 #include <limits.h>
1300 UWtype
1301 __fixunsdfSI (DFtype a)
1303 if (a >= - (DFtype) Wtype_MIN)
1304 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1305 return (Wtype) a;
1307 #endif
1309 #ifdef L_fixunssfsi
1310 /* Reenable the normal types, in case limits.h needs them. */
1311 #undef char
1312 #undef short
1313 #undef int
1314 #undef long
1315 #undef unsigned
1316 #undef float
1317 #undef double
1318 #undef MIN
1319 #undef MAX
1320 #include <limits.h>
1322 UWtype
1323 __fixunssfSI (SFtype a)
1325 if (a >= - (SFtype) Wtype_MIN)
1326 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1327 return (Wtype) a;
1329 #endif
1331 /* From here on down, the routines use normal data types. */
1333 #define SItype bogus_type
1334 #define USItype bogus_type
1335 #define DItype bogus_type
1336 #define UDItype bogus_type
1337 #define SFtype bogus_type
1338 #define DFtype bogus_type
1339 #undef Wtype
1340 #undef UWtype
1341 #undef HWtype
1342 #undef UHWtype
1343 #undef DWtype
1344 #undef UDWtype
1346 #undef char
1347 #undef short
1348 #undef int
1349 #undef long
1350 #undef unsigned
1351 #undef float
1352 #undef double
1354 #ifdef L__gcc_bcmp
1356 /* Like bcmp except the sign is meaningful.
1357 Result is negative if S1 is less than S2,
1358 positive if S1 is greater, 0 if S1 and S2 are equal. */
1361 __gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
1363 while (size > 0)
1365 unsigned char c1 = *s1++, c2 = *s2++;
1366 if (c1 != c2)
1367 return c1 - c2;
1368 size--;
1370 return 0;
1373 #endif
1375 /* __eprintf used to be used by GCC's private version of <assert.h>.
1376 We no longer provide that header, but this routine remains in libgcc.a
1377 for binary backward compatibility. Note that it is not included in
1378 the shared version of libgcc. */
1379 #ifdef L_eprintf
1380 #ifndef inhibit_libc
1382 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1383 #include <stdio.h>
1385 void
1386 __eprintf (const char *string, const char *expression,
1387 unsigned int line, const char *filename)
1389 fprintf (stderr, string, expression, line, filename);
1390 fflush (stderr);
1391 abort ();
1394 #endif
1395 #endif
1398 #ifdef L_clear_cache
1399 /* Clear part of an instruction cache. */
1401 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1403 void
1404 __clear_cache (char *beg __attribute__((__unused__)),
1405 char *end __attribute__((__unused__)))
1407 #ifdef CLEAR_INSN_CACHE
1408 CLEAR_INSN_CACHE (beg, end);
1409 #else
1410 #ifdef INSN_CACHE_SIZE
1411 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1412 static int initialized;
1413 int offset;
1414 void *start_addr
1415 void *end_addr;
1416 typedef (*function_ptr) (void);
1418 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1419 /* It's cheaper to clear the whole cache.
1420 Put in a series of jump instructions so that calling the beginning
1421 of the cache will clear the whole thing. */
1423 if (! initialized)
1425 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1426 & -INSN_CACHE_LINE_WIDTH);
1427 int end_ptr = ptr + INSN_CACHE_SIZE;
1429 while (ptr < end_ptr)
1431 *(INSTRUCTION_TYPE *)ptr
1432 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1433 ptr += INSN_CACHE_LINE_WIDTH;
1435 *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1437 initialized = 1;
1440 /* Call the beginning of the sequence. */
1441 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1442 & -INSN_CACHE_LINE_WIDTH))
1443 ());
1445 #else /* Cache is large. */
1447 if (! initialized)
1449 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1450 & -INSN_CACHE_LINE_WIDTH);
1452 while (ptr < (int) array + sizeof array)
1454 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1455 ptr += INSN_CACHE_LINE_WIDTH;
1458 initialized = 1;
1461 /* Find the location in array that occupies the same cache line as BEG. */
1463 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1464 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1465 & -INSN_CACHE_PLANE_SIZE)
1466 + offset);
1468 /* Compute the cache alignment of the place to stop clearing. */
1469 #if 0 /* This is not needed for gcc's purposes. */
1470 /* If the block to clear is bigger than a cache plane,
1471 we clear the entire cache, and OFFSET is already correct. */
1472 if (end < beg + INSN_CACHE_PLANE_SIZE)
1473 #endif
1474 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1475 & -INSN_CACHE_LINE_WIDTH)
1476 & (INSN_CACHE_PLANE_SIZE - 1));
1478 #if INSN_CACHE_DEPTH > 1
1479 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1480 if (end_addr <= start_addr)
1481 end_addr += INSN_CACHE_PLANE_SIZE;
1483 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1485 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1486 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1488 while (addr != stop)
1490 /* Call the return instruction at ADDR. */
1491 ((function_ptr) addr) ();
1493 addr += INSN_CACHE_LINE_WIDTH;
1496 #else /* just one plane */
1499 /* Call the return instruction at START_ADDR. */
1500 ((function_ptr) start_addr) ();
1502 start_addr += INSN_CACHE_LINE_WIDTH;
1504 while ((start_addr % INSN_CACHE_SIZE) != offset);
1505 #endif /* just one plane */
1506 #endif /* Cache is large */
1507 #endif /* Cache exists */
1508 #endif /* CLEAR_INSN_CACHE */
1511 #endif /* L_clear_cache */
1513 #ifdef L_trampoline
1515 /* Jump to a trampoline, loading the static chain address. */
1517 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
1519 long
1520 getpagesize (void)
1522 #ifdef _ALPHA_
1523 return 8192;
1524 #else
1525 return 4096;
1526 #endif
1529 #ifdef __i386__
1530 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
1531 #endif
1534 mprotect (char *addr, int len, int prot)
1536 int np, op;
1538 if (prot == 7)
1539 np = 0x40;
1540 else if (prot == 5)
1541 np = 0x20;
1542 else if (prot == 4)
1543 np = 0x10;
1544 else if (prot == 3)
1545 np = 0x04;
1546 else if (prot == 1)
1547 np = 0x02;
1548 else if (prot == 0)
1549 np = 0x01;
1551 if (VirtualProtect (addr, len, np, &op))
1552 return 0;
1553 else
1554 return -1;
1557 #endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
1559 #ifdef TRANSFER_FROM_TRAMPOLINE
1560 TRANSFER_FROM_TRAMPOLINE
1561 #endif
1563 #ifdef __sysV68__
1565 #include <sys/signal.h>
1566 #include <errno.h>
1568 /* Motorola forgot to put memctl.o in the libp version of libc881.a,
1569 so define it here, because we need it in __clear_insn_cache below */
1570 /* On older versions of this OS, no memctl or MCT_TEXT are defined;
1571 hence we enable this stuff only if MCT_TEXT is #define'd. */
1573 #ifdef MCT_TEXT
1574 asm("\n\
1575 global memctl\n\
1576 memctl:\n\
1577 movq &75,%d0\n\
1578 trap &0\n\
1579 bcc.b noerror\n\
1580 jmp cerror%\n\
1581 noerror:\n\
1582 movq &0,%d0\n\
1583 rts");
1584 #endif
1586 /* Clear instruction cache so we can call trampolines on stack.
1587 This is called from FINALIZE_TRAMPOLINE in mot3300.h. */
1589 void
1590 __clear_insn_cache (void)
1592 #ifdef MCT_TEXT
1593 int save_errno;
1595 /* Preserve errno, because users would be surprised to have
1596 errno changing without explicitly calling any system-call. */
1597 save_errno = errno;
1599 /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache.
1600 No need to use an address derived from _start or %sp, as 0 works also. */
1601 memctl(0, 4096, MCT_TEXT);
1602 errno = save_errno;
1603 #endif
1606 #endif /* __sysV68__ */
1607 #endif /* L_trampoline */
1609 #ifndef __CYGWIN__
1610 #ifdef L__main
1612 #include "gbl-ctors.h"
1613 /* Some systems use __main in a way incompatible with its use in gcc, in these
1614 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
1615 give the same symbol without quotes for an alternative entry point. You
1616 must define both, or neither. */
1617 #ifndef NAME__MAIN
1618 #define NAME__MAIN "__main"
1619 #define SYMBOL__MAIN __main
1620 #endif
1622 #ifdef INIT_SECTION_ASM_OP
1623 #undef HAS_INIT_SECTION
1624 #define HAS_INIT_SECTION
1625 #endif
1627 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
1629 /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
1630 code to run constructors. In that case, we need to handle EH here, too. */
1632 #ifdef EH_FRAME_SECTION_NAME
1633 #include "unwind-dw2-fde.h"
1634 extern unsigned char __EH_FRAME_BEGIN__[];
1635 #endif
1637 /* Run all the global destructors on exit from the program. */
1639 void
1640 __do_global_dtors (void)
1642 #ifdef DO_GLOBAL_DTORS_BODY
1643 DO_GLOBAL_DTORS_BODY;
1644 #else
1645 static func_ptr *p = __DTOR_LIST__ + 1;
1646 while (*p)
1648 p++;
1649 (*(p-1)) ();
1651 #endif
1652 #if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION)
1654 static int completed = 0;
1655 if (! completed)
1657 completed = 1;
1658 __deregister_frame_info (__EH_FRAME_BEGIN__);
1661 #endif
1663 #endif
1665 #ifndef HAS_INIT_SECTION
1666 /* Run all the global constructors on entry to the program. */
1668 void
1669 __do_global_ctors (void)
1671 #ifdef EH_FRAME_SECTION_NAME
1673 static struct object object;
1674 __register_frame_info (__EH_FRAME_BEGIN__, &object);
1676 #endif
1677 DO_GLOBAL_CTORS_BODY;
1678 atexit (__do_global_dtors);
1680 #endif /* no HAS_INIT_SECTION */
1682 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
1683 /* Subroutine called automatically by `main'.
1684 Compiling a global function named `main'
1685 produces an automatic call to this function at the beginning.
1687 For many systems, this routine calls __do_global_ctors.
1688 For systems which support a .init section we use the .init section
1689 to run __do_global_ctors, so we need not do anything here. */
1691 void
1692 SYMBOL__MAIN ()
1694 /* Support recursive calls to `main': run initializers just once. */
1695 static int initialized;
1696 if (! initialized)
1698 initialized = 1;
1699 __do_global_ctors ();
1702 #endif /* no HAS_INIT_SECTION or INVOKE__main */
1704 #endif /* L__main */
1705 #endif /* __CYGWIN__ */
1707 #ifdef L_ctors
1709 #include "gbl-ctors.h"
1711 /* Provide default definitions for the lists of constructors and
1712 destructors, so that we don't get linker errors. These symbols are
1713 intentionally bss symbols, so that gld and/or collect will provide
1714 the right values. */
1716 /* We declare the lists here with two elements each,
1717 so that they are valid empty lists if no other definition is loaded.
1719 If we are using the old "set" extensions to have the gnu linker
1720 collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
1721 must be in the bss/common section.
1723 Long term no port should use those extensions. But many still do. */
1724 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
1725 #if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2)
1726 func_ptr __CTOR_LIST__[2] = {0, 0};
1727 func_ptr __DTOR_LIST__[2] = {0, 0};
1728 #else
1729 func_ptr __CTOR_LIST__[2];
1730 func_ptr __DTOR_LIST__[2];
1731 #endif
1732 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1733 #endif /* L_ctors */
1735 #ifdef L_exit
1737 #include "gbl-ctors.h"
1739 #ifdef NEED_ATEXIT
1741 #ifndef ON_EXIT
1743 # include <errno.h>
1745 static func_ptr *atexit_chain = 0;
1746 static long atexit_chain_length = 0;
1747 static volatile long last_atexit_chain_slot = -1;
1750 atexit (func_ptr func)
1752 if (++last_atexit_chain_slot == atexit_chain_length)
1754 atexit_chain_length += 32;
1755 if (atexit_chain)
1756 atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
1757 * sizeof (func_ptr));
1758 else
1759 atexit_chain = (func_ptr *) malloc (atexit_chain_length
1760 * sizeof (func_ptr));
1761 if (! atexit_chain)
1763 atexit_chain_length = 0;
1764 last_atexit_chain_slot = -1;
1765 errno = ENOMEM;
1766 return (-1);
1769 atexit_chain[last_atexit_chain_slot] = func;
1770 return (0);
1773 extern void _cleanup (void);
1774 extern void _exit (int) __attribute__ ((__noreturn__));
1776 void
1777 exit (int status)
1779 if (atexit_chain)
1781 for ( ; last_atexit_chain_slot-- >= 0; )
1783 (*atexit_chain[last_atexit_chain_slot + 1]) ();
1784 atexit_chain[last_atexit_chain_slot + 1] = 0;
1786 free (atexit_chain);
1787 atexit_chain = 0;
1789 #ifdef EXIT_BODY
1790 EXIT_BODY;
1791 #else
1792 _cleanup ();
1793 #endif
1794 _exit (status);
1797 #else /* ON_EXIT */
1799 /* Simple; we just need a wrapper for ON_EXIT. */
1801 atexit (func_ptr func)
1803 return ON_EXIT (func);
1806 #endif /* ON_EXIT */
1807 #endif /* NEED_ATEXIT */
1809 #endif /* L_exit */