* Makefile.am (nat_source_files): Remove
[official-gcc.git] / gcc / libgcc2.c
blob069aedb14c1d88d669c8d9a86f1dd7bd5c93f7a5
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 __addvdi3 (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_ffssi2
344 #undef int
345 extern int __ffsSI2 (UWtype u);
347 __ffsSI2 (UWtype u)
349 UWtype count;
351 if (u == 0)
352 return 0;
354 count_trailing_zeros (count, u);
355 return count + 1;
357 #endif
359 #ifdef L_ffsdi2
360 #undef int
361 extern int __ffsDI2 (DWtype u);
363 __ffsDI2 (DWtype u)
365 DWunion uu;
366 UWtype word, count, add;
368 uu.ll = u;
369 if (uu.s.low != 0)
370 word = uu.s.low, add = 0;
371 else if (uu.s.high != 0)
372 word = uu.s.high, add = BITS_PER_UNIT * sizeof (Wtype);
373 else
374 return 0;
376 count_trailing_zeros (count, word);
377 return count + add + 1;
379 #endif
381 #ifdef L_muldi3
382 DWtype
383 __muldi3 (DWtype u, DWtype v)
385 DWunion w;
386 DWunion uu, vv;
388 uu.ll = u,
389 vv.ll = v;
391 w.ll = __umulsidi3 (uu.s.low, vv.s.low);
392 w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
393 + (UWtype) uu.s.high * (UWtype) vv.s.low);
395 return w.ll;
397 #endif
399 #if (defined (L_udivdi3) || defined (L_divdi3) || \
400 defined (L_umoddi3) || defined (L_moddi3))
401 #if defined (sdiv_qrnnd)
402 #define L_udiv_w_sdiv
403 #endif
404 #endif
406 #ifdef L_udiv_w_sdiv
407 #if defined (sdiv_qrnnd)
408 #if (defined (L_udivdi3) || defined (L_divdi3) || \
409 defined (L_umoddi3) || defined (L_moddi3))
410 static inline __attribute__ ((__always_inline__))
411 #endif
412 UWtype
413 __udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d)
415 UWtype q, r;
416 UWtype c0, c1, b1;
418 if ((Wtype) d >= 0)
420 if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1)))
422 /* dividend, divisor, and quotient are nonnegative */
423 sdiv_qrnnd (q, r, a1, a0, d);
425 else
427 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
428 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1));
429 /* Divide (c1*2^32 + c0) by d */
430 sdiv_qrnnd (q, r, c1, c0, d);
431 /* Add 2^31 to quotient */
432 q += (UWtype) 1 << (W_TYPE_SIZE - 1);
435 else
437 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
438 c1 = a1 >> 1; /* A/2 */
439 c0 = (a1 << (W_TYPE_SIZE - 1)) + (a0 >> 1);
441 if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
443 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
445 r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
446 if ((d & 1) != 0)
448 if (r >= q)
449 r = r - q;
450 else if (q - r <= d)
452 r = r - q + d;
453 q--;
455 else
457 r = r - q + 2*d;
458 q -= 2;
462 else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
464 c1 = (b1 - 1) - c1;
465 c0 = ~c0; /* logical NOT */
467 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
469 q = ~q; /* (A/2)/b1 */
470 r = (b1 - 1) - r;
472 r = 2*r + (a0 & 1); /* A/(2*b1) */
474 if ((d & 1) != 0)
476 if (r >= q)
477 r = r - q;
478 else if (q - r <= d)
480 r = r - q + d;
481 q--;
483 else
485 r = r - q + 2*d;
486 q -= 2;
490 else /* Implies c1 = b1 */
491 { /* Hence a1 = d - 1 = 2*b1 - 1 */
492 if (a0 >= -d)
494 q = -1;
495 r = a0 + d;
497 else
499 q = -2;
500 r = a0 + 2*d;
505 *rp = r;
506 return q;
508 #else
509 /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */
510 UWtype
511 __udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)),
512 UWtype a1 __attribute__ ((__unused__)),
513 UWtype a0 __attribute__ ((__unused__)),
514 UWtype d __attribute__ ((__unused__)))
516 return 0;
518 #endif
519 #endif
521 #if (defined (L_udivdi3) || defined (L_divdi3) || \
522 defined (L_umoddi3) || defined (L_moddi3))
523 #define L_udivmoddi4
524 #endif
526 #ifdef L_clz
527 const UQItype __clz_tab[] =
529 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,
530 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,
531 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,
532 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,
533 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,
534 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,
535 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,
536 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,
538 #endif
540 #ifdef L_clzsi2
541 #undef int
542 extern int __clzSI2 (UWtype x);
544 __clzSI2 (UWtype x)
546 Wtype ret;
548 count_leading_zeros (ret, x);
550 return ret;
552 #endif
554 #ifdef L_clzdi2
555 #undef int
556 extern int __clzDI2 (UDWtype x);
558 __clzDI2 (UDWtype x)
560 DWunion uu;
561 UWtype word;
562 Wtype ret, add;
564 uu.ll = x;
565 if (uu.s.high)
566 word = uu.s.high, add = 0;
567 else
568 word = uu.s.low, add = W_TYPE_SIZE;
570 count_leading_zeros (ret, word);
571 return ret + add;
573 #endif
575 #ifdef L_ctzsi2
576 #undef int
577 extern int __ctzSI2 (UWtype x);
579 __ctzSI2 (UWtype x)
581 Wtype ret;
583 count_trailing_zeros (ret, x);
585 return ret;
587 #endif
589 #ifdef L_ctzdi2
590 #undef int
591 extern int __ctzDI2 (UDWtype x);
593 __ctzDI2 (UDWtype x)
595 DWunion uu;
596 UWtype word;
597 Wtype ret, add;
599 uu.ll = x;
600 if (uu.s.low)
601 word = uu.s.low, add = 0;
602 else
603 word = uu.s.high, add = W_TYPE_SIZE;
605 count_trailing_zeros (ret, word);
606 return ret + add;
608 #endif
610 #if (defined (L_popcountsi2) || defined (L_popcountdi2) \
611 || defined (L_popcount_tab))
612 extern const UQItype __popcount_tab[] ATTRIBUTE_HIDDEN;
613 #endif
615 #ifdef L_popcount_tab
616 const UQItype __popcount_tab[] =
618 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,
619 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,
620 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,
621 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,
622 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,
623 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,
624 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,
625 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,
627 #endif
629 #ifdef L_popcountsi2
630 #undef int
631 extern int __popcountSI2 (UWtype x);
633 __popcountSI2 (UWtype x)
635 UWtype i, ret = 0;
637 for (i = 0; i < W_TYPE_SIZE; i += 8)
638 ret += __popcount_tab[(x >> i) & 0xff];
640 return ret;
642 #endif
644 #ifdef L_popcountdi2
645 #undef int
646 extern int __popcountDI2 (UDWtype x);
648 __popcountDI2 (UDWtype x)
650 UWtype i, ret = 0;
652 for (i = 0; i < 2*W_TYPE_SIZE; i += 8)
653 ret += __popcount_tab[(x >> i) & 0xff];
655 return ret;
657 #endif
659 #ifdef L_paritysi2
660 #undef int
661 extern int __paritySI2 (UWtype x);
663 __paritySI2 (UWtype x)
665 #if W_TYPE_SIZE > 64
666 # error "fill out the table"
667 #endif
668 #if W_TYPE_SIZE > 32
669 x ^= x >> 32;
670 #endif
671 #if W_TYPE_SIZE > 16
672 x ^= x >> 16;
673 #endif
674 x ^= x >> 8;
675 x ^= x >> 4;
676 x &= 0xf;
677 return (0x6996 >> x) & 1;
679 #endif
681 #ifdef L_paritydi2
682 #undef int
683 extern int __parityDI2 (UDWtype x);
685 __parityDI2 (UDWtype x)
687 DWunion uu;
688 UWtype nx;
690 uu.ll = x;
691 nx = uu.s.low ^ uu.s.high;
693 #if W_TYPE_SIZE > 64
694 # error "fill out the table"
695 #endif
696 #if W_TYPE_SIZE > 32
697 nx ^= nx >> 32;
698 #endif
699 #if W_TYPE_SIZE > 16
700 nx ^= nx >> 16;
701 #endif
702 nx ^= nx >> 8;
703 nx ^= nx >> 4;
704 nx &= 0xf;
705 return (0x6996 >> nx) & 1;
707 #endif
709 #ifdef L_udivmoddi4
711 #if (defined (L_udivdi3) || defined (L_divdi3) || \
712 defined (L_umoddi3) || defined (L_moddi3))
713 static inline __attribute__ ((__always_inline__))
714 #endif
715 UDWtype
716 __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
718 DWunion ww;
719 DWunion nn, dd;
720 DWunion rr;
721 UWtype d0, d1, n0, n1, n2;
722 UWtype q0, q1;
723 UWtype b, bm;
725 nn.ll = n;
726 dd.ll = d;
728 d0 = dd.s.low;
729 d1 = dd.s.high;
730 n0 = nn.s.low;
731 n1 = nn.s.high;
733 #if !UDIV_NEEDS_NORMALIZATION
734 if (d1 == 0)
736 if (d0 > n1)
738 /* 0q = nn / 0D */
740 udiv_qrnnd (q0, n0, n1, n0, d0);
741 q1 = 0;
743 /* Remainder in n0. */
745 else
747 /* qq = NN / 0d */
749 if (d0 == 0)
750 d0 = 1 / d0; /* Divide intentionally by zero. */
752 udiv_qrnnd (q1, n1, 0, n1, d0);
753 udiv_qrnnd (q0, n0, n1, n0, d0);
755 /* Remainder in n0. */
758 if (rp != 0)
760 rr.s.low = n0;
761 rr.s.high = 0;
762 *rp = rr.ll;
766 #else /* UDIV_NEEDS_NORMALIZATION */
768 if (d1 == 0)
770 if (d0 > n1)
772 /* 0q = nn / 0D */
774 count_leading_zeros (bm, d0);
776 if (bm != 0)
778 /* Normalize, i.e. make the most significant bit of the
779 denominator set. */
781 d0 = d0 << bm;
782 n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
783 n0 = n0 << bm;
786 udiv_qrnnd (q0, n0, n1, n0, d0);
787 q1 = 0;
789 /* Remainder in n0 >> bm. */
791 else
793 /* qq = NN / 0d */
795 if (d0 == 0)
796 d0 = 1 / d0; /* Divide intentionally by zero. */
798 count_leading_zeros (bm, d0);
800 if (bm == 0)
802 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
803 conclude (the most significant bit of n1 is set) /\ (the
804 leading quotient digit q1 = 1).
806 This special case is necessary, not an optimization.
807 (Shifts counts of W_TYPE_SIZE are undefined.) */
809 n1 -= d0;
810 q1 = 1;
812 else
814 /* Normalize. */
816 b = W_TYPE_SIZE - bm;
818 d0 = d0 << bm;
819 n2 = n1 >> b;
820 n1 = (n1 << bm) | (n0 >> b);
821 n0 = n0 << bm;
823 udiv_qrnnd (q1, n1, n2, n1, d0);
826 /* n1 != d0... */
828 udiv_qrnnd (q0, n0, n1, n0, d0);
830 /* Remainder in n0 >> bm. */
833 if (rp != 0)
835 rr.s.low = n0 >> bm;
836 rr.s.high = 0;
837 *rp = rr.ll;
840 #endif /* UDIV_NEEDS_NORMALIZATION */
842 else
844 if (d1 > n1)
846 /* 00 = nn / DD */
848 q0 = 0;
849 q1 = 0;
851 /* Remainder in n1n0. */
852 if (rp != 0)
854 rr.s.low = n0;
855 rr.s.high = n1;
856 *rp = rr.ll;
859 else
861 /* 0q = NN / dd */
863 count_leading_zeros (bm, d1);
864 if (bm == 0)
866 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
867 conclude (the most significant bit of n1 is set) /\ (the
868 quotient digit q0 = 0 or 1).
870 This special case is necessary, not an optimization. */
872 /* The condition on the next line takes advantage of that
873 n1 >= d1 (true due to program flow). */
874 if (n1 > d1 || n0 >= d0)
876 q0 = 1;
877 sub_ddmmss (n1, n0, n1, n0, d1, d0);
879 else
880 q0 = 0;
882 q1 = 0;
884 if (rp != 0)
886 rr.s.low = n0;
887 rr.s.high = n1;
888 *rp = rr.ll;
891 else
893 UWtype m1, m0;
894 /* Normalize. */
896 b = W_TYPE_SIZE - bm;
898 d1 = (d1 << bm) | (d0 >> b);
899 d0 = d0 << bm;
900 n2 = n1 >> b;
901 n1 = (n1 << bm) | (n0 >> b);
902 n0 = n0 << bm;
904 udiv_qrnnd (q0, n1, n2, n1, d1);
905 umul_ppmm (m1, m0, q0, d0);
907 if (m1 > n1 || (m1 == n1 && m0 > n0))
909 q0--;
910 sub_ddmmss (m1, m0, m1, m0, d1, d0);
913 q1 = 0;
915 /* Remainder in (n1n0 - m1m0) >> bm. */
916 if (rp != 0)
918 sub_ddmmss (n1, n0, n1, n0, m1, m0);
919 rr.s.low = (n1 << b) | (n0 >> bm);
920 rr.s.high = n1 >> bm;
921 *rp = rr.ll;
927 ww.s.low = q0;
928 ww.s.high = q1;
929 return ww.ll;
931 #endif
933 #ifdef L_divdi3
934 DWtype
935 __divdi3 (DWtype u, DWtype v)
937 word_type c = 0;
938 DWunion uu, vv;
939 DWtype w;
941 uu.ll = u;
942 vv.ll = v;
944 if (uu.s.high < 0)
945 c = ~c,
946 uu.ll = -uu.ll;
947 if (vv.s.high < 0)
948 c = ~c,
949 vv.ll = -vv.ll;
951 w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
952 if (c)
953 w = -w;
955 return w;
957 #endif
959 #ifdef L_moddi3
960 DWtype
961 __moddi3 (DWtype u, DWtype v)
963 word_type c = 0;
964 DWunion uu, vv;
965 DWtype w;
967 uu.ll = u;
968 vv.ll = v;
970 if (uu.s.high < 0)
971 c = ~c,
972 uu.ll = -uu.ll;
973 if (vv.s.high < 0)
974 vv.ll = -vv.ll;
976 (void) __udivmoddi4 (uu.ll, vv.ll, &w);
977 if (c)
978 w = -w;
980 return w;
982 #endif
984 #ifdef L_umoddi3
985 UDWtype
986 __umoddi3 (UDWtype u, UDWtype v)
988 UDWtype w;
990 (void) __udivmoddi4 (u, v, &w);
992 return w;
994 #endif
996 #ifdef L_udivdi3
997 UDWtype
998 __udivdi3 (UDWtype n, UDWtype d)
1000 return __udivmoddi4 (n, d, (UDWtype *) 0);
1002 #endif
1004 #ifdef L_cmpdi2
1005 word_type
1006 __cmpdi2 (DWtype a, DWtype b)
1008 DWunion au, bu;
1010 au.ll = a, bu.ll = b;
1012 if (au.s.high < bu.s.high)
1013 return 0;
1014 else if (au.s.high > bu.s.high)
1015 return 2;
1016 if ((UWtype) au.s.low < (UWtype) bu.s.low)
1017 return 0;
1018 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
1019 return 2;
1020 return 1;
1022 #endif
1024 #ifdef L_ucmpdi2
1025 word_type
1026 __ucmpdi2 (DWtype a, DWtype b)
1028 DWunion au, bu;
1030 au.ll = a, bu.ll = b;
1032 if ((UWtype) au.s.high < (UWtype) bu.s.high)
1033 return 0;
1034 else if ((UWtype) au.s.high > (UWtype) bu.s.high)
1035 return 2;
1036 if ((UWtype) au.s.low < (UWtype) bu.s.low)
1037 return 0;
1038 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
1039 return 2;
1040 return 1;
1042 #endif
1044 #if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
1045 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1046 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1048 DWtype
1049 __fixunstfDI (TFtype a)
1051 TFtype b;
1052 UDWtype v;
1054 if (a < 0)
1055 return 0;
1057 /* Compute high word of result, as a flonum. */
1058 b = (a / HIGH_WORD_COEFF);
1059 /* Convert that to fixed (but not to DWtype!),
1060 and shift it into the high word. */
1061 v = (UWtype) b;
1062 v <<= WORD_SIZE;
1063 /* Remove high part from the TFtype, leaving the low part as flonum. */
1064 a -= (TFtype)v;
1065 /* Convert that to fixed (but not to DWtype!) and add it in.
1066 Sometimes A comes out negative. This is significant, since
1067 A has more bits than a long int does. */
1068 if (a < 0)
1069 v -= (UWtype) (- a);
1070 else
1071 v += (UWtype) a;
1072 return v;
1074 #endif
1076 #if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
1077 DWtype
1078 __fixtfdi (TFtype a)
1080 if (a < 0)
1081 return - __fixunstfDI (-a);
1082 return __fixunstfDI (a);
1084 #endif
1086 #if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
1087 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1088 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1090 DWtype
1091 __fixunsxfDI (XFtype a)
1093 XFtype b;
1094 UDWtype v;
1096 if (a < 0)
1097 return 0;
1099 /* Compute high word of result, as a flonum. */
1100 b = (a / HIGH_WORD_COEFF);
1101 /* Convert that to fixed (but not to DWtype!),
1102 and shift it into the high word. */
1103 v = (UWtype) b;
1104 v <<= WORD_SIZE;
1105 /* Remove high part from the XFtype, leaving the low part as flonum. */
1106 a -= (XFtype)v;
1107 /* Convert that to fixed (but not to DWtype!) and add it in.
1108 Sometimes A comes out negative. This is significant, since
1109 A has more bits than a long int does. */
1110 if (a < 0)
1111 v -= (UWtype) (- a);
1112 else
1113 v += (UWtype) a;
1114 return v;
1116 #endif
1118 #if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
1119 DWtype
1120 __fixxfdi (XFtype a)
1122 if (a < 0)
1123 return - __fixunsxfDI (-a);
1124 return __fixunsxfDI (a);
1126 #endif
1128 #ifdef L_fixunsdfdi
1129 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1130 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1132 DWtype
1133 __fixunsdfDI (DFtype 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_fixdfdi
1153 DWtype
1154 __fixdfdi (DFtype a)
1156 if (a < 0)
1157 return - __fixunsdfDI (-a);
1158 return __fixunsdfDI (a);
1160 #endif
1162 #ifdef L_fixunssfdi
1163 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1164 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1166 DWtype
1167 __fixunssfDI (SFtype original_a)
1169 /* Convert the SFtype to a DFtype, because that is surely not going
1170 to lose any bits. Some day someone else can write a faster version
1171 that avoids converting to DFtype, and verify it really works right. */
1172 DFtype a = original_a;
1173 UWtype hi, lo;
1175 /* Get high part of result. The division here will just moves the radix
1176 point and will not cause any rounding. Then the conversion to integral
1177 type chops result as desired. */
1178 hi = a / HIGH_WORD_COEFF;
1180 /* Get low part of result. Convert `hi' to floating type and scale it back,
1181 then subtract this from the number being converted. This leaves the low
1182 part. Convert that to integral type. */
1183 lo = (a - ((DFtype) hi) * HIGH_WORD_COEFF);
1185 /* Assemble result from the two parts. */
1186 return ((UDWtype) hi << WORD_SIZE) | lo;
1188 #endif
1190 #ifdef L_fixsfdi
1191 DWtype
1192 __fixsfdi (SFtype a)
1194 if (a < 0)
1195 return - __fixunssfDI (-a);
1196 return __fixunssfDI (a);
1198 #endif
1200 #if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
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 XFtype
1206 __floatdixf (DWtype u)
1208 XFtype 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 #if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
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 TFtype
1225 __floatditf (DWtype u)
1227 TFtype d;
1229 d = (Wtype) (u >> WORD_SIZE);
1230 d *= HIGH_HALFWORD_COEFF;
1231 d *= HIGH_HALFWORD_COEFF;
1232 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1234 return d;
1236 #endif
1238 #ifdef L_floatdidf
1239 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1240 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1241 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1243 DFtype
1244 __floatdidf (DWtype u)
1246 DFtype d;
1248 d = (Wtype) (u >> WORD_SIZE);
1249 d *= HIGH_HALFWORD_COEFF;
1250 d *= HIGH_HALFWORD_COEFF;
1251 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1253 return d;
1255 #endif
1257 #ifdef L_floatdisf
1258 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1259 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1260 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1262 #define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT)
1263 #define DF_SIZE DBL_MANT_DIG
1264 #define SF_SIZE FLT_MANT_DIG
1266 SFtype
1267 __floatdisf (DWtype u)
1269 /* Do the calculation in DFmode
1270 so that we don't lose any of the precision of the high word
1271 while multiplying it. */
1272 DFtype f;
1274 /* Protect against double-rounding error.
1275 Represent any low-order bits, that might be truncated in DFmode,
1276 by a bit that won't be lost. The bit can go in anywhere below the
1277 rounding position of the SFmode. A fixed mask and bit position
1278 handles all usual configurations. It doesn't handle the case
1279 of 128-bit DImode, however. */
1280 if (DF_SIZE < DI_SIZE
1281 && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1283 #define REP_BIT ((UDWtype) 1 << (DI_SIZE - DF_SIZE))
1284 if (! (- ((DWtype) 1 << DF_SIZE) < u
1285 && u < ((DWtype) 1 << DF_SIZE)))
1287 if ((UDWtype) u & (REP_BIT - 1))
1289 u &= ~ (REP_BIT - 1);
1290 u |= REP_BIT;
1294 f = (Wtype) (u >> WORD_SIZE);
1295 f *= HIGH_HALFWORD_COEFF;
1296 f *= HIGH_HALFWORD_COEFF;
1297 f += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1299 return (SFtype) f;
1301 #endif
1303 #if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
1304 /* Reenable the normal types, in case limits.h needs them. */
1305 #undef char
1306 #undef short
1307 #undef int
1308 #undef long
1309 #undef unsigned
1310 #undef float
1311 #undef double
1312 #undef MIN
1313 #undef MAX
1314 #include <limits.h>
1316 UWtype
1317 __fixunsxfSI (XFtype a)
1319 if (a >= - (DFtype) Wtype_MIN)
1320 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1321 return (Wtype) a;
1323 #endif
1325 #ifdef L_fixunsdfsi
1326 /* Reenable the normal types, in case limits.h needs them. */
1327 #undef char
1328 #undef short
1329 #undef int
1330 #undef long
1331 #undef unsigned
1332 #undef float
1333 #undef double
1334 #undef MIN
1335 #undef MAX
1336 #include <limits.h>
1338 UWtype
1339 __fixunsdfSI (DFtype a)
1341 if (a >= - (DFtype) Wtype_MIN)
1342 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1343 return (Wtype) a;
1345 #endif
1347 #ifdef L_fixunssfsi
1348 /* Reenable the normal types, in case limits.h needs them. */
1349 #undef char
1350 #undef short
1351 #undef int
1352 #undef long
1353 #undef unsigned
1354 #undef float
1355 #undef double
1356 #undef MIN
1357 #undef MAX
1358 #include <limits.h>
1360 UWtype
1361 __fixunssfSI (SFtype a)
1363 if (a >= - (SFtype) Wtype_MIN)
1364 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1365 return (Wtype) a;
1367 #endif
1369 /* From here on down, the routines use normal data types. */
1371 #define SItype bogus_type
1372 #define USItype bogus_type
1373 #define DItype bogus_type
1374 #define UDItype bogus_type
1375 #define SFtype bogus_type
1376 #define DFtype bogus_type
1377 #undef Wtype
1378 #undef UWtype
1379 #undef HWtype
1380 #undef UHWtype
1381 #undef DWtype
1382 #undef UDWtype
1384 #undef char
1385 #undef short
1386 #undef int
1387 #undef long
1388 #undef unsigned
1389 #undef float
1390 #undef double
1392 #ifdef L__gcc_bcmp
1394 /* Like bcmp except the sign is meaningful.
1395 Result is negative if S1 is less than S2,
1396 positive if S1 is greater, 0 if S1 and S2 are equal. */
1399 __gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
1401 while (size > 0)
1403 unsigned char c1 = *s1++, c2 = *s2++;
1404 if (c1 != c2)
1405 return c1 - c2;
1406 size--;
1408 return 0;
1411 #endif
1413 /* __eprintf used to be used by GCC's private version of <assert.h>.
1414 We no longer provide that header, but this routine remains in libgcc.a
1415 for binary backward compatibility. Note that it is not included in
1416 the shared version of libgcc. */
1417 #ifdef L_eprintf
1418 #ifndef inhibit_libc
1420 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1421 #include <stdio.h>
1423 void
1424 __eprintf (const char *string, const char *expression,
1425 unsigned int line, const char *filename)
1427 fprintf (stderr, string, expression, line, filename);
1428 fflush (stderr);
1429 abort ();
1432 #endif
1433 #endif
1436 #ifdef L_clear_cache
1437 /* Clear part of an instruction cache. */
1439 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1441 void
1442 __clear_cache (char *beg __attribute__((__unused__)),
1443 char *end __attribute__((__unused__)))
1445 #ifdef CLEAR_INSN_CACHE
1446 CLEAR_INSN_CACHE (beg, end);
1447 #else
1448 #ifdef INSN_CACHE_SIZE
1449 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1450 static int initialized;
1451 int offset;
1452 void *start_addr
1453 void *end_addr;
1454 typedef (*function_ptr) (void);
1456 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1457 /* It's cheaper to clear the whole cache.
1458 Put in a series of jump instructions so that calling the beginning
1459 of the cache will clear the whole thing. */
1461 if (! initialized)
1463 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1464 & -INSN_CACHE_LINE_WIDTH);
1465 int end_ptr = ptr + INSN_CACHE_SIZE;
1467 while (ptr < end_ptr)
1469 *(INSTRUCTION_TYPE *)ptr
1470 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1471 ptr += INSN_CACHE_LINE_WIDTH;
1473 *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1475 initialized = 1;
1478 /* Call the beginning of the sequence. */
1479 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1480 & -INSN_CACHE_LINE_WIDTH))
1481 ());
1483 #else /* Cache is large. */
1485 if (! initialized)
1487 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1488 & -INSN_CACHE_LINE_WIDTH);
1490 while (ptr < (int) array + sizeof array)
1492 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1493 ptr += INSN_CACHE_LINE_WIDTH;
1496 initialized = 1;
1499 /* Find the location in array that occupies the same cache line as BEG. */
1501 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1502 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1503 & -INSN_CACHE_PLANE_SIZE)
1504 + offset);
1506 /* Compute the cache alignment of the place to stop clearing. */
1507 #if 0 /* This is not needed for gcc's purposes. */
1508 /* If the block to clear is bigger than a cache plane,
1509 we clear the entire cache, and OFFSET is already correct. */
1510 if (end < beg + INSN_CACHE_PLANE_SIZE)
1511 #endif
1512 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1513 & -INSN_CACHE_LINE_WIDTH)
1514 & (INSN_CACHE_PLANE_SIZE - 1));
1516 #if INSN_CACHE_DEPTH > 1
1517 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1518 if (end_addr <= start_addr)
1519 end_addr += INSN_CACHE_PLANE_SIZE;
1521 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1523 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1524 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1526 while (addr != stop)
1528 /* Call the return instruction at ADDR. */
1529 ((function_ptr) addr) ();
1531 addr += INSN_CACHE_LINE_WIDTH;
1534 #else /* just one plane */
1537 /* Call the return instruction at START_ADDR. */
1538 ((function_ptr) start_addr) ();
1540 start_addr += INSN_CACHE_LINE_WIDTH;
1542 while ((start_addr % INSN_CACHE_SIZE) != offset);
1543 #endif /* just one plane */
1544 #endif /* Cache is large */
1545 #endif /* Cache exists */
1546 #endif /* CLEAR_INSN_CACHE */
1549 #endif /* L_clear_cache */
1551 #ifdef L_trampoline
1553 /* Jump to a trampoline, loading the static chain address. */
1555 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
1557 long
1558 getpagesize (void)
1560 #ifdef _ALPHA_
1561 return 8192;
1562 #else
1563 return 4096;
1564 #endif
1567 #ifdef __i386__
1568 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
1569 #endif
1572 mprotect (char *addr, int len, int prot)
1574 int np, op;
1576 if (prot == 7)
1577 np = 0x40;
1578 else if (prot == 5)
1579 np = 0x20;
1580 else if (prot == 4)
1581 np = 0x10;
1582 else if (prot == 3)
1583 np = 0x04;
1584 else if (prot == 1)
1585 np = 0x02;
1586 else if (prot == 0)
1587 np = 0x01;
1589 if (VirtualProtect (addr, len, np, &op))
1590 return 0;
1591 else
1592 return -1;
1595 #endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
1597 #ifdef TRANSFER_FROM_TRAMPOLINE
1598 TRANSFER_FROM_TRAMPOLINE
1599 #endif
1601 #ifdef __sysV68__
1603 #include <sys/signal.h>
1604 #include <errno.h>
1606 /* Motorola forgot to put memctl.o in the libp version of libc881.a,
1607 so define it here, because we need it in __clear_insn_cache below */
1608 /* On older versions of this OS, no memctl or MCT_TEXT are defined;
1609 hence we enable this stuff only if MCT_TEXT is #define'd. */
1611 #ifdef MCT_TEXT
1612 asm("\n\
1613 global memctl\n\
1614 memctl:\n\
1615 movq &75,%d0\n\
1616 trap &0\n\
1617 bcc.b noerror\n\
1618 jmp cerror%\n\
1619 noerror:\n\
1620 movq &0,%d0\n\
1621 rts");
1622 #endif
1624 /* Clear instruction cache so we can call trampolines on stack.
1625 This is called from FINALIZE_TRAMPOLINE in mot3300.h. */
1627 void
1628 __clear_insn_cache (void)
1630 #ifdef MCT_TEXT
1631 int save_errno;
1633 /* Preserve errno, because users would be surprised to have
1634 errno changing without explicitly calling any system-call. */
1635 save_errno = errno;
1637 /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache.
1638 No need to use an address derived from _start or %sp, as 0 works also. */
1639 memctl(0, 4096, MCT_TEXT);
1640 errno = save_errno;
1641 #endif
1644 #endif /* __sysV68__ */
1645 #endif /* L_trampoline */
1647 #ifndef __CYGWIN__
1648 #ifdef L__main
1650 #include "gbl-ctors.h"
1651 /* Some systems use __main in a way incompatible with its use in gcc, in these
1652 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
1653 give the same symbol without quotes for an alternative entry point. You
1654 must define both, or neither. */
1655 #ifndef NAME__MAIN
1656 #define NAME__MAIN "__main"
1657 #define SYMBOL__MAIN __main
1658 #endif
1660 #ifdef INIT_SECTION_ASM_OP
1661 #undef HAS_INIT_SECTION
1662 #define HAS_INIT_SECTION
1663 #endif
1665 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
1667 /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
1668 code to run constructors. In that case, we need to handle EH here, too. */
1670 #ifdef EH_FRAME_SECTION_NAME
1671 #include "unwind-dw2-fde.h"
1672 extern unsigned char __EH_FRAME_BEGIN__[];
1673 #endif
1675 /* Run all the global destructors on exit from the program. */
1677 void
1678 __do_global_dtors (void)
1680 #ifdef DO_GLOBAL_DTORS_BODY
1681 DO_GLOBAL_DTORS_BODY;
1682 #else
1683 static func_ptr *p = __DTOR_LIST__ + 1;
1684 while (*p)
1686 p++;
1687 (*(p-1)) ();
1689 #endif
1690 #if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION)
1692 static int completed = 0;
1693 if (! completed)
1695 completed = 1;
1696 __deregister_frame_info (__EH_FRAME_BEGIN__);
1699 #endif
1701 #endif
1703 #ifndef HAS_INIT_SECTION
1704 /* Run all the global constructors on entry to the program. */
1706 void
1707 __do_global_ctors (void)
1709 #ifdef EH_FRAME_SECTION_NAME
1711 static struct object object;
1712 __register_frame_info (__EH_FRAME_BEGIN__, &object);
1714 #endif
1715 DO_GLOBAL_CTORS_BODY;
1716 atexit (__do_global_dtors);
1718 #endif /* no HAS_INIT_SECTION */
1720 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
1721 /* Subroutine called automatically by `main'.
1722 Compiling a global function named `main'
1723 produces an automatic call to this function at the beginning.
1725 For many systems, this routine calls __do_global_ctors.
1726 For systems which support a .init section we use the .init section
1727 to run __do_global_ctors, so we need not do anything here. */
1729 void
1730 SYMBOL__MAIN ()
1732 /* Support recursive calls to `main': run initializers just once. */
1733 static int initialized;
1734 if (! initialized)
1736 initialized = 1;
1737 __do_global_ctors ();
1740 #endif /* no HAS_INIT_SECTION or INVOKE__main */
1742 #endif /* L__main */
1743 #endif /* __CYGWIN__ */
1745 #ifdef L_ctors
1747 #include "gbl-ctors.h"
1749 /* Provide default definitions for the lists of constructors and
1750 destructors, so that we don't get linker errors. These symbols are
1751 intentionally bss symbols, so that gld and/or collect will provide
1752 the right values. */
1754 /* We declare the lists here with two elements each,
1755 so that they are valid empty lists if no other definition is loaded.
1757 If we are using the old "set" extensions to have the gnu linker
1758 collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
1759 must be in the bss/common section.
1761 Long term no port should use those extensions. But many still do. */
1762 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
1763 #if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2)
1764 func_ptr __CTOR_LIST__[2] = {0, 0};
1765 func_ptr __DTOR_LIST__[2] = {0, 0};
1766 #else
1767 func_ptr __CTOR_LIST__[2];
1768 func_ptr __DTOR_LIST__[2];
1769 #endif
1770 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1771 #endif /* L_ctors */
1773 #ifdef L_exit
1775 #include "gbl-ctors.h"
1777 #ifdef NEED_ATEXIT
1779 #ifndef ON_EXIT
1781 # include <errno.h>
1783 static func_ptr *atexit_chain = 0;
1784 static long atexit_chain_length = 0;
1785 static volatile long last_atexit_chain_slot = -1;
1788 atexit (func_ptr func)
1790 if (++last_atexit_chain_slot == atexit_chain_length)
1792 atexit_chain_length += 32;
1793 if (atexit_chain)
1794 atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
1795 * sizeof (func_ptr));
1796 else
1797 atexit_chain = (func_ptr *) malloc (atexit_chain_length
1798 * sizeof (func_ptr));
1799 if (! atexit_chain)
1801 atexit_chain_length = 0;
1802 last_atexit_chain_slot = -1;
1803 errno = ENOMEM;
1804 return (-1);
1807 atexit_chain[last_atexit_chain_slot] = func;
1808 return (0);
1811 extern void _cleanup (void);
1812 extern void _exit (int) __attribute__ ((__noreturn__));
1814 void
1815 exit (int status)
1817 if (atexit_chain)
1819 for ( ; last_atexit_chain_slot-- >= 0; )
1821 (*atexit_chain[last_atexit_chain_slot + 1]) ();
1822 atexit_chain[last_atexit_chain_slot + 1] = 0;
1824 free (atexit_chain);
1825 atexit_chain = 0;
1827 #ifdef EXIT_BODY
1828 EXIT_BODY;
1829 #else
1830 _cleanup ();
1831 #endif
1832 _exit (status);
1835 #else /* ON_EXIT */
1837 /* Simple; we just need a wrapper for ON_EXIT. */
1839 atexit (func_ptr func)
1841 return ON_EXIT (func);
1844 #endif /* ON_EXIT */
1845 #endif /* NEED_ATEXIT */
1847 #endif /* L_exit */