OSDN Git Service

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