Do not report -Wnested-extern errors for __FUNCTION__/__PRETTY_FUNCTION__.
[official-gcc.git] / gcc / libgcc2.c
blobc4f35c83e62f5028b7e2df597b45ac9e2481ee48
1 /* More subroutines needed by GCC output code on some machines. */
2 /* Compile this one with gcc. */
3 /* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
21 /* As a special exception, if you link this library with files
22 compiled with GCC to produce an executable, this does not cause
23 the resulting executable to be covered by the GNU General Public License.
24 This exception does not however invalidate any other reasons why
25 the executable file might be covered by the GNU General Public License. */
27 /* It is incorrect to include config.h here, because this file is being
28 compiled for the target, and hence definitions concerning only the host
29 do not apply. */
31 #include "tconfig.h"
32 #include "machmode.h"
33 #ifndef L_trampoline
34 #include "gstddef.h"
35 #endif
37 /* Don't use `fancy_abort' here even if config.h says to use it. */
38 #ifdef abort
39 #undef abort
40 #endif
42 /* In the first part of this file, we are interfacing to calls generated
43 by the compiler itself. These calls pass values into these routines
44 which have very specific modes (rather than very specific types), and
45 these compiler-generated calls also expect any return values to have
46 very specific modes (rather than very specific types). Thus, we need
47 to avoid using regular C language type names in this part of the file
48 because the sizes for those types can be configured to be anything.
49 Instead we use the following special type names. */
51 typedef unsigned int UQItype __attribute__ ((mode (QI)));
52 typedef int SItype __attribute__ ((mode (SI)));
53 typedef unsigned int USItype __attribute__ ((mode (SI)));
54 typedef int DItype __attribute__ ((mode (DI)));
55 typedef unsigned int UDItype __attribute__ ((mode (DI)));
56 typedef float SFtype __attribute__ ((mode (SF)));
57 typedef float DFtype __attribute__ ((mode (DF)));
58 #if LONG_DOUBLE_TYPE_SIZE == 96
59 typedef float XFtype __attribute__ ((mode (XF)));
60 #endif
61 #if LONG_DOUBLE_TYPE_SIZE == 128
62 typedef float TFtype __attribute__ ((mode (TF)));
63 #endif
65 #if BITS_PER_WORD==16
66 typedef int word_type __attribute__ ((mode (HI)));
67 #endif
68 #if BITS_PER_WORD==32
69 typedef int word_type __attribute__ ((mode (SI)));
70 #endif
71 #if BITS_PER_WORD==64
72 typedef int word_type __attribute__ ((mode (DI)));
73 #endif
75 /* Make sure that we don't accidentally use any normal C language built-in
76 type names in the first part of this file. Instead we want to use *only*
77 the type names defined above. The following macro definitions insure
78 that if we *do* accidentally use some normal C language built-in type name,
79 we will get a syntax error. */
81 #define char bogus_type
82 #define short bogus_type
83 #define int bogus_type
84 #define long bogus_type
85 #define unsigned bogus_type
86 #define float bogus_type
87 #define double bogus_type
89 #define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
91 /* DIstructs are pairs of SItype values in the order determined by
92 WORDS_BIG_ENDIAN. */
94 #if WORDS_BIG_ENDIAN
95 struct DIstruct {SItype high, low;};
96 #else
97 struct DIstruct {SItype low, high;};
98 #endif
100 /* We need this union to unpack/pack DImode values, since we don't have
101 any arithmetic yet. Incoming DImode parameters are stored into the
102 `ll' field, and the unpacked result is read from the struct `s'. */
104 typedef union
106 struct DIstruct s;
107 DItype ll;
108 } DIunion;
110 #if defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_w_sdiv)
112 #include "longlong.h"
114 #endif /* udiv or mul */
116 extern DItype __fixunssfdi (SFtype a);
117 extern DItype __fixunsdfdi (DFtype a);
119 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
120 #if defined (L_divdi3) || defined (L_moddi3)
121 static inline
122 #endif
123 DItype
124 __negdi2 (u)
125 DItype u;
127 DIunion w;
128 DIunion uu;
130 uu.ll = u;
132 w.s.low = -uu.s.low;
133 w.s.high = -uu.s.high - ((USItype) w.s.low > 0);
135 return w.ll;
137 #endif
139 #ifdef L_lshldi3
140 DItype
141 __lshldi3 (u, b)
142 DItype u;
143 SItype b;
145 DIunion w;
146 SItype bm;
147 DIunion uu;
149 if (b == 0)
150 return u;
152 uu.ll = u;
154 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
155 if (bm <= 0)
157 w.s.low = 0;
158 w.s.high = (USItype)uu.s.low << -bm;
160 else
162 USItype carries = (USItype)uu.s.low >> bm;
163 w.s.low = (USItype)uu.s.low << b;
164 w.s.high = ((USItype)uu.s.high << b) | carries;
167 return w.ll;
169 #endif
171 #ifdef L_lshrdi3
172 DItype
173 __lshrdi3 (u, b)
174 DItype u;
175 SItype b;
177 DIunion w;
178 SItype bm;
179 DIunion uu;
181 if (b == 0)
182 return u;
184 uu.ll = u;
186 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
187 if (bm <= 0)
189 w.s.high = 0;
190 w.s.low = (USItype)uu.s.high >> -bm;
192 else
194 USItype carries = (USItype)uu.s.high << bm;
195 w.s.high = (USItype)uu.s.high >> b;
196 w.s.low = ((USItype)uu.s.low >> b) | carries;
199 return w.ll;
201 #endif
203 #ifdef L_ashldi3
204 DItype
205 __ashldi3 (u, b)
206 DItype u;
207 SItype b;
209 DIunion w;
210 SItype bm;
211 DIunion uu;
213 if (b == 0)
214 return u;
216 uu.ll = u;
218 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
219 if (bm <= 0)
221 w.s.low = 0;
222 w.s.high = (USItype)uu.s.low << -bm;
224 else
226 USItype carries = (USItype)uu.s.low >> bm;
227 w.s.low = (USItype)uu.s.low << b;
228 w.s.high = ((USItype)uu.s.high << b) | carries;
231 return w.ll;
233 #endif
235 #ifdef L_ashrdi3
236 DItype
237 __ashrdi3 (u, b)
238 DItype u;
239 SItype b;
241 DIunion w;
242 SItype bm;
243 DIunion uu;
245 if (b == 0)
246 return u;
248 uu.ll = u;
250 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
251 if (bm <= 0)
253 /* w.s.high = 1..1 or 0..0 */
254 w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
255 w.s.low = uu.s.high >> -bm;
257 else
259 USItype carries = (USItype)uu.s.high << bm;
260 w.s.high = uu.s.high >> b;
261 w.s.low = ((USItype)uu.s.low >> b) | carries;
264 return w.ll;
266 #endif
268 #ifdef L_ffsdi2
269 DItype
270 __ffsdi2 (u)
271 DItype u;
273 DIunion uu, w;
274 uu.ll = u;
275 w.s.high = 0;
276 w.s.low = ffs (uu.s.low);
277 if (w.s.low != 0)
278 return w.ll;
279 w.s.low = ffs (uu.s.high);
280 if (w.s.low != 0)
282 w.s.low += BITS_PER_UNIT * sizeof (SItype);
283 return w.ll;
285 return w.ll;
287 #endif
289 #ifdef L_muldi3
290 DItype
291 __muldi3 (u, v)
292 DItype u, v;
294 DIunion w;
295 DIunion uu, vv;
297 uu.ll = u,
298 vv.ll = v;
300 w.ll = __umulsidi3 (uu.s.low, vv.s.low);
301 w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
302 + (USItype) uu.s.high * (USItype) vv.s.low);
304 return w.ll;
306 #endif
308 #ifdef L_udiv_w_sdiv
309 USItype
310 __udiv_w_sdiv (rp, a1, a0, d)
311 USItype *rp, a1, a0, d;
313 USItype q, r;
314 USItype c0, c1, b1;
316 if ((SItype) d >= 0)
318 if (a1 < d - a1 - (a0 >> (SI_TYPE_SIZE - 1)))
320 /* dividend, divisor, and quotient are nonnegative */
321 sdiv_qrnnd (q, r, a1, a0, d);
323 else
325 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
326 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (SI_TYPE_SIZE - 1));
327 /* Divide (c1*2^32 + c0) by d */
328 sdiv_qrnnd (q, r, c1, c0, d);
329 /* Add 2^31 to quotient */
330 q += (USItype) 1 << (SI_TYPE_SIZE - 1);
333 else
335 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
336 c1 = a1 >> 1; /* A/2 */
337 c0 = (a1 << (SI_TYPE_SIZE - 1)) + (a0 >> 1);
339 if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
341 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
343 r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
344 if ((d & 1) != 0)
346 if (r >= q)
347 r = r - q;
348 else if (q - r <= d)
350 r = r - q + d;
351 q--;
353 else
355 r = r - q + 2*d;
356 q -= 2;
360 else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
362 c1 = (b1 - 1) - c1;
363 c0 = ~c0; /* logical NOT */
365 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
367 q = ~q; /* (A/2)/b1 */
368 r = (b1 - 1) - r;
370 r = 2*r + (a0 & 1); /* A/(2*b1) */
372 if ((d & 1) != 0)
374 if (r >= q)
375 r = r - q;
376 else if (q - r <= d)
378 r = r - q + d;
379 q--;
381 else
383 r = r - q + 2*d;
384 q -= 2;
388 else /* Implies c1 = b1 */
389 { /* Hence a1 = d - 1 = 2*b1 - 1 */
390 if (a0 >= -d)
392 q = -1;
393 r = a0 + d;
395 else
397 q = -2;
398 r = a0 + 2*d;
403 *rp = r;
404 return q;
406 #endif
408 #ifdef L_udivmoddi4
409 static const UQItype __clz_tab[] =
411 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,
412 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,
413 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,
414 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,
415 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,
416 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,
417 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,
418 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,
421 UDItype
422 __udivmoddi4 (n, d, rp)
423 UDItype n, d;
424 UDItype *rp;
426 DIunion ww;
427 DIunion nn, dd;
428 DIunion rr;
429 USItype d0, d1, n0, n1, n2;
430 USItype q0, q1;
431 USItype b, bm;
433 nn.ll = n;
434 dd.ll = d;
436 d0 = dd.s.low;
437 d1 = dd.s.high;
438 n0 = nn.s.low;
439 n1 = nn.s.high;
441 #if !UDIV_NEEDS_NORMALIZATION
442 if (d1 == 0)
444 if (d0 > n1)
446 /* 0q = nn / 0D */
448 udiv_qrnnd (q0, n0, n1, n0, d0);
449 q1 = 0;
451 /* Remainder in n0. */
453 else
455 /* qq = NN / 0d */
457 if (d0 == 0)
458 d0 = 1 / d0; /* Divide intentionally by zero. */
460 udiv_qrnnd (q1, n1, 0, n1, d0);
461 udiv_qrnnd (q0, n0, n1, n0, d0);
463 /* Remainder in n0. */
466 if (rp != 0)
468 rr.s.low = n0;
469 rr.s.high = 0;
470 *rp = rr.ll;
474 #else /* UDIV_NEEDS_NORMALIZATION */
476 if (d1 == 0)
478 if (d0 > n1)
480 /* 0q = nn / 0D */
482 count_leading_zeros (bm, d0);
484 if (bm != 0)
486 /* Normalize, i.e. make the most significant bit of the
487 denominator set. */
489 d0 = d0 << bm;
490 n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
491 n0 = n0 << bm;
494 udiv_qrnnd (q0, n0, n1, n0, d0);
495 q1 = 0;
497 /* Remainder in n0 >> bm. */
499 else
501 /* qq = NN / 0d */
503 if (d0 == 0)
504 d0 = 1 / d0; /* Divide intentionally by zero. */
506 count_leading_zeros (bm, d0);
508 if (bm == 0)
510 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
511 conclude (the most significant bit of n1 is set) /\ (the
512 leading quotient digit q1 = 1).
514 This special case is necessary, not an optimization.
515 (Shifts counts of SI_TYPE_SIZE are undefined.) */
517 n1 -= d0;
518 q1 = 1;
520 else
522 /* Normalize. */
524 b = SI_TYPE_SIZE - bm;
526 d0 = d0 << bm;
527 n2 = n1 >> b;
528 n1 = (n1 << bm) | (n0 >> b);
529 n0 = n0 << bm;
531 udiv_qrnnd (q1, n1, n2, n1, d0);
534 /* n1 != d0... */
536 udiv_qrnnd (q0, n0, n1, n0, d0);
538 /* Remainder in n0 >> bm. */
541 if (rp != 0)
543 rr.s.low = n0 >> bm;
544 rr.s.high = 0;
545 *rp = rr.ll;
548 #endif /* UDIV_NEEDS_NORMALIZATION */
550 else
552 if (d1 > n1)
554 /* 00 = nn / DD */
556 q0 = 0;
557 q1 = 0;
559 /* Remainder in n1n0. */
560 if (rp != 0)
562 rr.s.low = n0;
563 rr.s.high = n1;
564 *rp = rr.ll;
567 else
569 /* 0q = NN / dd */
571 count_leading_zeros (bm, d1);
572 if (bm == 0)
574 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
575 conclude (the most significant bit of n1 is set) /\ (the
576 quotient digit q0 = 0 or 1).
578 This special case is necessary, not an optimization. */
580 /* The condition on the next line takes advantage of that
581 n1 >= d1 (true due to program flow). */
582 if (n1 > d1 || n0 >= d0)
584 q0 = 1;
585 sub_ddmmss (n1, n0, n1, n0, d1, d0);
587 else
588 q0 = 0;
590 q1 = 0;
592 if (rp != 0)
594 rr.s.low = n0;
595 rr.s.high = n1;
596 *rp = rr.ll;
599 else
601 USItype m1, m0;
602 /* Normalize. */
604 b = SI_TYPE_SIZE - bm;
606 d1 = (d1 << bm) | (d0 >> b);
607 d0 = d0 << bm;
608 n2 = n1 >> b;
609 n1 = (n1 << bm) | (n0 >> b);
610 n0 = n0 << bm;
612 udiv_qrnnd (q0, n1, n2, n1, d1);
613 umul_ppmm (m1, m0, q0, d0);
615 if (m1 > n1 || (m1 == n1 && m0 > n0))
617 q0--;
618 sub_ddmmss (m1, m0, m1, m0, d1, d0);
621 q1 = 0;
623 /* Remainder in (n1n0 - m1m0) >> bm. */
624 if (rp != 0)
626 sub_ddmmss (n1, n0, n1, n0, m1, m0);
627 rr.s.low = (n1 << b) | (n0 >> bm);
628 rr.s.high = n1 >> bm;
629 *rp = rr.ll;
635 ww.s.low = q0;
636 ww.s.high = q1;
637 return ww.ll;
639 #endif
641 #ifdef L_divdi3
642 UDItype __udivmoddi4 ();
643 DItype
644 __divdi3 (u, v)
645 DItype u, v;
647 SItype c = 0;
648 DIunion uu, vv;
649 DItype w;
651 uu.ll = u;
652 vv.ll = v;
654 if (uu.s.high < 0)
655 c = ~c,
656 uu.ll = __negdi2 (uu.ll);
657 if (vv.s.high < 0)
658 c = ~c,
659 vv.ll = __negdi2 (vv.ll);
661 w = __udivmoddi4 (uu.ll, vv.ll, (UDItype *) 0);
662 if (c)
663 w = __negdi2 (w);
665 return w;
667 #endif
669 #ifdef L_moddi3
670 UDItype __udivmoddi4 ();
671 DItype
672 __moddi3 (u, v)
673 DItype u, v;
675 SItype c = 0;
676 DIunion uu, vv;
677 DItype w;
679 uu.ll = u;
680 vv.ll = v;
682 if (uu.s.high < 0)
683 c = ~c,
684 uu.ll = __negdi2 (uu.ll);
685 if (vv.s.high < 0)
686 vv.ll = __negdi2 (vv.ll);
688 (void) __udivmoddi4 (uu.ll, vv.ll, &w);
689 if (c)
690 w = __negdi2 (w);
692 return w;
694 #endif
696 #ifdef L_umoddi3
697 UDItype __udivmoddi4 ();
698 UDItype
699 __umoddi3 (u, v)
700 UDItype u, v;
702 DItype w;
704 (void) __udivmoddi4 (u, v, &w);
706 return w;
708 #endif
710 #ifdef L_udivdi3
711 UDItype __udivmoddi4 ();
712 UDItype
713 __udivdi3 (n, d)
714 UDItype n, d;
716 return __udivmoddi4 (n, d, (UDItype *) 0);
718 #endif
720 #ifdef L_cmpdi2
721 word_type
722 __cmpdi2 (a, b)
723 DItype a, b;
725 DIunion au, bu;
727 au.ll = a, bu.ll = b;
729 if (au.s.high < bu.s.high)
730 return 0;
731 else if (au.s.high > bu.s.high)
732 return 2;
733 if ((USItype) au.s.low < (USItype) bu.s.low)
734 return 0;
735 else if ((USItype) au.s.low > (USItype) bu.s.low)
736 return 2;
737 return 1;
739 #endif
741 #ifdef L_ucmpdi2
742 word_type
743 __ucmpdi2 (a, b)
744 DItype a, b;
746 DIunion au, bu;
748 au.ll = a, bu.ll = b;
750 if ((USItype) au.s.high < (USItype) bu.s.high)
751 return 0;
752 else if ((USItype) au.s.high > (USItype) bu.s.high)
753 return 2;
754 if ((USItype) au.s.low < (USItype) bu.s.low)
755 return 0;
756 else if ((USItype) au.s.low > (USItype) bu.s.low)
757 return 2;
758 return 1;
760 #endif
762 #if defined(L_fixunstfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
763 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
764 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
766 DItype
767 __fixunstfdi (a)
768 TFtype a;
770 TFtype b;
771 UDItype v;
773 if (a < 0)
774 return 0;
776 /* Compute high word of result, as a flonum. */
777 b = (a / HIGH_WORD_COEFF);
778 /* Convert that to fixed (but not to DItype!),
779 and shift it into the high word. */
780 v = (USItype) b;
781 v <<= WORD_SIZE;
782 /* Remove high part from the TFtype, leaving the low part as flonum. */
783 a -= (TFtype)v;
784 /* Convert that to fixed (but not to DItype!) and add it in.
785 Sometimes A comes out negative. This is significant, since
786 A has more bits than a long int does. */
787 if (a < 0)
788 v -= (USItype) (- a);
789 else
790 v += (USItype) a;
791 return v;
793 #endif
795 #if defined(L_fixtfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
796 DItype
797 __fixtfdi (a)
798 TFtype a;
800 if (a < 0)
801 return - __fixunstfdi (-a);
802 return __fixunstfdi (a);
804 #endif
806 #if defined(L_fixunsxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
807 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
808 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
810 DItype
811 __fixunsxfdi (a)
812 XFtype a;
814 XFtype b;
815 UDItype v;
817 if (a < 0)
818 return 0;
820 /* Compute high word of result, as a flonum. */
821 b = (a / HIGH_WORD_COEFF);
822 /* Convert that to fixed (but not to DItype!),
823 and shift it into the high word. */
824 v = (USItype) b;
825 v <<= WORD_SIZE;
826 /* Remove high part from the XFtype, leaving the low part as flonum. */
827 a -= (XFtype)v;
828 /* Convert that to fixed (but not to DItype!) and add it in.
829 Sometimes A comes out negative. This is significant, since
830 A has more bits than a long int does. */
831 if (a < 0)
832 v -= (USItype) (- a);
833 else
834 v += (USItype) a;
835 return v;
837 #endif
839 #if defined(L_fixxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
840 DItype
841 __fixxfdi (a)
842 XFtype a;
844 if (a < 0)
845 return - __fixunsxfdi (-a);
846 return __fixunsxfdi (a);
848 #endif
850 #ifdef L_fixunsdfdi
851 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
852 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
854 DItype
855 __fixunsdfdi (a)
856 DFtype a;
858 DFtype b;
859 UDItype v;
861 if (a < 0)
862 return 0;
864 /* Compute high word of result, as a flonum. */
865 b = (a / HIGH_WORD_COEFF);
866 /* Convert that to fixed (but not to DItype!),
867 and shift it into the high word. */
868 v = (USItype) b;
869 v <<= WORD_SIZE;
870 /* Remove high part from the DFtype, leaving the low part as flonum. */
871 a -= (DFtype)v;
872 /* Convert that to fixed (but not to DItype!) and add it in.
873 Sometimes A comes out negative. This is significant, since
874 A has more bits than a long int does. */
875 if (a < 0)
876 v -= (USItype) (- a);
877 else
878 v += (USItype) a;
879 return v;
881 #endif
883 #ifdef L_fixdfdi
884 DItype
885 __fixdfdi (a)
886 DFtype a;
888 if (a < 0)
889 return - __fixunsdfdi (-a);
890 return __fixunsdfdi (a);
892 #endif
894 #ifdef L_fixunssfdi
895 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
896 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
898 DItype
899 __fixunssfdi (SFtype original_a)
901 /* Convert the SFtype to a DFtype, because that is surely not going
902 to lose any bits. Some day someone else can write a faster version
903 that avoids converting to DFtype, and verify it really works right. */
904 DFtype a = original_a;
905 DFtype b;
906 UDItype v;
908 if (a < 0)
909 return 0;
911 /* Compute high word of result, as a flonum. */
912 b = (a / HIGH_WORD_COEFF);
913 /* Convert that to fixed (but not to DItype!),
914 and shift it into the high word. */
915 v = (USItype) b;
916 v <<= WORD_SIZE;
917 /* Remove high part from the DFtype, leaving the low part as flonum. */
918 a -= (DFtype)v;
919 /* Convert that to fixed (but not to DItype!) and add it in.
920 Sometimes A comes out negative. This is significant, since
921 A has more bits than a long int does. */
922 if (a < 0)
923 v -= (USItype) (- a);
924 else
925 v += (USItype) a;
926 return v;
928 #endif
930 #ifdef L_fixsfdi
931 DItype
932 __fixsfdi (SFtype a)
934 if (a < 0)
935 return - __fixunssfdi (-a);
936 return __fixunssfdi (a);
938 #endif
940 #if defined(L_floatdixf) && (LONG_DOUBLE_TYPE_SIZE == 96)
941 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
942 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
943 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
945 XFtype
946 __floatdixf (u)
947 DItype u;
949 XFtype d;
950 SItype negate = 0;
952 if (u < 0)
953 u = -u, negate = 1;
955 d = (USItype) (u >> WORD_SIZE);
956 d *= HIGH_HALFWORD_COEFF;
957 d *= HIGH_HALFWORD_COEFF;
958 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
960 return (negate ? -d : d);
962 #endif
964 #if defined(L_floatditf) && (LONG_DOUBLE_TYPE_SIZE == 128)
965 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
966 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
967 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
969 TFtype
970 __floatditf (u)
971 DItype u;
973 TFtype d;
974 SItype negate = 0;
976 if (u < 0)
977 u = -u, negate = 1;
979 d = (USItype) (u >> WORD_SIZE);
980 d *= HIGH_HALFWORD_COEFF;
981 d *= HIGH_HALFWORD_COEFF;
982 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
984 return (negate ? -d : d);
986 #endif
988 #ifdef L_floatdidf
989 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
990 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
991 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
993 DFtype
994 __floatdidf (u)
995 DItype u;
997 DFtype d;
998 SItype negate = 0;
1000 if (u < 0)
1001 u = -u, negate = 1;
1003 d = (USItype) (u >> WORD_SIZE);
1004 d *= HIGH_HALFWORD_COEFF;
1005 d *= HIGH_HALFWORD_COEFF;
1006 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
1008 return (negate ? -d : d);
1010 #endif
1012 #ifdef L_floatdisf
1013 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
1014 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
1015 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
1017 SFtype
1018 __floatdisf (u)
1019 DItype u;
1021 /* Do the calculation in DFmode
1022 so that we don't lose any of the precision of the high word
1023 while multiplying it. */
1024 DFtype f;
1025 SItype negate = 0;
1027 if (u < 0)
1028 u = -u, negate = 1;
1030 f = (USItype) (u >> WORD_SIZE);
1031 f *= HIGH_HALFWORD_COEFF;
1032 f *= HIGH_HALFWORD_COEFF;
1033 f += (USItype) (u & (HIGH_WORD_COEFF - 1));
1035 return (SFtype) (negate ? -f : f);
1037 #endif
1039 #if defined(L_fixunsxfsi) && LONG_DOUBLE_TYPE_SIZE == 96
1040 #include "glimits.h"
1042 USItype
1043 __fixunsxfsi (a)
1044 XFtype a;
1046 if (a >= - (DFtype) LONG_MIN)
1047 return (SItype) (a + LONG_MIN) - LONG_MIN;
1048 return (SItype) a;
1050 #endif
1052 #ifdef L_fixunsdfsi
1053 #include "glimits.h"
1055 USItype
1056 __fixunsdfsi (a)
1057 DFtype a;
1059 if (a >= - (DFtype) LONG_MIN)
1060 return (SItype) (a + LONG_MIN) - LONG_MIN;
1061 return (SItype) a;
1063 #endif
1065 #ifdef L_fixunssfsi
1066 #include "glimits.h"
1068 USItype
1069 __fixunssfsi (SFtype a)
1071 if (a >= - (SFtype) LONG_MIN)
1072 return (SItype) (a + LONG_MIN) - LONG_MIN;
1073 return (SItype) a;
1075 #endif
1077 /* From here on down, the routines use normal data types. */
1079 #define SItype bogus_type
1080 #define USItype bogus_type
1081 #define DItype bogus_type
1082 #define UDItype bogus_type
1083 #define SFtype bogus_type
1084 #define DFtype bogus_type
1086 #undef char
1087 #undef short
1088 #undef int
1089 #undef long
1090 #undef unsigned
1091 #undef float
1092 #undef double
1094 #ifdef L__gcc_bcmp
1096 /* Like bcmp except the sign is meaningful.
1097 Reult is negative if S1 is less than S2,
1098 positive if S1 is greater, 0 if S1 and S2 are equal. */
1101 __gcc_bcmp (s1, s2, size)
1102 unsigned char *s1, *s2;
1103 size_t size;
1105 while (size > 0)
1107 unsigned char c1 = *s1++, c2 = *s2++;
1108 if (c1 != c2)
1109 return c1 - c2;
1110 size--;
1112 return 0;
1115 #endif
1116 \f\f
1117 #ifdef L_varargs
1118 #ifdef __i860__
1119 #if defined(__svr4__) || defined(__alliant__)
1120 asm (" .text");
1121 asm (" .align 4");
1123 /* The Alliant needs the added underscore. */
1124 asm (".globl __builtin_saveregs");
1125 asm ("__builtin_saveregs:");
1126 asm (".globl ___builtin_saveregs");
1127 asm ("___builtin_saveregs:");
1129 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
1130 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
1131 area and also for a new va_list
1132 structure */
1133 /* Save all argument registers in the arg reg save area. The
1134 arg reg save area must have the following layout (according
1135 to the svr4 ABI):
1137 struct {
1138 union {
1139 float freg[8];
1140 double dreg[4];
1141 } float_regs;
1142 long ireg[12];
1146 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
1147 asm (" fst.q %f12,16(%sp)");
1149 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
1150 asm (" st.l %r17,36(%sp)");
1151 asm (" st.l %r18,40(%sp)");
1152 asm (" st.l %r19,44(%sp)");
1153 asm (" st.l %r20,48(%sp)");
1154 asm (" st.l %r21,52(%sp)");
1155 asm (" st.l %r22,56(%sp)");
1156 asm (" st.l %r23,60(%sp)");
1157 asm (" st.l %r24,64(%sp)");
1158 asm (" st.l %r25,68(%sp)");
1159 asm (" st.l %r26,72(%sp)");
1160 asm (" st.l %r27,76(%sp)");
1162 asm (" adds 80,%sp,%r16"); /* compute the address of the new
1163 va_list structure. Put in into
1164 r16 so that it will be returned
1165 to the caller. */
1167 /* Initialize all fields of the new va_list structure. This
1168 structure looks like:
1170 typedef struct {
1171 unsigned long ireg_used;
1172 unsigned long freg_used;
1173 long *reg_base;
1174 long *mem_ptr;
1175 } va_list;
1178 asm (" st.l %r0, 0(%r16)"); /* nfixed */
1179 asm (" st.l %r0, 4(%r16)"); /* nfloating */
1180 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
1181 asm (" bri %r1"); /* delayed return */
1182 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
1184 #else /* not __svr4__ */
1185 asm (" .text");
1186 asm (" .align 4");
1188 asm (".globl ___builtin_saveregs");
1189 asm ("___builtin_saveregs:");
1190 asm (" mov sp,r30");
1191 asm (" andnot 0x0f,sp,sp");
1192 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
1194 /* Fill in the __va_struct. */
1195 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
1196 asm (" st.l r17, 4(sp)"); /* int fixed[12] */
1197 asm (" st.l r18, 8(sp)");
1198 asm (" st.l r19,12(sp)");
1199 asm (" st.l r20,16(sp)");
1200 asm (" st.l r21,20(sp)");
1201 asm (" st.l r22,24(sp)");
1202 asm (" st.l r23,28(sp)");
1203 asm (" st.l r24,32(sp)");
1204 asm (" st.l r25,36(sp)");
1205 asm (" st.l r26,40(sp)");
1206 asm (" st.l r27,44(sp)");
1208 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
1209 asm (" fst.q f12,64(sp)"); /* int floating[8] */
1211 /* Fill in the __va_ctl. */
1212 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
1213 asm (" st.l r28,84(sp)"); /* pointer to more args */
1214 asm (" st.l r0, 88(sp)"); /* nfixed */
1215 asm (" st.l r0, 92(sp)"); /* nfloating */
1217 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
1218 asm (" bri r1");
1219 asm (" mov r30,sp");
1220 /* recover stack and pass address to start
1221 of data. */
1222 #endif /* not __svr4__ */
1223 #else /* not __i860__ */
1224 #ifdef __sparc__
1225 asm (".global __builtin_saveregs");
1226 asm ("__builtin_saveregs:");
1227 asm (".global ___builtin_saveregs");
1228 asm ("___builtin_saveregs:");
1229 #ifdef NEED_PROC_COMMAND
1230 asm (".proc 020");
1231 #endif
1232 asm ("st %i0,[%fp+68]");
1233 asm ("st %i1,[%fp+72]");
1234 asm ("st %i2,[%fp+76]");
1235 asm ("st %i3,[%fp+80]");
1236 asm ("st %i4,[%fp+84]");
1237 asm ("retl");
1238 asm ("st %i5,[%fp+88]");
1239 #ifdef NEED_TYPE_COMMAND
1240 asm (".type __builtin_saveregs,#function");
1241 asm (".size __builtin_saveregs,.-__builtin_saveregs");
1242 #endif
1243 #else /* not __sparc__ */
1244 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1246 asm (" .text");
1247 asm (" .ent __builtin_saveregs");
1248 asm (" .globl __builtin_saveregs");
1249 asm ("__builtin_saveregs:");
1250 asm (" sw $4,0($30)");
1251 asm (" sw $5,4($30)");
1252 asm (" sw $6,8($30)");
1253 asm (" sw $7,12($30)");
1254 asm (" j $31");
1255 asm (" .end __builtin_saveregs");
1256 #else /* not __mips__, etc. */
1257 __builtin_saveregs ()
1259 abort ();
1261 #endif /* not __mips__ */
1262 #endif /* not __sparc__ */
1263 #endif /* not __i860__ */
1264 #endif
1266 #ifdef L_eprintf
1267 #ifndef inhibit_libc
1269 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1270 #include <stdio.h>
1271 /* This is used by the `assert' macro. */
1272 void
1273 __eprintf (string, expression, line, filename)
1274 const char *string;
1275 const char *expression;
1276 int line;
1277 const char *filename;
1279 fprintf (stderr, string, expression, line, filename);
1280 fflush (stderr);
1281 abort ();
1284 #endif
1285 #endif
1287 #ifdef L_bb
1288 /* Avoid warning from ranlib about empty object file. */
1289 void
1290 __bb_avoid_warning ()
1293 #if defined (__sun__) && defined (__mc68000__)
1294 struct bb
1296 int initialized;
1297 char *filename;
1298 int *counts;
1299 int ncounts;
1300 int zero_word;
1301 int *addresses;
1304 extern int ___tcov_init;
1306 __bb_init_func (blocks)
1307 struct bb *blocks;
1309 if (! ___tcov_init)
1310 ___tcov_init_func ();
1312 ___bb_link (blocks->filename, blocks->counts, blocks->ncounts);
1315 #endif
1316 #endif
1318 /* frills for C++ */
1320 #ifdef L_op_new
1321 typedef void (*vfp)(void);
1323 extern vfp __new_handler;
1325 /* void * operator new (size_t sz) */
1326 void *
1327 __builtin_new (size_t sz)
1329 void *p;
1331 /* malloc (0) is unpredictable; avoid it. */
1332 if (sz == 0)
1333 sz = 1;
1334 p = (void *) malloc (sz);
1335 if (p == 0)
1336 (*__new_handler) ();
1337 return p;
1339 #endif /* L_op_new */
1341 #ifdef L_new_handler
1343 #ifndef inhibit_libc
1344 /* This gets us __GNU_LIBRARY__. */
1345 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1346 #include <stdio.h>
1348 #ifdef __GNU_LIBRARY__
1349 /* Avoid forcing the library's meaning of `write' on the user program
1350 by using the "internal" name (for use within the library) */
1351 #define write(fd, buf, n) __write((fd), (buf), (n))
1352 #endif
1353 #endif /* inhibit_libc */
1355 typedef void (*vfp)(void);
1357 extern void *__builtin_new (size_t);
1358 static void default_new_handler (void);
1360 vfp __new_handler = default_new_handler;
1363 __set_new_handler (handler)
1364 vfp handler;
1366 vfp prev_handler;
1368 prev_handler = __new_handler;
1369 if (handler == 0) handler = default_new_handler;
1370 __new_handler = handler;
1371 return prev_handler;
1375 set_new_handler (handler)
1376 vfp handler;
1378 return __set_new_handler (handler);
1381 #define MESSAGE "Virtual memory exceeded in `new'\n"
1383 static void
1384 default_new_handler ()
1386 /* don't use fprintf (stderr, ...) because it may need to call malloc. */
1387 /* This should really print the name of the program, but that is hard to
1388 do. We need a standard, clean way to get at the name. */
1389 write (2, MESSAGE, sizeof (MESSAGE));
1390 /* don't call exit () because that may call global destructors which
1391 may cause a loop. */
1392 _exit (-1);
1394 #endif
1396 #ifdef L_op_delete
1397 /* void operator delete (void *ptr) */
1398 void
1399 __builtin_delete (void *ptr)
1401 if (ptr)
1402 free (ptr);
1404 #endif
1406 #ifdef L_shtab
1407 unsigned int __shtab[] = {
1408 0x00000001, 0x00000002, 0x00000004, 0x00000008,
1409 0x00000010, 0x00000020, 0x00000040, 0x00000080,
1410 0x00000100, 0x00000200, 0x00000400, 0x00000800,
1411 0x00001000, 0x00002000, 0x00004000, 0x00008000,
1412 0x00010000, 0x00020000, 0x00040000, 0x00080000,
1413 0x00100000, 0x00200000, 0x00400000, 0x00800000,
1414 0x01000000, 0x02000000, 0x04000000, 0x08000000,
1415 0x10000000, 0x20000000, 0x40000000, 0x80000000
1417 #endif
1419 #ifdef L_clear_cache
1420 /* Clear part of an instruction cache. */
1422 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1424 void
1425 __clear_cache (beg, end)
1426 char *beg, *end;
1428 #ifdef INSN_CACHE_SIZE
1429 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1430 static int initialized = 0;
1431 int offset;
1432 void *start_addr
1433 void *end_addr;
1434 typedef (*function_ptr) ();
1436 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1437 /* It's cheaper to clear the whole cache.
1438 Put in a series of jump instructions so that calling the beginning
1439 of the cache will clear the whole thing. */
1441 if (! initialized)
1443 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1444 & -INSN_CACHE_LINE_WIDTH);
1445 int end_ptr = ptr + INSN_CACHE_SIZE;
1447 while (ptr < end_ptr)
1449 *(INSTRUCTION_TYPE *)ptr
1450 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1451 ptr += INSN_CACHE_LINE_WIDTH;
1453 *(INSTRUCTION_TYPE *)(ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1455 initialized = 1;
1458 /* Call the beginning of the sequence. */
1459 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1460 & -INSN_CACHE_LINE_WIDTH))
1461 ());
1463 #else /* Cache is large. */
1465 if (! initialized)
1467 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1468 & -INSN_CACHE_LINE_WIDTH);
1470 while (ptr < (int) array + sizeof array)
1472 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1473 ptr += INSN_CACHE_LINE_WIDTH;
1476 initialized = 1;
1479 /* Find the location in array that occupies the same cache line as BEG. */
1481 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1482 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1483 & -INSN_CACHE_PLANE_SIZE)
1484 + offset);
1486 /* Compute the cache alignment of the place to stop clearing. */
1487 #if 0 /* This is not needed for gcc's purposes. */
1488 /* If the block to clear is bigger than a cache plane,
1489 we clear the entire cache, and OFFSET is already correct. */
1490 if (end < beg + INSN_CACHE_PLANE_SIZE)
1491 #endif
1492 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1493 & -INSN_CACHE_LINE_WIDTH)
1494 & (INSN_CACHE_PLANE_SIZE - 1));
1496 #if INSN_CACHE_DEPTH > 1
1497 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1498 if (end_addr <= start_addr)
1499 end_addr += INSN_CACHE_PLANE_SIZE;
1501 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1503 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1504 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1506 while (addr != stop)
1508 /* Call the return instruction at ADDR. */
1509 ((function_ptr) addr) ();
1511 addr += INSN_CACHE_LINE_WIDTH;
1514 #else /* just one plane */
1517 /* Call the return instruction at START_ADDR. */
1518 ((function_ptr) start_addr) ();
1520 start_addr += INSN_CACHE_LINE_WIDTH;
1522 while ((start_addr % INSN_CACHE_SIZE) != offset);
1523 #endif /* just one plane */
1524 #endif /* Cache is large */
1525 #endif /* Cache exists */
1528 #endif /* L_clear_cache */
1530 #ifdef L_trampoline
1532 /* Jump to a trampoline, loading the static chain address. */
1534 #ifdef TRANSFER_FROM_TRAMPOLINE
1535 TRANSFER_FROM_TRAMPOLINE
1536 #endif
1538 #ifdef __convex__
1540 /* Make stack executable so we can call trampolines on stack.
1541 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
1543 #include <sys/mman.h>
1544 #include <sys/vmparam.h>
1545 #include <machine/machparam.h>
1547 void
1548 __enable_execute_stack ()
1550 int fp;
1551 static unsigned lowest = USRSTACK;
1552 unsigned current = (unsigned) &fp & -NBPG;
1554 if (lowest > current)
1556 unsigned len = lowest - current;
1557 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
1558 lowest = current;
1561 /* Clear instruction cache in case an old trampoline is in it. */
1562 asm ("pich");
1564 #endif /* __convex__ */
1566 #ifdef __pyr__
1568 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1569 #include <stdio.h>
1570 #include <sys/mman.h>
1571 #include <sys/types.h>
1572 #include <sys/param.h>
1573 #include <sys/vmmac.h>
1575 /* Modified from the convex -code above.
1576 mremap promises to clear the i-cache. */
1578 void
1579 __enable_execute_stack ()
1581 int fp;
1582 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
1583 PROT_READ|PROT_WRITE|PROT_EXEC))
1585 perror ("mprotect in __enable_execute_stack");
1586 fflush (stderr);
1587 abort ();
1590 #endif /* __pyr__ */
1591 #endif /* L_trampoline */
1593 #ifdef L__main
1595 #include "gbl-ctors.h"
1596 /* Some systems use __main in a way incompatible with its use in gcc, in these
1597 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
1598 give the same symbol without quotes for an alternative entry point. You
1599 must define both, or niether. */
1600 #ifndef NAME__MAIN
1601 #define NAME__MAIN "__main"
1602 #define SYMBOL__MAIN __main
1603 #endif
1605 /* Run all the global destructors on exit from the program. */
1607 void
1608 __do_global_dtors ()
1610 #ifdef DO_GLOBAL_DTORS_BODY
1611 DO_GLOBAL_DTORS_BODY;
1612 #else
1613 unsigned nptrs = (unsigned HOST_WIDE_INT) __DTOR_LIST__[0];
1614 unsigned i;
1616 /* Some systems place the number of pointers
1617 in the first word of the table.
1618 On other systems, that word is -1.
1619 In all cases, the table is null-terminated. */
1621 /* If the length is not recorded, count up to the null. */
1622 if (nptrs == -1)
1623 for (nptrs = 0; __DTOR_LIST__[nptrs + 1] != 0; nptrs++);
1625 /* GNU LD format. */
1626 for (i = nptrs; i >= 1; i--)
1627 __DTOR_LIST__[i] ();
1628 #endif
1631 #ifndef INIT_SECTION_ASM_OP
1632 /* Run all the global constructors on entry to the program. */
1634 #ifndef ON_EXIT
1635 #define ON_EXIT(a, b)
1636 #else
1637 /* Make sure the exit routine is pulled in to define the globals as
1638 bss symbols, just in case the linker does not automatically pull
1639 bss definitions from the library. */
1641 extern int _exit_dummy_decl;
1642 int *_exit_dummy_ref = &_exit_dummy_decl;
1643 #endif /* ON_EXIT */
1645 void
1646 __do_global_ctors ()
1648 DO_GLOBAL_CTORS_BODY;
1649 ON_EXIT (__do_global_dtors, 0);
1651 #endif /* no INIT_SECTION_ASM_OP */
1653 #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
1654 /* Subroutine called automatically by `main'.
1655 Compiling a global function named `main'
1656 produces an automatic call to this function at the beginning.
1658 For many systems, this routine calls __do_global_ctors.
1659 For systems which support a .init section we use the .init section
1660 to run __do_global_ctors, so we need not do anything here. */
1662 void
1663 SYMBOL__MAIN ()
1665 /* Support recursive calls to `main': run initializers just once. */
1666 static int initialized = 0;
1667 if (! initialized)
1669 initialized = 1;
1670 __do_global_ctors ();
1673 #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
1675 #endif /* L__main */
1677 #ifdef L_ctors
1679 #include "gbl-ctors.h"
1681 /* Provide default definitions for the lists of constructors and
1682 destructors, so that we don't get linker errors. These symbols are
1683 intentionally bss symbols, so that gld and/or collect will provide
1684 the right values. */
1686 /* We declare the lists here with two elements each,
1687 so that they are valid empty lists if no other definition is loaded. */
1688 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
1689 #ifdef __NeXT__
1690 /* After 2.3, try this definition on all systems. */
1691 func_ptr __CTOR_LIST__[2] = {0, 0};
1692 func_ptr __DTOR_LIST__[2] = {0, 0};
1693 #else
1694 func_ptr __CTOR_LIST__[2];
1695 func_ptr __DTOR_LIST__[2];
1696 #endif
1697 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1698 #endif /* L_ctors */
1700 #ifdef L_exit
1702 #include "gbl-ctors.h"
1704 #ifndef ON_EXIT
1706 /* If we have no known way of registering our own __do_global_dtors
1707 routine so that it will be invoked at program exit time, then we
1708 have to define our own exit routine which will get this to happen. */
1710 extern void __do_global_dtors ();
1711 extern void _cleanup ();
1712 extern volatile void _exit ();
1714 void
1715 exit (status)
1716 int status;
1718 __do_global_dtors ();
1719 #ifdef EXIT_BODY
1720 EXIT_BODY;
1721 #else
1722 _cleanup ();
1723 #endif
1724 _exit (status);
1727 #else
1728 int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */
1729 #endif
1731 #endif /* L_exit */
1733 /* In a.out systems, we need to have these dummy constructor and destructor
1734 lists in the library.
1736 When using `collect', the first link will resolve __CTOR_LIST__
1737 and __DTOR_LIST__ to these symbols. We will then run "nm" on the
1738 result, build the correct __CTOR_LIST__ and __DTOR_LIST__, and relink.
1739 Since we don't do the second link if no constructors existed, these
1740 dummies must be fully functional empty lists.
1742 When using `gnu ld', these symbols will be used if there are no
1743 constructors. If there are constructors, the N_SETV symbol defined
1744 by the linker from the N_SETT's in input files will define __CTOR_LIST__
1745 and __DTOR_LIST__ rather than its being allocated as common storage
1746 by the definitions below.
1748 When using a linker that supports constructor and destructor segments,
1749 these definitions will not be used, since crtbegin.o and crtend.o
1750 (from crtstuff.c) will have already defined __CTOR_LIST__ and
1751 __DTOR_LIST__. The crt*.o files are passed directly to the linker
1752 on its command line, by gcc. */
1754 /* The list needs two elements: one is ignored (the old count); the
1755 second is the terminating zero. Since both values are zero, this
1756 declaration is not initialized, and it becomes `common'. */
1758 #ifdef L_ctor_list
1759 #include "gbl-ctors.h"
1760 func_ptr __CTOR_LIST__[2];
1761 #endif
1763 #ifdef L_dtor_list
1764 #include "gbl-ctors.h"
1765 func_ptr __DTOR_LIST__[2];
1766 #endif