OSDN Git Service

(__builtin_new): Avoid passing 0 to malloc.
[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 Free Software Foundation, Inc.
4
5 This file is part of GNU CC.
6
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.
11
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.
16
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.  */
20
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.  */
26
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.  */
30
31 #include "tconfig.h"
32 #include "machmode.h"
33 #ifndef L_trampoline
34 #include "gstddef.h"
35 #endif
36
37 /* Don't use `fancy_abort' here even if config.h says to use it.  */
38 #ifdef abort
39 #undef abort
40 #endif
41
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.  */
50
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 0
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
64
65 /* Make sure that we don't accidentaly use any normal C language built-in
66    type names in the first part of this file.  Instead we want to use *only*
67    the type names defined above.  The following macro definitions insure
68    that if we *do* accidently use soem normal C language built-in type name,
69    we will get a syntax error.  */
70
71 #define char bogus_type
72 #define short bogus_type
73 #define int bogus_type
74 #define long bogus_type
75 #define unsigned bogus_type
76 #define float bogus_type
77 #define double bogus_type
78
79 #define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
80
81 /* DIstructs are pairs of SItype values in the order determined by
82    WORDS_BIG_ENDIAN.  */
83
84 #if WORDS_BIG_ENDIAN
85   struct DIstruct {SItype high, low;};
86 #else
87   struct DIstruct {SItype low, high;};
88 #endif
89
90 /* We need this union to unpack/pack DImode values, since we don't have
91    any arithmetic yet.  Incoming DImode parameters are stored into the
92    `ll' field, and the unpacked result is read from the struct `s'.  */
93
94 typedef union
95 {
96   struct DIstruct s;
97   DItype ll;
98 } DIunion;
99
100 #if defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_w_sdiv)
101
102 #include "longlong.h"
103
104 #endif /* udiv or mul */
105
106 extern DItype __fixunssfdi (SFtype a);
107 extern DItype __fixunsdfdi (DFtype a);
108 \f
109 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
110 #if defined (L_divdi3) || defined (L_moddi3)
111 static inline
112 #endif
113 DItype
114 __negdi2 (u)
115      DItype u;
116 {
117   DIunion w;
118   DIunion uu;
119
120   uu.ll = u;
121
122   w.s.low = -uu.s.low;
123   w.s.high = -uu.s.high - ((USItype) w.s.low > 0);
124
125   return w.ll;
126 }
127 #endif
128 \f
129 #ifdef L_lshldi3
130 DItype
131 __lshldi3 (u, b)
132      DItype u;
133      SItype b;
134 {
135   DIunion w;
136   SItype bm;
137   DIunion uu;
138
139   if (b == 0)
140     return u;
141
142   uu.ll = u;
143
144   bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
145   if (bm <= 0)
146     {
147       w.s.low = 0;
148       w.s.high = (USItype)uu.s.low << -bm;
149     }
150   else
151     {
152       USItype carries = (USItype)uu.s.low >> bm;
153       w.s.low = (USItype)uu.s.low << b;
154       w.s.high = ((USItype)uu.s.high << b) | carries;
155     }
156
157   return w.ll;
158 }
159 #endif
160
161 #ifdef L_lshrdi3
162 DItype
163 __lshrdi3 (u, b)
164      DItype u;
165      SItype b;
166 {
167   DIunion w;
168   SItype bm;
169   DIunion uu;
170
171   if (b == 0)
172     return u;
173
174   uu.ll = u;
175
176   bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
177   if (bm <= 0)
178     {
179       w.s.high = 0;
180       w.s.low = (USItype)uu.s.high >> -bm;
181     }
182   else
183     {
184       USItype carries = (USItype)uu.s.high << bm;
185       w.s.high = (USItype)uu.s.high >> b;
186       w.s.low = ((USItype)uu.s.low >> b) | carries;
187     }
188
189   return w.ll;
190 }
191 #endif
192
193 #ifdef L_ashldi3
194 DItype
195 __ashldi3 (u, b)
196      DItype u;
197      SItype b;
198 {
199   DIunion w;
200   SItype bm;
201   DIunion uu;
202
203   if (b == 0)
204     return u;
205
206   uu.ll = u;
207
208   bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
209   if (bm <= 0)
210     {
211       w.s.low = 0;
212       w.s.high = (USItype)uu.s.low << -bm;
213     }
214   else
215     {
216       USItype carries = (USItype)uu.s.low >> bm;
217       w.s.low = (USItype)uu.s.low << b;
218       w.s.high = ((USItype)uu.s.high << b) | carries;
219     }
220
221   return w.ll;
222 }
223 #endif
224
225 #ifdef L_ashrdi3
226 DItype
227 __ashrdi3 (u, b)
228      DItype u;
229      SItype b;
230 {
231   DIunion w;
232   SItype bm;
233   DIunion uu;
234
235   if (b == 0)
236     return u;
237
238   uu.ll = u;
239
240   bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
241   if (bm <= 0)
242     {
243       /* w.s.high = 1..1 or 0..0 */
244       w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
245       w.s.low = uu.s.high >> -bm;
246     }
247   else
248     {
249       USItype carries = (USItype)uu.s.high << bm;
250       w.s.high = uu.s.high >> b;
251       w.s.low = ((USItype)uu.s.low >> b) | carries;
252     }
253
254   return w.ll;
255 }
256 #endif
257 \f
258 #ifdef L_muldi3
259 DItype
260 __muldi3 (u, v)
261      DItype u, v;
262 {
263   DIunion w;
264   DIunion uu, vv;
265
266   uu.ll = u,
267   vv.ll = v;
268
269   w.ll = __umulsidi3 (uu.s.low, vv.s.low);
270   w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
271                + (USItype) uu.s.high * (USItype) vv.s.low);
272
273   return w.ll;
274 }
275 #endif
276 \f
277 #ifdef L_udiv_w_sdiv
278 USItype
279 __udiv_w_sdiv (rp, a1, a0, d)
280      USItype *rp, a1, a0, d;
281 {
282   USItype q, r;
283   USItype c0, c1, b1;
284
285   if ((SItype) d >= 0)
286     {
287       if (a1 < d - a1 - (a0 >> 31))
288         {
289           /* dividend, divisor, and quotient are nonnegative */
290           sdiv_qrnnd (q, r, a1, a0, d);
291         }
292       else
293         {
294           /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
295           sub_ddmmss (c1, c0, a1, a0, d >> 1, d << 31);
296           /* Divide (c1*2^32 + c0) by d */
297           sdiv_qrnnd (q, r, c1, c0, d);
298           /* Add 2^31 to quotient */
299           q += 1 << 31;
300         }
301     }
302   else
303     {
304       b1 = d >> 1;                      /* d/2, between 2^30 and 2^31 - 1 */
305       c1 = a1 >> 1;                     /* A/2 */
306       c0 = (a1 << 31) + (a0 >> 1);
307
308       if (a1 < b1)                      /* A < 2^32*b1, so A/2 < 2^31*b1 */
309         {
310           sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
311
312           r = 2*r + (a0 & 1);           /* Remainder from A/(2*b1) */
313           if ((d & 1) != 0)
314             {
315               if (r >= q)
316                 r = r - q;
317               else if (q - r <= d)
318                 {
319                   r = r - q + d;
320                   q--;
321                 }
322               else
323                 {
324                   r = r - q + 2*d;
325                   q -= 2;
326                 }
327             }
328         }
329       else if (c1 < b1)                 /* So 2^31 <= (A/2)/b1 < 2^32 */
330         {
331           c1 = (b1 - 1) - c1;
332           c0 = ~c0;                     /* logical NOT */
333
334           sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
335
336           q = ~q;                       /* (A/2)/b1 */
337           r = (b1 - 1) - r;
338
339           r = 2*r + (a0 & 1);           /* A/(2*b1) */
340
341           if ((d & 1) != 0)
342             {
343               if (r >= q)
344                 r = r - q;
345               else if (q - r <= d)
346                 {
347                   r = r - q + d;
348                   q--;
349                 }
350               else
351                 {
352                   r = r - q + 2*d;
353                   q -= 2;
354                 }
355             }
356         }
357       else                              /* Implies c1 = b1 */
358         {                               /* Hence a1 = d - 1 = 2*b1 - 1 */
359           if (a0 >= -d)
360             {
361               q = -1;
362               r = a0 + d;
363             }
364           else
365             {
366               q = -2;
367               r = a0 + 2*d;
368             }
369         }
370     }
371
372   *rp = r;
373   return q;
374 }
375 #endif
376 \f
377 #ifdef L_udivmoddi4
378 static const UQItype __clz_tab[] =
379 {
380   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,
381   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,
382   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,
383   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,
384   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,
385   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,
386   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,
387   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,
388 };
389
390 UDItype
391 __udivmoddi4 (n, d, rp)
392      UDItype n, d;
393      UDItype *rp;
394 {
395   DIunion ww;
396   DIunion nn, dd;
397   DIunion rr;
398   USItype d0, d1, n0, n1, n2;
399   USItype q0, q1;
400   USItype b, bm;
401
402   nn.ll = n;
403   dd.ll = d;
404
405   d0 = dd.s.low;
406   d1 = dd.s.high;
407   n0 = nn.s.low;
408   n1 = nn.s.high;
409
410 #if !UDIV_NEEDS_NORMALIZATION
411   if (d1 == 0)
412     {
413       if (d0 > n1)
414         {
415           /* 0q = nn / 0D */
416
417           udiv_qrnnd (q0, n0, n1, n0, d0);
418           q1 = 0;
419
420           /* Remainder in n0.  */
421         }
422       else
423         {
424           /* qq = NN / 0d */
425
426           if (d0 == 0)
427             d0 = 1 / d0;        /* Divide intentionally by zero.  */
428
429           udiv_qrnnd (q1, n1, 0, n1, d0);
430           udiv_qrnnd (q0, n0, n1, n0, d0);
431
432           /* Remainder in n0.  */
433         }
434
435       if (rp != 0)
436         {
437           rr.s.low = n0;
438           rr.s.high = 0;
439           *rp = rr.ll;
440         }
441     }
442
443 #else /* UDIV_NEEDS_NORMALIZATION */
444
445   if (d1 == 0)
446     {
447       if (d0 > n1)
448         {
449           /* 0q = nn / 0D */
450
451           count_leading_zeros (bm, d0);
452
453           if (bm != 0)
454             {
455               /* Normalize, i.e. make the most significant bit of the
456                  denominator set.  */
457
458               d0 = d0 << bm;
459               n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
460               n0 = n0 << bm;
461             }
462
463           udiv_qrnnd (q0, n0, n1, n0, d0);
464           q1 = 0;
465
466           /* Remainder in n0 >> bm.  */
467         }
468       else
469         {
470           /* qq = NN / 0d */
471
472           if (d0 == 0)
473             d0 = 1 / d0;        /* Divide intentionally by zero.  */
474
475           count_leading_zeros (bm, d0);
476
477           if (bm == 0)
478             {
479               /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
480                  conclude (the most significant bit of n1 is set) /\ (the
481                  leading quotient digit q1 = 1).
482
483                  This special case is necessary, not an optimization.
484                  (Shifts counts of SI_TYPE_SIZE are undefined.)  */
485
486               n1 -= d0;
487               q1 = 1;
488             }
489           else
490             {
491               /* Normalize.  */
492
493               b = SI_TYPE_SIZE - bm;
494
495               d0 = d0 << bm;
496               n2 = n1 >> b;
497               n1 = (n1 << bm) | (n0 >> b);
498               n0 = n0 << bm;
499
500               udiv_qrnnd (q1, n1, n2, n1, d0);
501             }
502
503           /* n1 != d0... */
504
505           udiv_qrnnd (q0, n0, n1, n0, d0);
506
507           /* Remainder in n0 >> bm.  */
508         }
509
510       if (rp != 0)
511         {
512           rr.s.low = n0 >> bm;
513           rr.s.high = 0;
514           *rp = rr.ll;
515         }
516     }
517 #endif /* UDIV_NEEDS_NORMALIZATION */
518
519   else
520     {
521       if (d1 > n1)
522         {
523           /* 00 = nn / DD */
524
525           q0 = 0;
526           q1 = 0;
527
528           /* Remainder in n1n0.  */
529           if (rp != 0)
530             {
531               rr.s.low = n0;
532               rr.s.high = n1;
533               *rp = rr.ll;
534             }
535         }
536       else
537         {
538           /* 0q = NN / dd */
539
540           count_leading_zeros (bm, d1);
541           if (bm == 0)
542             {
543               /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
544                  conclude (the most significant bit of n1 is set) /\ (the
545                  quotient digit q0 = 0 or 1).
546
547                  This special case is necessary, not an optimization.  */
548
549               /* The condition on the next line takes advantage of that
550                  n1 >= d1 (true due to program flow).  */
551               if (n1 > d1 || n0 >= d0)
552                 {
553                   q0 = 1;
554                   sub_ddmmss (n1, n0, n1, n0, d1, d0);
555                 }
556               else
557                 q0 = 0;
558
559               q1 = 0;
560
561               if (rp != 0)
562                 {
563                   rr.s.low = n0;
564                   rr.s.high = n1;
565                   *rp = rr.ll;
566                 }
567             }
568           else
569             {
570               USItype m1, m0;
571               /* Normalize.  */
572
573               b = SI_TYPE_SIZE - bm;
574
575               d1 = (d1 << bm) | (d0 >> b);
576               d0 = d0 << bm;
577               n2 = n1 >> b;
578               n1 = (n1 << bm) | (n0 >> b);
579               n0 = n0 << bm;
580
581               udiv_qrnnd (q0, n1, n2, n1, d1);
582               umul_ppmm (m1, m0, q0, d0);
583
584               if (m1 > n1 || (m1 == n1 && m0 > n0))
585                 {
586                   q0--;
587                   sub_ddmmss (m1, m0, m1, m0, d1, d0);
588                 }
589
590               q1 = 0;
591
592               /* Remainder in (n1n0 - m1m0) >> bm.  */
593               if (rp != 0)
594                 {
595                   sub_ddmmss (n1, n0, n1, n0, m1, m0);
596                   rr.s.low = (n1 << b) | (n0 >> bm);
597                   rr.s.high = n1 >> bm;
598                   *rp = rr.ll;
599                 }
600             }
601         }
602     }
603
604   ww.s.low = q0;
605   ww.s.high = q1;
606   return ww.ll;
607 }
608 #endif
609
610 #ifdef L_divdi3
611 UDItype __udivmoddi4 ();
612 DItype
613 __divdi3 (u, v)
614      DItype u, v;
615 {
616   SItype c = 0;
617   DIunion uu, vv;
618   DItype w;
619
620   uu.ll = u;
621   vv.ll = v;
622
623   if (uu.s.high < 0)
624     c = ~c,
625     uu.ll = __negdi2 (uu.ll);
626   if (vv.s.high < 0)
627     c = ~c,
628     vv.ll = __negdi2 (vv.ll);
629
630   w = __udivmoddi4 (uu.ll, vv.ll, (UDItype *) 0);
631   if (c)
632     w = __negdi2 (w);
633
634   return w;
635 }
636 #endif
637
638 #ifdef L_moddi3
639 UDItype __udivmoddi4 ();
640 DItype
641 __moddi3 (u, v)
642      DItype u, v;
643 {
644   SItype c = 0;
645   DIunion uu, vv;
646   DItype w;
647
648   uu.ll = u;
649   vv.ll = v;
650
651   if (uu.s.high < 0)
652     c = ~c,
653     uu.ll = __negdi2 (uu.ll);
654   if (vv.s.high < 0)
655     vv.ll = __negdi2 (vv.ll);
656
657   (void) __udivmoddi4 (uu.ll, vv.ll, &w);
658   if (c)
659     w = __negdi2 (w);
660
661   return w;
662 }
663 #endif
664
665 #ifdef L_umoddi3
666 UDItype __udivmoddi4 ();
667 UDItype
668 __umoddi3 (u, v)
669      UDItype u, v;
670 {
671   DItype w;
672
673   (void) __udivmoddi4 (u, v, &w);
674
675   return w;
676 }
677 #endif
678
679 #ifdef L_udivdi3
680 UDItype __udivmoddi4 ();
681 UDItype
682 __udivdi3 (n, d)
683      UDItype n, d;
684 {
685   return __udivmoddi4 (n, d, (UDItype *) 0);
686 }
687 #endif
688 \f
689 #ifdef L_cmpdi2
690 SItype
691 __cmpdi2 (a, b)
692      DItype a, b;
693 {
694   DIunion au, bu;
695
696   au.ll = a, bu.ll = b;
697
698   if (au.s.high < bu.s.high)
699     return 0;
700   else if (au.s.high > bu.s.high)
701     return 2;
702   if ((USItype) au.s.low < (USItype) bu.s.low)
703     return 0;
704   else if ((USItype) au.s.low > (USItype) bu.s.low)
705     return 2;
706   return 1;
707 }
708 #endif
709
710 #ifdef L_ucmpdi2
711 SItype
712 __ucmpdi2 (a, b)
713      DItype a, b;
714 {
715   DIunion au, bu;
716
717   au.ll = a, bu.ll = b;
718
719   if ((USItype) au.s.high < (USItype) bu.s.high)
720     return 0;
721   else if ((USItype) au.s.high > (USItype) bu.s.high)
722     return 2;
723   if ((USItype) au.s.low < (USItype) bu.s.low)
724     return 0;
725   else if ((USItype) au.s.low > (USItype) bu.s.low)
726     return 2;
727   return 1;
728 }
729 #endif
730 \f
731 #if defined(L_fixunstfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
732 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
733 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
734
735 DItype
736 __fixunstfdi (a)
737      TFtype a;
738 {
739   TFtype b;
740   UDItype v;
741
742   if (a < 0)
743     return 0;
744
745   /* Compute high word of result, as a flonum.  */
746   b = (a / HIGH_WORD_COEFF);
747   /* Convert that to fixed (but not to DItype!),
748      and shift it into the high word.  */
749   v = (USItype) b;
750   v <<= WORD_SIZE;
751   /* Remove high part from the TFtype, leaving the low part as flonum.  */
752   a -= (TFtype)v;
753   /* Convert that to fixed (but not to DItype!) and add it in.
754      Sometimes A comes out negative.  This is significant, since
755      A has more bits than a long int does.  */
756   if (a < 0)
757     v -= (USItype) (- a);
758   else
759     v += (USItype) a;
760   return v;
761 }
762 #endif
763
764 #if defined(L_fixtfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
765 DItype
766 __fixtfdi (a)
767      TFtype a;
768 {
769   if (a < 0)
770     return - __fixunstfdi (-a);
771   return __fixunstfdi (a);
772 }
773 #endif
774
775 #ifdef L_fixunsdfdi
776 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
777 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
778
779 DItype
780 __fixunsdfdi (a)
781      DFtype a;
782 {
783   DFtype b;
784   UDItype v;
785
786   if (a < 0)
787     return 0;
788
789   /* Compute high word of result, as a flonum.  */
790   b = (a / HIGH_WORD_COEFF);
791   /* Convert that to fixed (but not to DItype!),
792      and shift it into the high word.  */
793   v = (USItype) b;
794   v <<= WORD_SIZE;
795   /* Remove high part from the DFtype, leaving the low part as flonum.  */
796   a -= (DFtype)v;
797   /* Convert that to fixed (but not to DItype!) and add it in.
798      Sometimes A comes out negative.  This is significant, since
799      A has more bits than a long int does.  */
800   if (a < 0)
801     v -= (USItype) (- a);
802   else
803     v += (USItype) a;
804   return v;
805 }
806 #endif
807
808 #ifdef L_fixdfdi
809 DItype
810 __fixdfdi (a)
811      DFtype a;
812 {
813   if (a < 0)
814     return - __fixunsdfdi (-a);
815   return __fixunsdfdi (a);
816 }
817 #endif
818
819 #ifdef L_fixunssfdi
820 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
821 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
822
823 DItype
824 __fixunssfdi (SFtype original_a)
825 {
826   /* Convert the SFtype to a DFtype, because that is surely not going
827      to lose any bits.  Some day someone else can write a faster version
828      that avoids converting to DFtype, and verify it really works right.  */
829   DFtype a = original_a;
830   DFtype b;
831   UDItype v;
832
833   if (a < 0)
834     return 0;
835
836   /* Compute high word of result, as a flonum.  */
837   b = (a / HIGH_WORD_COEFF);
838   /* Convert that to fixed (but not to DItype!),
839      and shift it into the high word.  */
840   v = (USItype) b;
841   v <<= WORD_SIZE;
842   /* Remove high part from the DFtype, leaving the low part as flonum.  */
843   a -= (DFtype)v;
844   /* Convert that to fixed (but not to DItype!) and add it in.
845      Sometimes A comes out negative.  This is significant, since
846      A has more bits than a long int does.  */
847   if (a < 0)
848     v -= (USItype) (- a);
849   else
850     v += (USItype) a;
851   return v;
852 }
853 #endif
854
855 #ifdef L_fixsfdi
856 DItype
857 __fixsfdi (SFtype a)
858 {
859   if (a < 0)
860     return - __fixunssfdi (-a);
861   return __fixunssfdi (a);
862 }
863 #endif
864
865 #if defined(L_floatditf) && (LONG_DOUBLE_TYPE_SIZE == 128)
866 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
867 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
868 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
869
870 TFtype
871 __floatditf (u)
872      DItype u;
873 {
874   TFtype d;
875   SItype negate = 0;
876
877   if (u < 0)
878     u = -u, negate = 1;
879
880   d = (USItype) (u >> WORD_SIZE);
881   d *= HIGH_HALFWORD_COEFF;
882   d *= HIGH_HALFWORD_COEFF;
883   d += (USItype) (u & (HIGH_WORD_COEFF - 1));
884
885   return (negate ? -d : d);
886 }
887 #endif
888
889 #ifdef L_floatdidf
890 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
891 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
892 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
893
894 DFtype
895 __floatdidf (u)
896      DItype u;
897 {
898   DFtype d;
899   SItype negate = 0;
900
901   if (u < 0)
902     u = -u, negate = 1;
903
904   d = (USItype) (u >> WORD_SIZE);
905   d *= HIGH_HALFWORD_COEFF;
906   d *= HIGH_HALFWORD_COEFF;
907   d += (USItype) (u & (HIGH_WORD_COEFF - 1));
908
909   return (negate ? -d : d);
910 }
911 #endif
912
913 #ifdef L_floatdisf
914 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
915 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
916 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
917
918 SFtype
919 __floatdisf (u)
920      DItype u;
921 {
922   SFtype f;
923   SItype negate = 0;
924
925   if (u < 0)
926     u = -u, negate = 1;
927
928   f = (USItype) (u >> WORD_SIZE);
929   f *= HIGH_HALFWORD_COEFF;
930   f *= HIGH_HALFWORD_COEFF;
931   f += (USItype) (u & (HIGH_WORD_COEFF - 1));
932
933   return (negate ? -f : f);
934 }
935 #endif
936
937 #ifdef L_fixunsdfsi
938 #include "glimits.h"
939
940 USItype
941 __fixunsdfsi (a)
942      DFtype a;
943 {
944   if (a >= - (DFtype) LONG_MIN)
945     return (SItype) (a + LONG_MIN) - LONG_MIN;
946   return (SItype) a;
947 }
948 #endif
949
950 #ifdef L_fixunssfsi
951 #include "glimits.h"
952
953 USItype
954 __fixunssfsi (SFtype a)
955 {
956   if (a >= - (SFtype) LONG_MIN)
957     return (SItype) (a + LONG_MIN) - LONG_MIN;
958   return (SItype) a;
959 }
960 #endif
961 \f
962 /* From here on down, the routines use normal data types.  */
963
964 #define SItype bogus_type
965 #define USItype bogus_type
966 #define DItype bogus_type
967 #define UDItype bogus_type
968 #define SFtype bogus_type
969 #define DFtype bogus_type
970
971 #undef char
972 #undef short
973 #undef int
974 #undef long
975 #undef unsigned
976 #undef float
977 #undef double
978 \f
979 #ifdef L__gcc_bcmp
980
981 /* Like bcmp except the sign is meaningful.
982    Reult is negative if S1 is less than S2,
983    positive if S1 is greater, 0 if S1 and S2 are equal.  */
984
985 int
986 __gcc_bcmp (s1, s2, size)
987      char *s1, *s2;
988      size_t size;
989 {
990   while (size > 0)
991     {
992       char c1 = *s1++, c2 = *s2++;
993       if (c1 != c2)
994         return c1 - c2;
995       size--;
996     }
997   return 0;
998 }
999
1000 #endif
1001 \f\f
1002 #ifdef L_varargs
1003 #ifdef __i860__
1004 #if defined(__svr4__) || defined(__alliant__)
1005         asm ("  .text");
1006         asm ("  .align  4");
1007
1008 /* The Alliant needs the added underscore.  */
1009         asm (".globl    __builtin_saveregs");
1010 asm ("__builtin_saveregs:");
1011         asm (".globl    ___builtin_saveregs");
1012 asm ("___builtin_saveregs:");
1013
1014         asm ("  andnot  0x0f,%sp,%sp"); /* round down to 16-byte boundary */
1015         asm ("  adds    -96,%sp,%sp");  /* allocate stack space for reg save
1016                                            area and also for a new va_list
1017                                            structure */
1018         /* Save all argument registers in the arg reg save area.  The
1019            arg reg save area must have the following layout (according
1020            to the svr4 ABI):
1021
1022                 struct {
1023                   union  {
1024                     float freg[8];
1025                     double dreg[4];
1026                   } float_regs;
1027                   long  ireg[12];
1028                 };
1029         */
1030
1031         asm ("  fst.q   %f8,  0(%sp)"); /* save floating regs (f8-f15)  */
1032         asm ("  fst.q   %f12,16(%sp)"); 
1033
1034         asm ("  st.l    %r16,32(%sp)"); /* save integer regs (r16-r27) */
1035         asm ("  st.l    %r17,36(%sp)"); 
1036         asm ("  st.l    %r18,40(%sp)");
1037         asm ("  st.l    %r19,44(%sp)");
1038         asm ("  st.l    %r20,48(%sp)");
1039         asm ("  st.l    %r21,52(%sp)");
1040         asm ("  st.l    %r22,56(%sp)");
1041         asm ("  st.l    %r23,60(%sp)");
1042         asm ("  st.l    %r24,64(%sp)");
1043         asm ("  st.l    %r25,68(%sp)");
1044         asm ("  st.l    %r26,72(%sp)");
1045         asm ("  st.l    %r27,76(%sp)");
1046
1047         asm ("  adds    80,%sp,%r16");  /* compute the address of the new
1048                                            va_list structure.  Put in into
1049                                            r16 so that it will be returned
1050                                            to the caller.  */
1051
1052         /* Initialize all fields of the new va_list structure.  This
1053            structure looks like:
1054
1055                 typedef struct {
1056                     unsigned long       ireg_used;
1057                     unsigned long       freg_used;
1058                     long                *reg_base;
1059                     long                *mem_ptr;
1060                 } va_list;
1061         */
1062
1063         asm ("  st.l    %r0, 0(%r16)"); /* nfixed */
1064         asm ("  st.l    %r0, 4(%r16)"); /* nfloating */
1065         asm ("  st.l    %sp, 8(%r16)"); /* __va_ctl points to __va_struct.  */
1066         asm ("  bri     %r1");          /* delayed return */
1067         asm ("  st.l    %r28,12(%r16)"); /* pointer to overflow args */
1068
1069 #else /* not __SVR4__ */
1070         asm ("  .text");
1071         asm ("  .align  4");
1072
1073         asm (".globl    ___builtin_saveregs");
1074         asm ("___builtin_saveregs:");
1075         asm ("  mov     sp,r30");
1076         asm ("  andnot  0x0f,sp,sp");
1077         asm ("  adds    -96,sp,sp");  /* allocate sufficient space on the stack */
1078
1079 /* Fill in the __va_struct.  */
1080         asm ("  st.l    r16, 0(sp)"); /* save integer regs (r16-r27) */
1081         asm ("  st.l    r17, 4(sp)"); /* int    fixed[12] */
1082         asm ("  st.l    r18, 8(sp)");
1083         asm ("  st.l    r19,12(sp)");
1084         asm ("  st.l    r20,16(sp)");
1085         asm ("  st.l    r21,20(sp)");
1086         asm ("  st.l    r22,24(sp)");
1087         asm ("  st.l    r23,28(sp)");
1088         asm ("  st.l    r24,32(sp)");
1089         asm ("  st.l    r25,36(sp)");
1090         asm ("  st.l    r26,40(sp)");
1091         asm ("  st.l    r27,44(sp)");
1092
1093         asm ("  fst.q   f8, 48(sp)"); /* save floating regs (f8-f15) */
1094         asm ("  fst.q   f12,64(sp)"); /* int floating[8] */
1095
1096 /* Fill in the __va_ctl.  */
1097         asm ("  st.l    sp, 80(sp)"); /* __va_ctl points to __va_struct.  */
1098         asm ("  st.l    r28,84(sp)"); /* pointer to more args */
1099         asm ("  st.l    r0, 88(sp)"); /* nfixed */
1100         asm ("  st.l    r0, 92(sp)"); /* nfloating */
1101
1102         asm ("  adds    80,sp,r16");  /* return address of the __va_ctl.  */
1103         asm ("  bri     r1");
1104         asm ("  mov     r30,sp");
1105                                 /* recover stack and pass address to start 
1106                                    of data.  */
1107 #endif /* not __SVR4__ */
1108 #else /* not __i860__ */
1109 #ifdef __sparc__
1110         asm (".global __builtin_saveregs");
1111         asm ("__builtin_saveregs:");
1112         asm (".global ___builtin_saveregs");
1113         asm ("___builtin_saveregs:");
1114 #ifdef NEED_PROC_COMMAND
1115         asm (".proc 020");
1116 #endif
1117         asm ("st %i0,[%fp+68]");
1118         asm ("st %i1,[%fp+72]");
1119         asm ("st %i2,[%fp+76]");
1120         asm ("st %i3,[%fp+80]");
1121         asm ("st %i4,[%fp+84]");
1122         asm ("retl");
1123         asm ("st %i5,[%fp+88]");
1124 #ifdef NEED_TYPE_COMMAND
1125         asm (".type __builtin_saveregs,#function");
1126         asm (".size __builtin_saveregs,.-__builtin_saveregs");
1127 #endif
1128 #else /* not __sparc__ */
1129 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1130
1131   asm ("        .text");
1132   asm ("        .ent __builtin_saveregs");
1133   asm ("        .globl __builtin_saveregs");
1134   asm ("__builtin_saveregs:");
1135   asm ("        sw      $4,0($30)");
1136   asm ("        sw      $5,4($30)");
1137   asm ("        sw      $6,8($30)");
1138   asm ("        sw      $7,12($30)");
1139   asm ("        j       $31");
1140   asm ("        .end __builtin_saveregs");
1141 #else /* not __mips__, etc. */
1142 __builtin_saveregs ()
1143 {
1144   abort ();
1145 }
1146 #endif /* not __mips__ */
1147 #endif /* not __sparc__ */
1148 #endif /* not __i860__ */
1149 #endif
1150 \f
1151 #ifdef L_eprintf
1152 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1153 #include <stdio.h>
1154 /* This is used by the `assert' macro.  */
1155 void
1156 __eprintf (string, expression, line, filename)
1157      const char *string;
1158      const char *expression;
1159      int line;
1160      const char *filename;
1161 {
1162   fprintf (stderr, string, expression, line, filename);
1163   fflush (stderr);
1164   abort ();
1165 }
1166 #endif
1167
1168 #ifdef L_bb
1169 /* Avoid warning from ranlib about empty object file.  */
1170 void
1171 __bb_avoid_warning ()
1172 {}
1173
1174 #if defined (__sun__) && defined (__mc68000__)
1175 struct bb
1176 {
1177   int initialized;
1178   char *filename;
1179   int *counts;
1180   int ncounts;
1181   int zero_word;
1182   int *addresses;
1183 };
1184
1185 extern int ___tcov_init;
1186
1187 __bb_init_func (blocks)
1188         struct bb *blocks;
1189 {
1190   if (! ___tcov_init)
1191     ___tcov_init_func ();
1192
1193   ___bb_link (blocks->filename, blocks->counts, blocks->ncounts);
1194 }
1195
1196 #endif
1197 #endif
1198 \f
1199 /* frills for C++ */
1200
1201 #ifdef L_builtin_new
1202 typedef void (*vfp)(void);
1203
1204 extern vfp __new_handler;
1205
1206 void *
1207 __builtin_new (sz)
1208      size_t sz;
1209 {
1210   void *p;
1211
1212   /* malloc (0) is unpredictable; avoid it.  */
1213   if (sz == 0)
1214     sz = 1;
1215   p = (void *) malloc (sz);
1216   if (p == 0)
1217     (*__new_handler) ();
1218   return p;
1219 }
1220 #endif
1221
1222 #ifdef L_caps_New
1223 typedef void (*vfp)(void);
1224
1225 extern void *__builtin_new (size_t);
1226 static void default_new_handler (void);
1227
1228 vfp __new_handler = default_new_handler;
1229
1230 void *
1231 __builtin_vec_new (p, maxindex, size, ctor)
1232      void *p;
1233      size_t maxindex;
1234      size_t size;
1235      void (*ctor)(void *);
1236 {
1237   size_t i;
1238   size_t nelts = maxindex + 1;
1239   void *rval;
1240
1241   if (p == 0)
1242     p = __builtin_new (nelts * size);
1243
1244   rval = p;
1245
1246   for (i = 0; i < nelts; i++)
1247     {
1248       (*ctor) (p);
1249       p += size;
1250     }
1251
1252   return rval;
1253 }
1254
1255 vfp
1256 __set_new_handler (handler)
1257      vfp handler;
1258 {
1259   vfp prev_handler;
1260
1261   prev_handler = __new_handler;
1262   if (handler == 0) handler = default_new_handler;
1263   __new_handler = handler;
1264   return prev_handler;
1265 }
1266
1267 vfp
1268 set_new_handler (handler)
1269      vfp handler;
1270 {
1271   return __set_new_handler (handler);
1272 }
1273
1274 #define MESSAGE "Virtual memory exceeded in `new'\n"
1275
1276 static void
1277 default_new_handler ()
1278 {
1279   /* don't use fprintf (stderr, ...) because it may need to call malloc.  */
1280   /* This should really print the name of the program, but that is hard to
1281      do.  We need a standard, clean way to get at the name.  */
1282   write (2, MESSAGE, sizeof (MESSAGE));
1283   /* don't call exit () because that may call global destructors which
1284      may cause a loop.  */
1285   _exit (-1);
1286 }
1287 #endif
1288 \f
1289 #ifdef L_builtin_del
1290 typedef void (*vfp)(void);
1291
1292 void
1293 __builtin_delete (ptr)
1294      void *ptr;
1295 {
1296   if (ptr)
1297     free (ptr);
1298 }
1299
1300 void
1301 __builtin_vec_delete (ptr, maxindex, size, dtor, auto_delete_vec, auto_delete)
1302      void *ptr;
1303      size_t maxindex;
1304      size_t size;
1305      void (*dtor)(void *, int);
1306      int auto_delete;
1307 {
1308   size_t i;
1309   size_t nelts = maxindex + 1;
1310   void *p = ptr;
1311
1312   ptr += nelts * size;
1313
1314   for (i = 0; i < nelts; i++)
1315     {
1316       ptr -= size;
1317       (*dtor) (ptr, auto_delete);
1318     }
1319
1320   if (auto_delete_vec)
1321     __builtin_delete (p);
1322 }
1323
1324 #endif
1325
1326 #ifdef L_shtab
1327 unsigned int __shtab[] = {
1328     0x00000001, 0x00000002, 0x00000004, 0x00000008,
1329     0x00000010, 0x00000020, 0x00000040, 0x00000080,
1330     0x00000100, 0x00000200, 0x00000400, 0x00000800,
1331     0x00001000, 0x00002000, 0x00004000, 0x00008000,
1332     0x00010000, 0x00020000, 0x00040000, 0x00080000,
1333     0x00100000, 0x00200000, 0x00400000, 0x00800000,
1334     0x01000000, 0x02000000, 0x04000000, 0x08000000,
1335     0x10000000, 0x20000000, 0x40000000, 0x80000000
1336   };
1337 #endif
1338 \f
1339 #ifdef L_clear_cache
1340 /* Clear part of an instruction cache.  */
1341
1342 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1343
1344 void
1345 __clear_cache (beg, end)
1346      char *beg, *end;
1347 {
1348 #ifdef INSN_CACHE_SIZE
1349   static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1350   static int initialized = 0;
1351   int offset;
1352   void *start_addr
1353   void *end_addr;
1354   typedef (*function_ptr) ();
1355
1356 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1357   /* It's cheaper to clear the whole cache.
1358      Put in a series of jump instructions so that calling the beginning
1359      of the cache will clear the whole thing.  */
1360
1361   if (! initialized)
1362     {
1363       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1364                  & -INSN_CACHE_LINE_WIDTH);
1365       int end_ptr = ptr + INSN_CACHE_SIZE;
1366
1367       while (ptr < end_ptr)
1368         {
1369           *(INSTRUCTION_TYPE *)ptr
1370             = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1371           ptr += INSN_CACHE_LINE_WIDTH;
1372         }
1373       *(INSTRUCTION_TYPE *)(ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1374
1375       initialized = 1;
1376     }
1377
1378   /* Call the beginning of the sequence.  */
1379   (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1380                     & -INSN_CACHE_LINE_WIDTH))
1381    ());
1382
1383 #else /* Cache is large.  */
1384
1385   if (! initialized)
1386     {
1387       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1388                  & -INSN_CACHE_LINE_WIDTH);
1389
1390       while (ptr < (int) array + sizeof array)
1391         {
1392           *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1393           ptr += INSN_CACHE_LINE_WIDTH;
1394         }
1395
1396       initialized = 1;
1397     }
1398
1399   /* Find the location in array that occupies the same cache line as BEG.  */
1400
1401   offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1402   start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1403                  & -INSN_CACHE_PLANE_SIZE)
1404                 + offset);
1405
1406   /* Compute the cache alignment of the place to stop clearing.  */
1407 #if 0  /* This is not needed for gcc's purposes.  */
1408   /* If the block to clear is bigger than a cache plane,
1409      we clear the entire cache, and OFFSET is already correct.  */ 
1410   if (end < beg + INSN_CACHE_PLANE_SIZE)
1411 #endif
1412     offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1413                & -INSN_CACHE_LINE_WIDTH)
1414               & (INSN_CACHE_PLANE_SIZE - 1));
1415
1416 #if INSN_CACHE_DEPTH > 1
1417   end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1418   if (end_addr <= start_addr)
1419     end_addr += INSN_CACHE_PLANE_SIZE;
1420
1421   for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1422     {
1423       int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1424       int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1425
1426       while (addr != stop)
1427         {
1428           /* Call the return instruction at ADDR.  */
1429           ((function_ptr) addr) ();
1430
1431           addr += INSN_CACHE_LINE_WIDTH;
1432         }
1433     }
1434 #else /* just one plane */
1435   do
1436     {
1437       /* Call the return instruction at START_ADDR.  */
1438       ((function_ptr) start_addr) ();
1439
1440       start_addr += INSN_CACHE_LINE_WIDTH;
1441     }
1442   while ((start_addr % INSN_CACHE_SIZE) != offset);
1443 #endif /* just one plane */
1444 #endif /* Cache is large */
1445 #endif /* Cache exists */
1446 }
1447
1448 #endif /* L_clear_cache */
1449 \f
1450 #ifdef L_trampoline
1451
1452 /* Jump to a trampoline, loading the static chain address.  */
1453
1454 #ifdef TRANSFER_FROM_TRAMPOLINE 
1455 TRANSFER_FROM_TRAMPOLINE 
1456 #endif
1457
1458 #ifdef __convex__
1459
1460 /* Make stack executable so we can call trampolines on stack.
1461    This is called from INITIALIZE_TRAMPOLINE in convex.h.  */
1462
1463 #include <sys/mman.h>
1464 #include <sys/vmparam.h>
1465 #include <machine/machparam.h>
1466
1467 void
1468 __enable_execute_stack ()
1469 {
1470   int fp;
1471   static unsigned lowest = USRSTACK;
1472   unsigned current = (unsigned) &fp & -NBPG;
1473
1474   if (lowest > current)
1475     {
1476       unsigned len = lowest - current;
1477       mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
1478       lowest = current;
1479     }
1480
1481   /* Clear instruction cache in case an old trampoline is in it. */
1482   asm ("pich");
1483 }
1484 #endif /* __convex__ */
1485
1486 #ifdef __pyr__
1487
1488 #include <stdio.h>
1489 #include <sys/mman.h>
1490 #include <sys/types.h>
1491 #include <sys/param.h>
1492 #include <sys/vmmac.h>
1493
1494 /* Modified from the convex -code above.
1495    mremap promises to clear the i-cache. */
1496
1497 void
1498 __enable_execute_stack ()
1499 {
1500   int fp;
1501   if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
1502                 PROT_READ|PROT_WRITE|PROT_EXEC))
1503     {
1504       perror ("mprotect in __enable_execute_stack");
1505       fflush (stderr);
1506       abort ();
1507     }
1508 }
1509 #endif /* __pyr__ */
1510 #endif /* L_trampoline */
1511 \f
1512 #ifdef L__main
1513
1514 #include "gbl-ctors.h"
1515
1516 /* Run all the global destructors on exit from the program.  */
1517
1518 void
1519 __do_global_dtors ()
1520 {
1521 #ifdef DO_GLOBAL_DTORS_BODY
1522   DO_GLOBAL_DTORS_BODY;
1523 #else
1524   unsigned nptrs = (unsigned HOST_WIDE_INT) __DTOR_LIST__[0];
1525   unsigned i;
1526
1527   /* Some systems place the number of pointers
1528      in the first word of the table.
1529      On other systems, that word is -1.
1530      In all cases, the table is null-terminated.  */
1531
1532   /* If the length is not recorded, count up to the null.  */
1533   if (nptrs == -1)
1534     for (nptrs = 0; __DTOR_LIST__[nptrs + 1] != 0; nptrs++);
1535
1536   /* GNU LD format.  */
1537   for (i = nptrs; i >= 1; i--)
1538     __DTOR_LIST__[i] ();
1539 #endif
1540 }
1541
1542 #ifndef INIT_SECTION_ASM_OP
1543 /* Run all the global constructors on entry to the program.  */
1544
1545 #ifndef ON_EXIT
1546 #define ON_EXIT(a, b)
1547 #else
1548 /* Make sure the exit routine is pulled in to define the globals as
1549    bss symbols, just in case the linker does not automatically pull
1550    bss definitions from the library.  */
1551
1552 extern int _exit_dummy_decl;
1553 int *_exit_dummy_ref = &_exit_dummy_decl;
1554 #endif /* ON_EXIT */
1555
1556 void
1557 __do_global_ctors ()
1558 {
1559   DO_GLOBAL_CTORS_BODY;
1560   ON_EXIT (__do_global_dtors, 0);
1561 }
1562 #endif /* no INIT_SECTION_ASM_OP */
1563
1564 #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
1565 /* Subroutine called automatically by `main'.
1566    Compiling a global function named `main'
1567    produces an automatic call to this function at the beginning.
1568
1569    For many systems, this routine calls __do_global_ctors.
1570    For systems which support a .init section we use the .init section
1571    to run __do_global_ctors, so we need not do anything here.  */
1572
1573 void
1574 __main ()
1575 {
1576   /* Support recursive calls to `main': run initializers just once.  */
1577   static int initialized = 0;
1578   if (! initialized)
1579     {
1580       initialized = 1;
1581       __do_global_ctors ();
1582     }
1583 }
1584 #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
1585
1586 #endif /* L__main */
1587 \f
1588 #ifdef L_ctors
1589
1590 #include "gbl-ctors.h"
1591
1592 /* Provide default definitions for the lists of constructors and
1593    destructors, so that we don't get linker errors.  These symbols are
1594    intentionally bss symbols, so that gld and/or collect will provide
1595    the right values.  */
1596
1597 /* We declare the lists here with two elements each,
1598    so that they are valid empty lists if no other definition is loaded.  */
1599 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
1600 func_ptr __CTOR_LIST__[2];
1601 func_ptr __DTOR_LIST__[2];
1602 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1603 #endif /* L_ctors */
1604 \f
1605 #ifdef L_exit
1606
1607 #include "gbl-ctors.h"
1608
1609 #ifndef ON_EXIT
1610
1611 /* If we have no known way of registering our own __do_global_dtors
1612    routine so that it will be invoked at program exit time, then we
1613    have to define our own exit routine which will get this to happen.  */
1614
1615 extern void __do_global_dtors ();
1616 extern void _cleanup ();
1617 extern volatile void _exit ();
1618
1619 void 
1620 exit (status)
1621      int status;
1622 {
1623   __do_global_dtors ();
1624 #ifdef EXIT_BODY
1625   EXIT_BODY;
1626 #else
1627   _cleanup ();
1628 #endif
1629   _exit (status);
1630 }
1631
1632 #else
1633 int _exit_dummy_decl = 0;       /* prevent compiler & linker warnings */
1634 #endif
1635
1636 #endif /* L_exit */
1637 \f
1638 /* In a.out systems, we need to have these dummy constructor and destructor
1639    lists in the library.
1640
1641    When using `collect', the first link will resolve __CTOR_LIST__
1642    and __DTOR_LIST__ to these symbols.  We will then run "nm" on the
1643    result, build the correct __CTOR_LIST__ and __DTOR_LIST__, and relink.
1644    Since we don't do the second link if no constructors existed, these
1645    dummies must be fully functional empty lists.
1646
1647    When using `gnu ld', these symbols will be used if there are no
1648    constructors.  If there are constructors, the N_SETV symbol defined
1649    by the linker from the N_SETT's in input files will define __CTOR_LIST__
1650    and __DTOR_LIST__ rather than its being allocated as common storage
1651    by the definitions below.
1652
1653    When using a linker that supports constructor and destructor segments,
1654    these definitions will not be used, since crtbegin.o and crtend.o
1655    (from crtstuff.c) will have already defined __CTOR_LIST__ and
1656     __DTOR_LIST__.  The crt*.o files are passed directly to the linker
1657    on its command line, by gcc.  */
1658
1659 /* The list needs two elements:  one is ignored (the old count); the
1660    second is the terminating zero.  Since both values are zero, this
1661    declaration is not initialized, and it becomes `common'.  */
1662
1663 #ifdef L_ctor_list
1664 #include "gbl-ctors.h"
1665 func_ptr __CTOR_LIST__[2];
1666 #endif
1667
1668 #ifdef L_dtor_list
1669 #include "gbl-ctors.h"
1670 func_ptr __DTOR_LIST__[2];
1671 #endif