OSDN Git Service

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