OSDN Git Service

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