OSDN Git Service

* regclass.c (init_reg_autoinc): New function.
[pf3gnuchains/gcc-fork.git] / gcc / libgcc2.c
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.
5
6 This file is part of GCC.
7
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.
12
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.)
21
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.
26
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.  */
31
32 /* It is incorrect to include config.h here, because this file is being
33    compiled for the target, and hence definitions concerning only the host
34    do not apply.  */
35
36 #include "tconfig.h"
37 #include "tsystem.h"
38 #include "coretypes.h"
39 #include "tm.h"
40
41 /* Don't use `fancy_abort' here even if config.h says to use it.  */
42 #ifdef abort
43 #undef abort
44 #endif
45
46 #include "libgcc2.h"
47 \f
48 #ifdef DECLARE_LIBRARY_RENAMES
49   DECLARE_LIBRARY_RENAMES
50 #endif
51
52 #if defined (L_negdi2)
53 DWtype
54 __negdi2 (DWtype u)
55 {
56   DWunion w;
57   DWunion uu;
58
59   uu.ll = u;
60
61   w.s.low = -uu.s.low;
62   w.s.high = -uu.s.high - ((UWtype) w.s.low > 0);
63
64   return w.ll;
65 }
66 #endif
67
68 #ifdef L_addvsi3
69 Wtype
70 __addvsi3 (Wtype a, Wtype b)
71 {
72   Wtype w;
73
74   w = a + b;
75
76   if (b >= 0 ? w < a : w > a)
77     abort ();
78
79   return w;
80 }
81 #endif
82 \f
83 #ifdef L_addvdi3
84 DWtype
85 __addvdi3 (DWtype a, DWtype b)
86 {
87   DWtype w;
88
89   w = a + b;
90
91   if (b >= 0 ? w < a : w > a)
92     abort ();
93
94   return w;
95 }
96 #endif
97 \f
98 #ifdef L_subvsi3
99 Wtype
100 __subvsi3 (Wtype a, Wtype b)
101 {
102 #ifdef L_addvsi3
103   return __addvsi3 (a, (-b));
104 #else
105   DWtype w;
106
107   w = a - b;
108
109   if (b >= 0 ? w > a : w < a)
110     abort ();
111
112   return w;
113 #endif
114 }
115 #endif
116 \f
117 #ifdef L_subvdi3
118 DWtype
119 __subvdi3 (DWtype a, DWtype b)
120 {
121 #ifdef L_addvdi3
122   return (a, (-b));
123 #else
124   DWtype w;
125
126   w = a - b;
127
128   if (b >= 0 ? w > a : w < a)
129     abort ();
130
131   return w;
132 #endif
133 }
134 #endif
135 \f
136 #ifdef L_mulvsi3
137 Wtype
138 __mulvsi3 (Wtype a, Wtype b)
139 {
140   DWtype w;
141
142   w = a * b;
143
144   if (((a >= 0) == (b >= 0)) ? w < 0 : w > 0)
145     abort ();
146
147   return w;
148 }
149 #endif
150 \f
151 #ifdef L_negvsi2
152 Wtype
153 __negvsi2 (Wtype a)
154 {
155   Wtype w;
156
157   w  = -a;
158
159   if (a >= 0 ? w > 0 : w < 0)
160     abort ();
161
162    return w;
163 }
164 #endif
165 \f
166 #ifdef L_negvdi2
167 DWtype
168 __negvdi2 (DWtype a)
169 {
170   DWtype w;
171
172   w  = -a;
173
174   if (a >= 0 ? w > 0 : w < 0)
175     abort ();
176
177   return w;
178 }
179 #endif
180 \f
181 #ifdef L_absvsi2
182 Wtype
183 __absvsi2 (Wtype a)
184 {
185   Wtype w = a;
186
187   if (a < 0)
188 #ifdef L_negvsi2
189     w = __negvsi2 (a);
190 #else
191     w = -a;
192
193   if (w < 0)
194     abort ();
195 #endif
196
197    return w;
198 }
199 #endif
200 \f
201 #ifdef L_absvdi2
202 DWtype
203 __absvdi2 (DWtype a)
204 {
205   DWtype w = a;
206
207   if (a < 0)
208 #ifdef L_negvsi2
209     w = __negvsi2 (a);
210 #else
211     w = -a;
212
213   if (w < 0)
214     abort ();
215 #endif
216
217   return w;
218 }
219 #endif
220 \f
221 #ifdef L_mulvdi3
222 DWtype
223 __mulvdi3 (DWtype u, DWtype v)
224 {
225   DWtype w;
226
227   w = u * v;
228
229   if (((u >= 0) == (v >= 0)) ? w < 0 : w > 0)
230     abort ();
231
232   return w;
233 }
234 #endif
235 \f
236
237 /* Unless shift functions are defined with full ANSI prototypes,
238    parameter b will be promoted to int if word_type is smaller than an int.  */
239 #ifdef L_lshrdi3
240 DWtype
241 __lshrdi3 (DWtype u, word_type b)
242 {
243   DWunion w;
244   word_type bm;
245   DWunion uu;
246
247   if (b == 0)
248     return u;
249
250   uu.ll = u;
251
252   bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
253   if (bm <= 0)
254     {
255       w.s.high = 0;
256       w.s.low = (UWtype) uu.s.high >> -bm;
257     }
258   else
259     {
260       UWtype carries = (UWtype) uu.s.high << bm;
261
262       w.s.high = (UWtype) uu.s.high >> b;
263       w.s.low = ((UWtype) uu.s.low >> b) | carries;
264     }
265
266   return w.ll;
267 }
268 #endif
269
270 #ifdef L_ashldi3
271 DWtype
272 __ashldi3 (DWtype u, word_type b)
273 {
274   DWunion w;
275   word_type bm;
276   DWunion uu;
277
278   if (b == 0)
279     return u;
280
281   uu.ll = u;
282
283   bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
284   if (bm <= 0)
285     {
286       w.s.low = 0;
287       w.s.high = (UWtype) uu.s.low << -bm;
288     }
289   else
290     {
291       UWtype carries = (UWtype) uu.s.low >> bm;
292
293       w.s.low = (UWtype) uu.s.low << b;
294       w.s.high = ((UWtype) uu.s.high << b) | carries;
295     }
296
297   return w.ll;
298 }
299 #endif
300
301 #ifdef L_ashrdi3
302 DWtype
303 __ashrdi3 (DWtype u, word_type b)
304 {
305   DWunion w;
306   word_type bm;
307   DWunion uu;
308
309   if (b == 0)
310     return u;
311
312   uu.ll = u;
313
314   bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
315   if (bm <= 0)
316     {
317       /* w.s.high = 1..1 or 0..0 */
318       w.s.high = uu.s.high >> (sizeof (Wtype) * BITS_PER_UNIT - 1);
319       w.s.low = uu.s.high >> -bm;
320     }
321   else
322     {
323       UWtype carries = (UWtype) uu.s.high << bm;
324
325       w.s.high = uu.s.high >> b;
326       w.s.low = ((UWtype) uu.s.low >> b) | carries;
327     }
328
329   return w.ll;
330 }
331 #endif
332 \f
333 #ifdef L_ffsdi2
334 DWtype
335 __ffsdi2 (DWtype u)
336 {
337   DWunion uu;
338   UWtype word, count, add;
339
340   uu.ll = u;
341   if (uu.s.low != 0)
342     word = uu.s.low, add = 0;
343   else if (uu.s.high != 0)
344     word = uu.s.high, add = BITS_PER_UNIT * sizeof (Wtype);
345   else
346     return 0;
347
348   count_trailing_zeros (count, word);
349   return count + add + 1;
350 }
351 #endif
352 \f
353 #ifdef L_muldi3
354 DWtype
355 __muldi3 (DWtype u, DWtype v)
356 {
357   DWunion w;
358   DWunion uu, vv;
359
360   uu.ll = u,
361   vv.ll = v;
362
363   w.ll = __umulsidi3 (uu.s.low, vv.s.low);
364   w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
365                + (UWtype) uu.s.high * (UWtype) vv.s.low);
366
367   return w.ll;
368 }
369 #endif
370 \f
371 #if (defined (L_udivdi3) || defined (L_divdi3) || \
372      defined (L_umoddi3) || defined (L_moddi3))
373 #if defined (sdiv_qrnnd)
374 #define L_udiv_w_sdiv
375 #endif
376 #endif
377
378 #ifdef L_udiv_w_sdiv
379 #if defined (sdiv_qrnnd)
380 #if (defined (L_udivdi3) || defined (L_divdi3) || \
381      defined (L_umoddi3) || defined (L_moddi3))
382 static inline __attribute__ ((__always_inline__))
383 #endif
384 UWtype
385 __udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d)
386 {
387   UWtype q, r;
388   UWtype c0, c1, b1;
389
390   if ((Wtype) d >= 0)
391     {
392       if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1)))
393         {
394           /* dividend, divisor, and quotient are nonnegative */
395           sdiv_qrnnd (q, r, a1, a0, d);
396         }
397       else
398         {
399           /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
400           sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1));
401           /* Divide (c1*2^32 + c0) by d */
402           sdiv_qrnnd (q, r, c1, c0, d);
403           /* Add 2^31 to quotient */
404           q += (UWtype) 1 << (W_TYPE_SIZE - 1);
405         }
406     }
407   else
408     {
409       b1 = d >> 1;                      /* d/2, between 2^30 and 2^31 - 1 */
410       c1 = a1 >> 1;                     /* A/2 */
411       c0 = (a1 << (W_TYPE_SIZE - 1)) + (a0 >> 1);
412
413       if (a1 < b1)                      /* A < 2^32*b1, so A/2 < 2^31*b1 */
414         {
415           sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
416
417           r = 2*r + (a0 & 1);           /* Remainder from A/(2*b1) */
418           if ((d & 1) != 0)
419             {
420               if (r >= q)
421                 r = r - q;
422               else if (q - r <= d)
423                 {
424                   r = r - q + d;
425                   q--;
426                 }
427               else
428                 {
429                   r = r - q + 2*d;
430                   q -= 2;
431                 }
432             }
433         }
434       else if (c1 < b1)                 /* So 2^31 <= (A/2)/b1 < 2^32 */
435         {
436           c1 = (b1 - 1) - c1;
437           c0 = ~c0;                     /* logical NOT */
438
439           sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
440
441           q = ~q;                       /* (A/2)/b1 */
442           r = (b1 - 1) - r;
443
444           r = 2*r + (a0 & 1);           /* A/(2*b1) */
445
446           if ((d & 1) != 0)
447             {
448               if (r >= q)
449                 r = r - q;
450               else if (q - r <= d)
451                 {
452                   r = r - q + d;
453                   q--;
454                 }
455               else
456                 {
457                   r = r - q + 2*d;
458                   q -= 2;
459                 }
460             }
461         }
462       else                              /* Implies c1 = b1 */
463         {                               /* Hence a1 = d - 1 = 2*b1 - 1 */
464           if (a0 >= -d)
465             {
466               q = -1;
467               r = a0 + d;
468             }
469           else
470             {
471               q = -2;
472               r = a0 + 2*d;
473             }
474         }
475     }
476
477   *rp = r;
478   return q;
479 }
480 #else
481 /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv.  */
482 UWtype
483 __udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)),
484                UWtype a1 __attribute__ ((__unused__)),
485                UWtype a0 __attribute__ ((__unused__)),
486                UWtype d __attribute__ ((__unused__)))
487 {
488   return 0;
489 }
490 #endif
491 #endif
492 \f
493 #if (defined (L_udivdi3) || defined (L_divdi3) || \
494      defined (L_umoddi3) || defined (L_moddi3))
495 #define L_udivmoddi4
496 #endif
497
498 #ifdef L_clz
499 const UQItype __clz_tab[] =
500 {
501   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,
502   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,
503   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,
504   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,
505   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,
506   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,
507   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,
508   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,
509 };
510 #endif
511
512 #ifdef L_udivmoddi4
513
514 #if (defined (L_udivdi3) || defined (L_divdi3) || \
515      defined (L_umoddi3) || defined (L_moddi3))
516 static inline __attribute__ ((__always_inline__))
517 #endif
518 UDWtype
519 __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
520 {
521   DWunion ww;
522   DWunion nn, dd;
523   DWunion rr;
524   UWtype d0, d1, n0, n1, n2;
525   UWtype q0, q1;
526   UWtype b, bm;
527
528   nn.ll = n;
529   dd.ll = d;
530
531   d0 = dd.s.low;
532   d1 = dd.s.high;
533   n0 = nn.s.low;
534   n1 = nn.s.high;
535
536 #if !UDIV_NEEDS_NORMALIZATION
537   if (d1 == 0)
538     {
539       if (d0 > n1)
540         {
541           /* 0q = nn / 0D */
542
543           udiv_qrnnd (q0, n0, n1, n0, d0);
544           q1 = 0;
545
546           /* Remainder in n0.  */
547         }
548       else
549         {
550           /* qq = NN / 0d */
551
552           if (d0 == 0)
553             d0 = 1 / d0;        /* Divide intentionally by zero.  */
554
555           udiv_qrnnd (q1, n1, 0, n1, d0);
556           udiv_qrnnd (q0, n0, n1, n0, d0);
557
558           /* Remainder in n0.  */
559         }
560
561       if (rp != 0)
562         {
563           rr.s.low = n0;
564           rr.s.high = 0;
565           *rp = rr.ll;
566         }
567     }
568
569 #else /* UDIV_NEEDS_NORMALIZATION */
570
571   if (d1 == 0)
572     {
573       if (d0 > n1)
574         {
575           /* 0q = nn / 0D */
576
577           count_leading_zeros (bm, d0);
578
579           if (bm != 0)
580             {
581               /* Normalize, i.e. make the most significant bit of the
582                  denominator set.  */
583
584               d0 = d0 << bm;
585               n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
586               n0 = n0 << bm;
587             }
588
589           udiv_qrnnd (q0, n0, n1, n0, d0);
590           q1 = 0;
591
592           /* Remainder in n0 >> bm.  */
593         }
594       else
595         {
596           /* qq = NN / 0d */
597
598           if (d0 == 0)
599             d0 = 1 / d0;        /* Divide intentionally by zero.  */
600
601           count_leading_zeros (bm, d0);
602
603           if (bm == 0)
604             {
605               /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
606                  conclude (the most significant bit of n1 is set) /\ (the
607                  leading quotient digit q1 = 1).
608
609                  This special case is necessary, not an optimization.
610                  (Shifts counts of W_TYPE_SIZE are undefined.)  */
611
612               n1 -= d0;
613               q1 = 1;
614             }
615           else
616             {
617               /* Normalize.  */
618
619               b = W_TYPE_SIZE - bm;
620
621               d0 = d0 << bm;
622               n2 = n1 >> b;
623               n1 = (n1 << bm) | (n0 >> b);
624               n0 = n0 << bm;
625
626               udiv_qrnnd (q1, n1, n2, n1, d0);
627             }
628
629           /* n1 != d0...  */
630
631           udiv_qrnnd (q0, n0, n1, n0, d0);
632
633           /* Remainder in n0 >> bm.  */
634         }
635
636       if (rp != 0)
637         {
638           rr.s.low = n0 >> bm;
639           rr.s.high = 0;
640           *rp = rr.ll;
641         }
642     }
643 #endif /* UDIV_NEEDS_NORMALIZATION */
644
645   else
646     {
647       if (d1 > n1)
648         {
649           /* 00 = nn / DD */
650
651           q0 = 0;
652           q1 = 0;
653
654           /* Remainder in n1n0.  */
655           if (rp != 0)
656             {
657               rr.s.low = n0;
658               rr.s.high = n1;
659               *rp = rr.ll;
660             }
661         }
662       else
663         {
664           /* 0q = NN / dd */
665
666           count_leading_zeros (bm, d1);
667           if (bm == 0)
668             {
669               /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
670                  conclude (the most significant bit of n1 is set) /\ (the
671                  quotient digit q0 = 0 or 1).
672
673                  This special case is necessary, not an optimization.  */
674
675               /* The condition on the next line takes advantage of that
676                  n1 >= d1 (true due to program flow).  */
677               if (n1 > d1 || n0 >= d0)
678                 {
679                   q0 = 1;
680                   sub_ddmmss (n1, n0, n1, n0, d1, d0);
681                 }
682               else
683                 q0 = 0;
684
685               q1 = 0;
686
687               if (rp != 0)
688                 {
689                   rr.s.low = n0;
690                   rr.s.high = n1;
691                   *rp = rr.ll;
692                 }
693             }
694           else
695             {
696               UWtype m1, m0;
697               /* Normalize.  */
698
699               b = W_TYPE_SIZE - bm;
700
701               d1 = (d1 << bm) | (d0 >> b);
702               d0 = d0 << bm;
703               n2 = n1 >> b;
704               n1 = (n1 << bm) | (n0 >> b);
705               n0 = n0 << bm;
706
707               udiv_qrnnd (q0, n1, n2, n1, d1);
708               umul_ppmm (m1, m0, q0, d0);
709
710               if (m1 > n1 || (m1 == n1 && m0 > n0))
711                 {
712                   q0--;
713                   sub_ddmmss (m1, m0, m1, m0, d1, d0);
714                 }
715
716               q1 = 0;
717
718               /* Remainder in (n1n0 - m1m0) >> bm.  */
719               if (rp != 0)
720                 {
721                   sub_ddmmss (n1, n0, n1, n0, m1, m0);
722                   rr.s.low = (n1 << b) | (n0 >> bm);
723                   rr.s.high = n1 >> bm;
724                   *rp = rr.ll;
725                 }
726             }
727         }
728     }
729
730   ww.s.low = q0;
731   ww.s.high = q1;
732   return ww.ll;
733 }
734 #endif
735
736 #ifdef L_divdi3
737 DWtype
738 __divdi3 (DWtype u, DWtype v)
739 {
740   word_type c = 0;
741   DWunion uu, vv;
742   DWtype w;
743
744   uu.ll = u;
745   vv.ll = v;
746
747   if (uu.s.high < 0)
748     c = ~c,
749     uu.ll = -uu.ll;
750   if (vv.s.high < 0)
751     c = ~c,
752     vv.ll = -vv.ll;
753
754   w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
755   if (c)
756     w = -w;
757
758   return w;
759 }
760 #endif
761
762 #ifdef L_moddi3
763 DWtype
764 __moddi3 (DWtype u, DWtype v)
765 {
766   word_type c = 0;
767   DWunion uu, vv;
768   DWtype w;
769
770   uu.ll = u;
771   vv.ll = v;
772
773   if (uu.s.high < 0)
774     c = ~c,
775     uu.ll = -uu.ll;
776   if (vv.s.high < 0)
777     vv.ll = -vv.ll;
778
779   (void) __udivmoddi4 (uu.ll, vv.ll, &w);
780   if (c)
781     w = -w;
782
783   return w;
784 }
785 #endif
786
787 #ifdef L_umoddi3
788 UDWtype
789 __umoddi3 (UDWtype u, UDWtype v)
790 {
791   UDWtype w;
792
793   (void) __udivmoddi4 (u, v, &w);
794
795   return w;
796 }
797 #endif
798
799 #ifdef L_udivdi3
800 UDWtype
801 __udivdi3 (UDWtype n, UDWtype d)
802 {
803   return __udivmoddi4 (n, d, (UDWtype *) 0);
804 }
805 #endif
806 \f
807 #ifdef L_cmpdi2
808 word_type
809 __cmpdi2 (DWtype a, DWtype b)
810 {
811   DWunion au, bu;
812
813   au.ll = a, bu.ll = b;
814
815   if (au.s.high < bu.s.high)
816     return 0;
817   else if (au.s.high > bu.s.high)
818     return 2;
819   if ((UWtype) au.s.low < (UWtype) bu.s.low)
820     return 0;
821   else if ((UWtype) au.s.low > (UWtype) bu.s.low)
822     return 2;
823   return 1;
824 }
825 #endif
826
827 #ifdef L_ucmpdi2
828 word_type
829 __ucmpdi2 (DWtype a, DWtype b)
830 {
831   DWunion au, bu;
832
833   au.ll = a, bu.ll = b;
834
835   if ((UWtype) au.s.high < (UWtype) bu.s.high)
836     return 0;
837   else if ((UWtype) au.s.high > (UWtype) bu.s.high)
838     return 2;
839   if ((UWtype) au.s.low < (UWtype) bu.s.low)
840     return 0;
841   else if ((UWtype) au.s.low > (UWtype) bu.s.low)
842     return 2;
843   return 1;
844 }
845 #endif
846 \f
847 #if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
848 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
849 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
850
851 DWtype
852 __fixunstfDI (TFtype a)
853 {
854   TFtype b;
855   UDWtype v;
856
857   if (a < 0)
858     return 0;
859
860   /* Compute high word of result, as a flonum.  */
861   b = (a / HIGH_WORD_COEFF);
862   /* Convert that to fixed (but not to DWtype!),
863      and shift it into the high word.  */
864   v = (UWtype) b;
865   v <<= WORD_SIZE;
866   /* Remove high part from the TFtype, leaving the low part as flonum.  */
867   a -= (TFtype)v;
868   /* Convert that to fixed (but not to DWtype!) and add it in.
869      Sometimes A comes out negative.  This is significant, since
870      A has more bits than a long int does.  */
871   if (a < 0)
872     v -= (UWtype) (- a);
873   else
874     v += (UWtype) a;
875   return v;
876 }
877 #endif
878
879 #if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
880 DWtype
881 __fixtfdi (TFtype a)
882 {
883   if (a < 0)
884     return - __fixunstfDI (-a);
885   return __fixunstfDI (a);
886 }
887 #endif
888
889 #if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
890 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
891 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
892
893 DWtype
894 __fixunsxfDI (XFtype a)
895 {
896   XFtype b;
897   UDWtype v;
898
899   if (a < 0)
900     return 0;
901
902   /* Compute high word of result, as a flonum.  */
903   b = (a / HIGH_WORD_COEFF);
904   /* Convert that to fixed (but not to DWtype!),
905      and shift it into the high word.  */
906   v = (UWtype) b;
907   v <<= WORD_SIZE;
908   /* Remove high part from the XFtype, leaving the low part as flonum.  */
909   a -= (XFtype)v;
910   /* Convert that to fixed (but not to DWtype!) and add it in.
911      Sometimes A comes out negative.  This is significant, since
912      A has more bits than a long int does.  */
913   if (a < 0)
914     v -= (UWtype) (- a);
915   else
916     v += (UWtype) a;
917   return v;
918 }
919 #endif
920
921 #if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
922 DWtype
923 __fixxfdi (XFtype a)
924 {
925   if (a < 0)
926     return - __fixunsxfDI (-a);
927   return __fixunsxfDI (a);
928 }
929 #endif
930
931 #ifdef L_fixunsdfdi
932 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
933 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
934
935 DWtype
936 __fixunsdfDI (DFtype a)
937 {
938   UWtype hi, lo;
939
940   /* Get high part of result.  The division here will just moves the radix
941      point and will not cause any rounding.  Then the conversion to integral
942      type chops result as desired.  */
943   hi = a / HIGH_WORD_COEFF;
944
945   /* Get low part of result.  Convert `hi' to floating type and scale it back,
946      then subtract this from the number being converted.  This leaves the low
947      part.  Convert that to integral type.  */
948   lo = (a - ((DFtype) hi) * HIGH_WORD_COEFF);
949
950   /* Assemble result from the two parts.  */
951   return ((UDWtype) hi << WORD_SIZE) | lo;
952 }
953 #endif
954
955 #ifdef L_fixdfdi
956 DWtype
957 __fixdfdi (DFtype a)
958 {
959   if (a < 0)
960     return - __fixunsdfDI (-a);
961   return __fixunsdfDI (a);
962 }
963 #endif
964
965 #ifdef L_fixunssfdi
966 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
967 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
968
969 DWtype
970 __fixunssfDI (SFtype original_a)
971 {
972   /* Convert the SFtype to a DFtype, because that is surely not going
973      to lose any bits.  Some day someone else can write a faster version
974      that avoids converting to DFtype, and verify it really works right.  */
975   DFtype a = original_a;
976   UWtype hi, lo;
977
978   /* Get high part of result.  The division here will just moves the radix
979      point and will not cause any rounding.  Then the conversion to integral
980      type chops result as desired.  */
981   hi = a / HIGH_WORD_COEFF;
982
983   /* Get low part of result.  Convert `hi' to floating type and scale it back,
984      then subtract this from the number being converted.  This leaves the low
985      part.  Convert that to integral type.  */
986   lo = (a - ((DFtype) hi) * HIGH_WORD_COEFF);
987
988   /* Assemble result from the two parts.  */
989   return ((UDWtype) hi << WORD_SIZE) | lo;
990 }
991 #endif
992
993 #ifdef L_fixsfdi
994 DWtype
995 __fixsfdi (SFtype a)
996 {
997   if (a < 0)
998     return - __fixunssfDI (-a);
999   return __fixunssfDI (a);
1000 }
1001 #endif
1002
1003 #if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
1004 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1005 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1006 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1007
1008 XFtype
1009 __floatdixf (DWtype u)
1010 {
1011   XFtype d;
1012
1013   d = (Wtype) (u >> WORD_SIZE);
1014   d *= HIGH_HALFWORD_COEFF;
1015   d *= HIGH_HALFWORD_COEFF;
1016   d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1017
1018   return d;
1019 }
1020 #endif
1021
1022 #if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
1023 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1024 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1025 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1026
1027 TFtype
1028 __floatditf (DWtype u)
1029 {
1030   TFtype d;
1031
1032   d = (Wtype) (u >> WORD_SIZE);
1033   d *= HIGH_HALFWORD_COEFF;
1034   d *= HIGH_HALFWORD_COEFF;
1035   d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1036
1037   return d;
1038 }
1039 #endif
1040
1041 #ifdef L_floatdidf
1042 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1043 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1044 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1045
1046 DFtype
1047 __floatdidf (DWtype u)
1048 {
1049   DFtype d;
1050
1051   d = (Wtype) (u >> WORD_SIZE);
1052   d *= HIGH_HALFWORD_COEFF;
1053   d *= HIGH_HALFWORD_COEFF;
1054   d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1055
1056   return d;
1057 }
1058 #endif
1059
1060 #ifdef L_floatdisf
1061 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1062 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1063 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1064
1065 #define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT)
1066 #define DF_SIZE DBL_MANT_DIG
1067 #define SF_SIZE FLT_MANT_DIG
1068
1069 SFtype
1070 __floatdisf (DWtype u)
1071 {
1072   /* Do the calculation in DFmode
1073      so that we don't lose any of the precision of the high word
1074      while multiplying it.  */
1075   DFtype f;
1076
1077   /* Protect against double-rounding error.
1078      Represent any low-order bits, that might be truncated in DFmode,
1079      by a bit that won't be lost.  The bit can go in anywhere below the
1080      rounding position of the SFmode.  A fixed mask and bit position
1081      handles all usual configurations.  It doesn't handle the case
1082      of 128-bit DImode, however.  */
1083   if (DF_SIZE < DI_SIZE
1084       && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1085     {
1086 #define REP_BIT ((UDWtype) 1 << (DI_SIZE - DF_SIZE))
1087       if (! (- ((DWtype) 1 << DF_SIZE) < u
1088              && u < ((DWtype) 1 << DF_SIZE)))
1089         {
1090           if ((UDWtype) u & (REP_BIT - 1))
1091             {
1092               u &= ~ (REP_BIT - 1);
1093               u |= REP_BIT;
1094             }
1095         }
1096     }
1097   f = (Wtype) (u >> WORD_SIZE);
1098   f *= HIGH_HALFWORD_COEFF;
1099   f *= HIGH_HALFWORD_COEFF;
1100   f += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1101
1102   return (SFtype) f;
1103 }
1104 #endif
1105
1106 #if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
1107 /* Reenable the normal types, in case limits.h needs them.  */
1108 #undef char
1109 #undef short
1110 #undef int
1111 #undef long
1112 #undef unsigned
1113 #undef float
1114 #undef double
1115 #undef MIN
1116 #undef MAX
1117 #include <limits.h>
1118
1119 UWtype
1120 __fixunsxfSI (XFtype a)
1121 {
1122   if (a >= - (DFtype) Wtype_MIN)
1123     return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1124   return (Wtype) a;
1125 }
1126 #endif
1127
1128 #ifdef L_fixunsdfsi
1129 /* Reenable the normal types, in case limits.h needs them.  */
1130 #undef char
1131 #undef short
1132 #undef int
1133 #undef long
1134 #undef unsigned
1135 #undef float
1136 #undef double
1137 #undef MIN
1138 #undef MAX
1139 #include <limits.h>
1140
1141 UWtype
1142 __fixunsdfSI (DFtype a)
1143 {
1144   if (a >= - (DFtype) Wtype_MIN)
1145     return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1146   return (Wtype) a;
1147 }
1148 #endif
1149
1150 #ifdef L_fixunssfsi
1151 /* Reenable the normal types, in case limits.h needs them.  */
1152 #undef char
1153 #undef short
1154 #undef int
1155 #undef long
1156 #undef unsigned
1157 #undef float
1158 #undef double
1159 #undef MIN
1160 #undef MAX
1161 #include <limits.h>
1162
1163 UWtype
1164 __fixunssfSI (SFtype a)
1165 {
1166   if (a >= - (SFtype) Wtype_MIN)
1167     return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1168   return (Wtype) a;
1169 }
1170 #endif
1171 \f
1172 /* From here on down, the routines use normal data types.  */
1173
1174 #define SItype bogus_type
1175 #define USItype bogus_type
1176 #define DItype bogus_type
1177 #define UDItype bogus_type
1178 #define SFtype bogus_type
1179 #define DFtype bogus_type
1180 #undef Wtype
1181 #undef UWtype
1182 #undef HWtype
1183 #undef UHWtype
1184 #undef DWtype
1185 #undef UDWtype
1186
1187 #undef char
1188 #undef short
1189 #undef int
1190 #undef long
1191 #undef unsigned
1192 #undef float
1193 #undef double
1194 \f
1195 #ifdef L__gcc_bcmp
1196
1197 /* Like bcmp except the sign is meaningful.
1198    Result is negative if S1 is less than S2,
1199    positive if S1 is greater, 0 if S1 and S2 are equal.  */
1200
1201 int
1202 __gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
1203 {
1204   while (size > 0)
1205     {
1206       unsigned char c1 = *s1++, c2 = *s2++;
1207       if (c1 != c2)
1208         return c1 - c2;
1209       size--;
1210     }
1211   return 0;
1212 }
1213
1214 #endif
1215 \f
1216 /* __eprintf used to be used by GCC's private version of <assert.h>.
1217    We no longer provide that header, but this routine remains in libgcc.a
1218    for binary backward compatibility.  Note that it is not included in
1219    the shared version of libgcc.  */
1220 #ifdef L_eprintf
1221 #ifndef inhibit_libc
1222
1223 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1224 #include <stdio.h>
1225
1226 void
1227 __eprintf (const char *string, const char *expression,
1228            unsigned int line, const char *filename)
1229 {
1230   fprintf (stderr, string, expression, line, filename);
1231   fflush (stderr);
1232   abort ();
1233 }
1234
1235 #endif
1236 #endif
1237
1238 \f
1239 #ifdef L_clear_cache
1240 /* Clear part of an instruction cache.  */
1241
1242 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1243
1244 void
1245 __clear_cache (char *beg __attribute__((__unused__)),
1246                char *end __attribute__((__unused__)))
1247 {
1248 #ifdef CLEAR_INSN_CACHE
1249   CLEAR_INSN_CACHE (beg, end);
1250 #else
1251 #ifdef INSN_CACHE_SIZE
1252   static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1253   static int initialized;
1254   int offset;
1255   void *start_addr
1256   void *end_addr;
1257   typedef (*function_ptr) (void);
1258
1259 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1260   /* It's cheaper to clear the whole cache.
1261      Put in a series of jump instructions so that calling the beginning
1262      of the cache will clear the whole thing.  */
1263
1264   if (! initialized)
1265     {
1266       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1267                  & -INSN_CACHE_LINE_WIDTH);
1268       int end_ptr = ptr + INSN_CACHE_SIZE;
1269
1270       while (ptr < end_ptr)
1271         {
1272           *(INSTRUCTION_TYPE *)ptr
1273             = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1274           ptr += INSN_CACHE_LINE_WIDTH;
1275         }
1276       *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1277
1278       initialized = 1;
1279     }
1280
1281   /* Call the beginning of the sequence.  */
1282   (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1283                     & -INSN_CACHE_LINE_WIDTH))
1284    ());
1285
1286 #else /* Cache is large.  */
1287
1288   if (! initialized)
1289     {
1290       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1291                  & -INSN_CACHE_LINE_WIDTH);
1292
1293       while (ptr < (int) array + sizeof array)
1294         {
1295           *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1296           ptr += INSN_CACHE_LINE_WIDTH;
1297         }
1298
1299       initialized = 1;
1300     }
1301
1302   /* Find the location in array that occupies the same cache line as BEG.  */
1303
1304   offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1305   start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1306                  & -INSN_CACHE_PLANE_SIZE)
1307                 + offset);
1308
1309   /* Compute the cache alignment of the place to stop clearing.  */
1310 #if 0  /* This is not needed for gcc's purposes.  */
1311   /* If the block to clear is bigger than a cache plane,
1312      we clear the entire cache, and OFFSET is already correct.  */
1313   if (end < beg + INSN_CACHE_PLANE_SIZE)
1314 #endif
1315     offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1316                & -INSN_CACHE_LINE_WIDTH)
1317               & (INSN_CACHE_PLANE_SIZE - 1));
1318
1319 #if INSN_CACHE_DEPTH > 1
1320   end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1321   if (end_addr <= start_addr)
1322     end_addr += INSN_CACHE_PLANE_SIZE;
1323
1324   for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1325     {
1326       int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1327       int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1328
1329       while (addr != stop)
1330         {
1331           /* Call the return instruction at ADDR.  */
1332           ((function_ptr) addr) ();
1333
1334           addr += INSN_CACHE_LINE_WIDTH;
1335         }
1336     }
1337 #else /* just one plane */
1338   do
1339     {
1340       /* Call the return instruction at START_ADDR.  */
1341       ((function_ptr) start_addr) ();
1342
1343       start_addr += INSN_CACHE_LINE_WIDTH;
1344     }
1345   while ((start_addr % INSN_CACHE_SIZE) != offset);
1346 #endif /* just one plane */
1347 #endif /* Cache is large */
1348 #endif /* Cache exists */
1349 #endif /* CLEAR_INSN_CACHE */
1350 }
1351
1352 #endif /* L_clear_cache */
1353 \f
1354 #ifdef L_trampoline
1355
1356 /* Jump to a trampoline, loading the static chain address.  */
1357
1358 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
1359
1360 long
1361 getpagesize (void)
1362 {
1363 #ifdef _ALPHA_
1364   return 8192;
1365 #else
1366   return 4096;
1367 #endif
1368 }
1369
1370 #ifdef __i386__
1371 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
1372 #endif
1373
1374 int
1375 mprotect (char *addr, int len, int prot)
1376 {
1377   int np, op;
1378
1379   if (prot == 7)
1380     np = 0x40;
1381   else if (prot == 5)
1382     np = 0x20;
1383   else if (prot == 4)
1384     np = 0x10;
1385   else if (prot == 3)
1386     np = 0x04;
1387   else if (prot == 1)
1388     np = 0x02;
1389   else if (prot == 0)
1390     np = 0x01;
1391
1392   if (VirtualProtect (addr, len, np, &op))
1393     return 0;
1394   else
1395     return -1;
1396 }
1397
1398 #endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
1399
1400 #ifdef TRANSFER_FROM_TRAMPOLINE
1401 TRANSFER_FROM_TRAMPOLINE
1402 #endif
1403
1404 #ifdef __sysV68__
1405
1406 #include <sys/signal.h>
1407 #include <errno.h>
1408
1409 /* Motorola forgot to put memctl.o in the libp version of libc881.a,
1410    so define it here, because we need it in __clear_insn_cache below */
1411 /* On older versions of this OS, no memctl or MCT_TEXT are defined;
1412    hence we enable this stuff only if MCT_TEXT is #define'd.  */
1413
1414 #ifdef MCT_TEXT
1415 asm("\n\
1416         global memctl\n\
1417 memctl:\n\
1418         movq &75,%d0\n\
1419         trap &0\n\
1420         bcc.b noerror\n\
1421         jmp cerror%\n\
1422 noerror:\n\
1423         movq &0,%d0\n\
1424         rts");
1425 #endif
1426
1427 /* Clear instruction cache so we can call trampolines on stack.
1428    This is called from FINALIZE_TRAMPOLINE in mot3300.h.  */
1429
1430 void
1431 __clear_insn_cache (void)
1432 {
1433 #ifdef MCT_TEXT
1434   int save_errno;
1435
1436   /* Preserve errno, because users would be surprised to have
1437   errno changing without explicitly calling any system-call.  */
1438   save_errno = errno;
1439
1440   /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache.
1441      No need to use an address derived from _start or %sp, as 0 works also.  */
1442   memctl(0, 4096, MCT_TEXT);
1443   errno = save_errno;
1444 #endif
1445 }
1446
1447 #endif /* __sysV68__ */
1448 #endif /* L_trampoline */
1449 \f
1450 #ifndef __CYGWIN__
1451 #ifdef L__main
1452
1453 #include "gbl-ctors.h"
1454 /* Some systems use __main in a way incompatible with its use in gcc, in these
1455    cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
1456    give the same symbol without quotes for an alternative entry point.  You
1457    must define both, or neither.  */
1458 #ifndef NAME__MAIN
1459 #define NAME__MAIN "__main"
1460 #define SYMBOL__MAIN __main
1461 #endif
1462
1463 #ifdef INIT_SECTION_ASM_OP
1464 #undef HAS_INIT_SECTION
1465 #define HAS_INIT_SECTION
1466 #endif
1467
1468 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
1469
1470 /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
1471    code to run constructors.  In that case, we need to handle EH here, too.  */
1472
1473 #ifdef EH_FRAME_SECTION_NAME
1474 #include "unwind-dw2-fde.h"
1475 extern unsigned char __EH_FRAME_BEGIN__[];
1476 #endif
1477
1478 /* Run all the global destructors on exit from the program.  */
1479
1480 void
1481 __do_global_dtors (void)
1482 {
1483 #ifdef DO_GLOBAL_DTORS_BODY
1484   DO_GLOBAL_DTORS_BODY;
1485 #else
1486   static func_ptr *p = __DTOR_LIST__ + 1;
1487   while (*p)
1488     {
1489       p++;
1490       (*(p-1)) ();
1491     }
1492 #endif
1493 #if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION)
1494   {
1495     static int completed = 0;
1496     if (! completed)
1497       {
1498         completed = 1;
1499         __deregister_frame_info (__EH_FRAME_BEGIN__);
1500       }
1501   }
1502 #endif
1503 }
1504 #endif
1505
1506 #ifndef HAS_INIT_SECTION
1507 /* Run all the global constructors on entry to the program.  */
1508
1509 void
1510 __do_global_ctors (void)
1511 {
1512 #ifdef EH_FRAME_SECTION_NAME
1513   {
1514     static struct object object;
1515     __register_frame_info (__EH_FRAME_BEGIN__, &object);
1516   }
1517 #endif
1518   DO_GLOBAL_CTORS_BODY;
1519   atexit (__do_global_dtors);
1520 }
1521 #endif /* no HAS_INIT_SECTION */
1522
1523 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
1524 /* Subroutine called automatically by `main'.
1525    Compiling a global function named `main'
1526    produces an automatic call to this function at the beginning.
1527
1528    For many systems, this routine calls __do_global_ctors.
1529    For systems which support a .init section we use the .init section
1530    to run __do_global_ctors, so we need not do anything here.  */
1531
1532 void
1533 SYMBOL__MAIN ()
1534 {
1535   /* Support recursive calls to `main': run initializers just once.  */
1536   static int initialized;
1537   if (! initialized)
1538     {
1539       initialized = 1;
1540       __do_global_ctors ();
1541     }
1542 }
1543 #endif /* no HAS_INIT_SECTION or INVOKE__main */
1544
1545 #endif /* L__main */
1546 #endif /* __CYGWIN__ */
1547 \f
1548 #ifdef L_ctors
1549
1550 #include "gbl-ctors.h"
1551
1552 /* Provide default definitions for the lists of constructors and
1553    destructors, so that we don't get linker errors.  These symbols are
1554    intentionally bss symbols, so that gld and/or collect will provide
1555    the right values.  */
1556
1557 /* We declare the lists here with two elements each,
1558    so that they are valid empty lists if no other definition is loaded.
1559
1560    If we are using the old "set" extensions to have the gnu linker
1561    collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
1562    must be in the bss/common section.
1563
1564    Long term no port should use those extensions.  But many still do.  */
1565 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
1566 #if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2)
1567 func_ptr __CTOR_LIST__[2] = {0, 0};
1568 func_ptr __DTOR_LIST__[2] = {0, 0};
1569 #else
1570 func_ptr __CTOR_LIST__[2];
1571 func_ptr __DTOR_LIST__[2];
1572 #endif
1573 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1574 #endif /* L_ctors */
1575 \f
1576 #ifdef L_exit
1577
1578 #include "gbl-ctors.h"
1579
1580 #ifdef NEED_ATEXIT
1581
1582 #ifndef ON_EXIT
1583
1584 # include <errno.h>
1585
1586 static func_ptr *atexit_chain = 0;
1587 static long atexit_chain_length = 0;
1588 static volatile long last_atexit_chain_slot = -1;
1589
1590 int
1591 atexit (func_ptr func)
1592 {
1593   if (++last_atexit_chain_slot == atexit_chain_length)
1594     {
1595       atexit_chain_length += 32;
1596       if (atexit_chain)
1597         atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
1598                                              * sizeof (func_ptr));
1599       else
1600         atexit_chain = (func_ptr *) malloc (atexit_chain_length
1601                                             * sizeof (func_ptr));
1602       if (! atexit_chain)
1603         {
1604           atexit_chain_length = 0;
1605           last_atexit_chain_slot = -1;
1606           errno = ENOMEM;
1607           return (-1);
1608         }
1609     }
1610   atexit_chain[last_atexit_chain_slot] = func;
1611   return (0);
1612 }
1613
1614 extern void _cleanup (void);
1615 extern void _exit (int) __attribute__ ((__noreturn__));
1616
1617 void
1618 exit (int status)
1619 {
1620   if (atexit_chain)
1621     {
1622       for ( ; last_atexit_chain_slot-- >= 0; )
1623         {
1624           (*atexit_chain[last_atexit_chain_slot + 1]) ();
1625           atexit_chain[last_atexit_chain_slot + 1] = 0;
1626         }
1627       free (atexit_chain);
1628       atexit_chain = 0;
1629     }
1630 #ifdef EXIT_BODY
1631   EXIT_BODY;
1632 #else
1633   _cleanup ();
1634 #endif
1635   _exit (status);
1636 }
1637
1638 #else /* ON_EXIT */
1639
1640 /* Simple; we just need a wrapper for ON_EXIT.  */
1641 int
1642 atexit (func_ptr func)
1643 {
1644   return ON_EXIT (func);
1645 }
1646
1647 #endif /* ON_EXIT */
1648 #endif /* NEED_ATEXIT */
1649
1650 #endif /* L_exit */