* config/i386/uwin.h: Remove SUBTARGET_PROLOGUE.
[official-gcc.git] / gcc / libgcc2.c
bloba9d8e682a8fc88340460dcfcf2af8d114fd7354c
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, 2003 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 void
1440 __clear_cache (char *beg __attribute__((__unused__)),
1441 char *end __attribute__((__unused__)))
1443 #ifdef CLEAR_INSN_CACHE
1444 CLEAR_INSN_CACHE (beg, end);
1445 #endif /* CLEAR_INSN_CACHE */
1448 #endif /* L_clear_cache */
1450 #ifdef L_trampoline
1452 /* Jump to a trampoline, loading the static chain address. */
1454 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
1456 long
1457 getpagesize (void)
1459 #ifdef _ALPHA_
1460 return 8192;
1461 #else
1462 return 4096;
1463 #endif
1466 #ifdef __i386__
1467 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
1468 #endif
1471 mprotect (char *addr, int len, int prot)
1473 int np, op;
1475 if (prot == 7)
1476 np = 0x40;
1477 else if (prot == 5)
1478 np = 0x20;
1479 else if (prot == 4)
1480 np = 0x10;
1481 else if (prot == 3)
1482 np = 0x04;
1483 else if (prot == 1)
1484 np = 0x02;
1485 else if (prot == 0)
1486 np = 0x01;
1488 if (VirtualProtect (addr, len, np, &op))
1489 return 0;
1490 else
1491 return -1;
1494 #endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
1496 #ifdef TRANSFER_FROM_TRAMPOLINE
1497 TRANSFER_FROM_TRAMPOLINE
1498 #endif
1500 #ifdef __sysV68__
1502 #include <sys/signal.h>
1503 #include <errno.h>
1505 /* Motorola forgot to put memctl.o in the libp version of libc881.a,
1506 so define it here, because we need it in __clear_insn_cache below */
1507 /* On older versions of this OS, no memctl or MCT_TEXT are defined;
1508 hence we enable this stuff only if MCT_TEXT is #define'd. */
1510 #ifdef MCT_TEXT
1511 asm("\n\
1512 global memctl\n\
1513 memctl:\n\
1514 movq &75,%d0\n\
1515 trap &0\n\
1516 bcc.b noerror\n\
1517 jmp cerror%\n\
1518 noerror:\n\
1519 movq &0,%d0\n\
1520 rts");
1521 #endif
1523 /* Clear instruction cache so we can call trampolines on stack.
1524 This is called from FINALIZE_TRAMPOLINE in mot3300.h. */
1526 void
1527 __clear_insn_cache (void)
1529 #ifdef MCT_TEXT
1530 int save_errno;
1532 /* Preserve errno, because users would be surprised to have
1533 errno changing without explicitly calling any system-call. */
1534 save_errno = errno;
1536 /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache.
1537 No need to use an address derived from _start or %sp, as 0 works also. */
1538 memctl(0, 4096, MCT_TEXT);
1539 errno = save_errno;
1540 #endif
1543 #endif /* __sysV68__ */
1544 #endif /* L_trampoline */
1546 #ifndef __CYGWIN__
1547 #ifdef L__main
1549 #include "gbl-ctors.h"
1550 /* Some systems use __main in a way incompatible with its use in gcc, in these
1551 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
1552 give the same symbol without quotes for an alternative entry point. You
1553 must define both, or neither. */
1554 #ifndef NAME__MAIN
1555 #define NAME__MAIN "__main"
1556 #define SYMBOL__MAIN __main
1557 #endif
1559 #ifdef INIT_SECTION_ASM_OP
1560 #undef HAS_INIT_SECTION
1561 #define HAS_INIT_SECTION
1562 #endif
1564 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
1566 /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
1567 code to run constructors. In that case, we need to handle EH here, too. */
1569 #ifdef EH_FRAME_SECTION_NAME
1570 #include "unwind-dw2-fde.h"
1571 extern unsigned char __EH_FRAME_BEGIN__[];
1572 #endif
1574 /* Run all the global destructors on exit from the program. */
1576 void
1577 __do_global_dtors (void)
1579 #ifdef DO_GLOBAL_DTORS_BODY
1580 DO_GLOBAL_DTORS_BODY;
1581 #else
1582 static func_ptr *p = __DTOR_LIST__ + 1;
1583 while (*p)
1585 p++;
1586 (*(p-1)) ();
1588 #endif
1589 #if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION)
1591 static int completed = 0;
1592 if (! completed)
1594 completed = 1;
1595 __deregister_frame_info (__EH_FRAME_BEGIN__);
1598 #endif
1600 #endif
1602 #ifndef HAS_INIT_SECTION
1603 /* Run all the global constructors on entry to the program. */
1605 void
1606 __do_global_ctors (void)
1608 #ifdef EH_FRAME_SECTION_NAME
1610 static struct object object;
1611 __register_frame_info (__EH_FRAME_BEGIN__, &object);
1613 #endif
1614 DO_GLOBAL_CTORS_BODY;
1615 atexit (__do_global_dtors);
1617 #endif /* no HAS_INIT_SECTION */
1619 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
1620 /* Subroutine called automatically by `main'.
1621 Compiling a global function named `main'
1622 produces an automatic call to this function at the beginning.
1624 For many systems, this routine calls __do_global_ctors.
1625 For systems which support a .init section we use the .init section
1626 to run __do_global_ctors, so we need not do anything here. */
1628 void
1629 SYMBOL__MAIN ()
1631 /* Support recursive calls to `main': run initializers just once. */
1632 static int initialized;
1633 if (! initialized)
1635 initialized = 1;
1636 __do_global_ctors ();
1639 #endif /* no HAS_INIT_SECTION or INVOKE__main */
1641 #endif /* L__main */
1642 #endif /* __CYGWIN__ */
1644 #ifdef L_ctors
1646 #include "gbl-ctors.h"
1648 /* Provide default definitions for the lists of constructors and
1649 destructors, so that we don't get linker errors. These symbols are
1650 intentionally bss symbols, so that gld and/or collect will provide
1651 the right values. */
1653 /* We declare the lists here with two elements each,
1654 so that they are valid empty lists if no other definition is loaded.
1656 If we are using the old "set" extensions to have the gnu linker
1657 collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
1658 must be in the bss/common section.
1660 Long term no port should use those extensions. But many still do. */
1661 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
1662 #if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2)
1663 func_ptr __CTOR_LIST__[2] = {0, 0};
1664 func_ptr __DTOR_LIST__[2] = {0, 0};
1665 #else
1666 func_ptr __CTOR_LIST__[2];
1667 func_ptr __DTOR_LIST__[2];
1668 #endif
1669 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1670 #endif /* L_ctors */
1672 #ifdef L_exit
1674 #include "gbl-ctors.h"
1676 #ifdef NEED_ATEXIT
1678 #ifndef ON_EXIT
1680 # include <errno.h>
1682 static func_ptr *atexit_chain = 0;
1683 static long atexit_chain_length = 0;
1684 static volatile long last_atexit_chain_slot = -1;
1687 atexit (func_ptr func)
1689 if (++last_atexit_chain_slot == atexit_chain_length)
1691 atexit_chain_length += 32;
1692 if (atexit_chain)
1693 atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
1694 * sizeof (func_ptr));
1695 else
1696 atexit_chain = (func_ptr *) malloc (atexit_chain_length
1697 * sizeof (func_ptr));
1698 if (! atexit_chain)
1700 atexit_chain_length = 0;
1701 last_atexit_chain_slot = -1;
1702 errno = ENOMEM;
1703 return (-1);
1706 atexit_chain[last_atexit_chain_slot] = func;
1707 return (0);
1710 extern void _cleanup (void);
1711 extern void _exit (int) __attribute__ ((__noreturn__));
1713 void
1714 exit (int status)
1716 if (atexit_chain)
1718 for ( ; last_atexit_chain_slot-- >= 0; )
1720 (*atexit_chain[last_atexit_chain_slot + 1]) ();
1721 atexit_chain[last_atexit_chain_slot + 1] = 0;
1723 free (atexit_chain);
1724 atexit_chain = 0;
1726 #ifdef EXIT_BODY
1727 EXIT_BODY;
1728 #else
1729 _cleanup ();
1730 #endif
1731 _exit (status);
1734 #else /* ON_EXIT */
1736 /* Simple; we just need a wrapper for ON_EXIT. */
1738 atexit (func_ptr func)
1740 return ON_EXIT (func);
1743 #endif /* ON_EXIT */
1744 #endif /* NEED_ATEXIT */
1746 #endif /* L_exit */