OSDN Git Service

(cmpdi2, ucmpdi2): comparison result type is now word_mode.
[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_eprintf
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 /* This gets us __GNU_LIBRARY__.  */
1260 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1261 #include <stdio.h>
1262
1263 #ifdef __GNU_LIBRARY__
1264   /* Avoid forcing the library's meaning of `write' on the user program
1265      by using the "internal" name (for use within the library)  */
1266 #define write(fd, buf, n)       __write((fd), (buf), (n))
1267 #endif
1268
1269 typedef void (*vfp)(void);
1270
1271 extern void *__builtin_new (size_t);
1272 static void default_new_handler (void);
1273
1274 vfp __new_handler = default_new_handler;
1275
1276 vfp
1277 __set_new_handler (handler)
1278      vfp handler;
1279 {
1280   vfp prev_handler;
1281
1282   prev_handler = __new_handler;
1283   if (handler == 0) handler = default_new_handler;
1284   __new_handler = handler;
1285   return prev_handler;
1286 }
1287
1288 vfp
1289 set_new_handler (handler)
1290      vfp handler;
1291 {
1292   return __set_new_handler (handler);
1293 }
1294
1295 #define MESSAGE "Virtual memory exceeded in `new'\n"
1296
1297 static void
1298 default_new_handler ()
1299 {
1300   /* don't use fprintf (stderr, ...) because it may need to call malloc.  */
1301   /* This should really print the name of the program, but that is hard to
1302      do.  We need a standard, clean way to get at the name.  */
1303   write (2, MESSAGE, sizeof (MESSAGE));
1304   /* don't call exit () because that may call global destructors which
1305      may cause a loop.  */
1306   _exit (-1);
1307 }
1308 #endif
1309
1310 #ifdef L_op_delete
1311 /* void operator delete (void *ptr) */
1312 void
1313 __builtin_delete (void *ptr)
1314 {
1315   if (ptr)
1316     free (ptr);
1317 }
1318 #endif
1319 \f
1320 #ifdef L_shtab
1321 unsigned int __shtab[] = {
1322     0x00000001, 0x00000002, 0x00000004, 0x00000008,
1323     0x00000010, 0x00000020, 0x00000040, 0x00000080,
1324     0x00000100, 0x00000200, 0x00000400, 0x00000800,
1325     0x00001000, 0x00002000, 0x00004000, 0x00008000,
1326     0x00010000, 0x00020000, 0x00040000, 0x00080000,
1327     0x00100000, 0x00200000, 0x00400000, 0x00800000,
1328     0x01000000, 0x02000000, 0x04000000, 0x08000000,
1329     0x10000000, 0x20000000, 0x40000000, 0x80000000
1330   };
1331 #endif
1332 \f
1333 #ifdef L_clear_cache
1334 /* Clear part of an instruction cache.  */
1335
1336 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1337
1338 void
1339 __clear_cache (beg, end)
1340      char *beg, *end;
1341 {
1342 #ifdef INSN_CACHE_SIZE
1343   static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1344   static int initialized = 0;
1345   int offset;
1346   void *start_addr
1347   void *end_addr;
1348   typedef (*function_ptr) ();
1349
1350 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1351   /* It's cheaper to clear the whole cache.
1352      Put in a series of jump instructions so that calling the beginning
1353      of the cache will clear the whole thing.  */
1354
1355   if (! initialized)
1356     {
1357       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1358                  & -INSN_CACHE_LINE_WIDTH);
1359       int end_ptr = ptr + INSN_CACHE_SIZE;
1360
1361       while (ptr < end_ptr)
1362         {
1363           *(INSTRUCTION_TYPE *)ptr
1364             = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1365           ptr += INSN_CACHE_LINE_WIDTH;
1366         }
1367       *(INSTRUCTION_TYPE *)(ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1368
1369       initialized = 1;
1370     }
1371
1372   /* Call the beginning of the sequence.  */
1373   (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1374                     & -INSN_CACHE_LINE_WIDTH))
1375    ());
1376
1377 #else /* Cache is large.  */
1378
1379   if (! initialized)
1380     {
1381       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1382                  & -INSN_CACHE_LINE_WIDTH);
1383
1384       while (ptr < (int) array + sizeof array)
1385         {
1386           *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1387           ptr += INSN_CACHE_LINE_WIDTH;
1388         }
1389
1390       initialized = 1;
1391     }
1392
1393   /* Find the location in array that occupies the same cache line as BEG.  */
1394
1395   offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1396   start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1397                  & -INSN_CACHE_PLANE_SIZE)
1398                 + offset);
1399
1400   /* Compute the cache alignment of the place to stop clearing.  */
1401 #if 0  /* This is not needed for gcc's purposes.  */
1402   /* If the block to clear is bigger than a cache plane,
1403      we clear the entire cache, and OFFSET is already correct.  */ 
1404   if (end < beg + INSN_CACHE_PLANE_SIZE)
1405 #endif
1406     offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1407                & -INSN_CACHE_LINE_WIDTH)
1408               & (INSN_CACHE_PLANE_SIZE - 1));
1409
1410 #if INSN_CACHE_DEPTH > 1
1411   end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1412   if (end_addr <= start_addr)
1413     end_addr += INSN_CACHE_PLANE_SIZE;
1414
1415   for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1416     {
1417       int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1418       int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1419
1420       while (addr != stop)
1421         {
1422           /* Call the return instruction at ADDR.  */
1423           ((function_ptr) addr) ();
1424
1425           addr += INSN_CACHE_LINE_WIDTH;
1426         }
1427     }
1428 #else /* just one plane */
1429   do
1430     {
1431       /* Call the return instruction at START_ADDR.  */
1432       ((function_ptr) start_addr) ();
1433
1434       start_addr += INSN_CACHE_LINE_WIDTH;
1435     }
1436   while ((start_addr % INSN_CACHE_SIZE) != offset);
1437 #endif /* just one plane */
1438 #endif /* Cache is large */
1439 #endif /* Cache exists */
1440 }
1441
1442 #endif /* L_clear_cache */
1443 \f
1444 #ifdef L_trampoline
1445
1446 /* Jump to a trampoline, loading the static chain address.  */
1447
1448 #ifdef TRANSFER_FROM_TRAMPOLINE 
1449 TRANSFER_FROM_TRAMPOLINE 
1450 #endif
1451
1452 #ifdef __convex__
1453
1454 /* Make stack executable so we can call trampolines on stack.
1455    This is called from INITIALIZE_TRAMPOLINE in convex.h.  */
1456
1457 #include <sys/mman.h>
1458 #include <sys/vmparam.h>
1459 #include <machine/machparam.h>
1460
1461 void
1462 __enable_execute_stack ()
1463 {
1464   int fp;
1465   static unsigned lowest = USRSTACK;
1466   unsigned current = (unsigned) &fp & -NBPG;
1467
1468   if (lowest > current)
1469     {
1470       unsigned len = lowest - current;
1471       mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
1472       lowest = current;
1473     }
1474
1475   /* Clear instruction cache in case an old trampoline is in it. */
1476   asm ("pich");
1477 }
1478 #endif /* __convex__ */
1479
1480 #ifdef __pyr__
1481
1482 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1483 #include <stdio.h>
1484 #include <sys/mman.h>
1485 #include <sys/types.h>
1486 #include <sys/param.h>
1487 #include <sys/vmmac.h>
1488
1489 /* Modified from the convex -code above.
1490    mremap promises to clear the i-cache. */
1491
1492 void
1493 __enable_execute_stack ()
1494 {
1495   int fp;
1496   if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
1497                 PROT_READ|PROT_WRITE|PROT_EXEC))
1498     {
1499       perror ("mprotect in __enable_execute_stack");
1500       fflush (stderr);
1501       abort ();
1502     }
1503 }
1504 #endif /* __pyr__ */
1505 #endif /* L_trampoline */
1506 \f
1507 #ifdef L__main
1508
1509 #include "gbl-ctors.h"
1510
1511 /* Run all the global destructors on exit from the program.  */
1512
1513 void
1514 __do_global_dtors ()
1515 {
1516 #ifdef DO_GLOBAL_DTORS_BODY
1517   DO_GLOBAL_DTORS_BODY;
1518 #else
1519   unsigned nptrs = (unsigned HOST_WIDE_INT) __DTOR_LIST__[0];
1520   unsigned i;
1521
1522   /* Some systems place the number of pointers
1523      in the first word of the table.
1524      On other systems, that word is -1.
1525      In all cases, the table is null-terminated.  */
1526
1527   /* If the length is not recorded, count up to the null.  */
1528   if (nptrs == -1)
1529     for (nptrs = 0; __DTOR_LIST__[nptrs + 1] != 0; nptrs++);
1530
1531   /* GNU LD format.  */
1532   for (i = nptrs; i >= 1; i--)
1533     __DTOR_LIST__[i] ();
1534 #endif
1535 }
1536
1537 #ifndef INIT_SECTION_ASM_OP
1538 /* Run all the global constructors on entry to the program.  */
1539
1540 #ifndef ON_EXIT
1541 #define ON_EXIT(a, b)
1542 #else
1543 /* Make sure the exit routine is pulled in to define the globals as
1544    bss symbols, just in case the linker does not automatically pull
1545    bss definitions from the library.  */
1546
1547 extern int _exit_dummy_decl;
1548 int *_exit_dummy_ref = &_exit_dummy_decl;
1549 #endif /* ON_EXIT */
1550
1551 void
1552 __do_global_ctors ()
1553 {
1554   DO_GLOBAL_CTORS_BODY;
1555   ON_EXIT (__do_global_dtors, 0);
1556 }
1557 #endif /* no INIT_SECTION_ASM_OP */
1558
1559 #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
1560 /* Subroutine called automatically by `main'.
1561    Compiling a global function named `main'
1562    produces an automatic call to this function at the beginning.
1563
1564    For many systems, this routine calls __do_global_ctors.
1565    For systems which support a .init section we use the .init section
1566    to run __do_global_ctors, so we need not do anything here.  */
1567
1568 void
1569 __main ()
1570 {
1571   /* Support recursive calls to `main': run initializers just once.  */
1572   static int initialized = 0;
1573   if (! initialized)
1574     {
1575       initialized = 1;
1576       __do_global_ctors ();
1577     }
1578 }
1579 #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
1580
1581 #endif /* L__main */
1582 \f
1583 #ifdef L_ctors
1584
1585 #include "gbl-ctors.h"
1586
1587 /* Provide default definitions for the lists of constructors and
1588    destructors, so that we don't get linker errors.  These symbols are
1589    intentionally bss symbols, so that gld and/or collect will provide
1590    the right values.  */
1591
1592 /* We declare the lists here with two elements each,
1593    so that they are valid empty lists if no other definition is loaded.  */
1594 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
1595 #ifdef __NeXT__
1596 /* After 2.3, try this definition on all systems.  */
1597 func_ptr __CTOR_LIST__[2] = {0, 0};
1598 func_ptr __DTOR_LIST__[2] = {0, 0};
1599 #else
1600 func_ptr __CTOR_LIST__[2];
1601 func_ptr __DTOR_LIST__[2];
1602 #endif
1603 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1604 #endif /* L_ctors */
1605 \f
1606 #ifdef L_exit
1607
1608 #include "gbl-ctors.h"
1609
1610 #ifndef ON_EXIT
1611
1612 /* If we have no known way of registering our own __do_global_dtors
1613    routine so that it will be invoked at program exit time, then we
1614    have to define our own exit routine which will get this to happen.  */
1615
1616 extern void __do_global_dtors ();
1617 extern void _cleanup ();
1618 extern volatile void _exit ();
1619
1620 void 
1621 exit (status)
1622      int status;
1623 {
1624   __do_global_dtors ();
1625 #ifdef EXIT_BODY
1626   EXIT_BODY;
1627 #else
1628   _cleanup ();
1629 #endif
1630   _exit (status);
1631 }
1632
1633 #else
1634 int _exit_dummy_decl = 0;       /* prevent compiler & linker warnings */
1635 #endif
1636
1637 #endif /* L_exit */
1638 \f
1639 /* In a.out systems, we need to have these dummy constructor and destructor
1640    lists in the library.
1641
1642    When using `collect', the first link will resolve __CTOR_LIST__
1643    and __DTOR_LIST__ to these symbols.  We will then run "nm" on the
1644    result, build the correct __CTOR_LIST__ and __DTOR_LIST__, and relink.
1645    Since we don't do the second link if no constructors existed, these
1646    dummies must be fully functional empty lists.
1647
1648    When using `gnu ld', these symbols will be used if there are no
1649    constructors.  If there are constructors, the N_SETV symbol defined
1650    by the linker from the N_SETT's in input files will define __CTOR_LIST__
1651    and __DTOR_LIST__ rather than its being allocated as common storage
1652    by the definitions below.
1653
1654    When using a linker that supports constructor and destructor segments,
1655    these definitions will not be used, since crtbegin.o and crtend.o
1656    (from crtstuff.c) will have already defined __CTOR_LIST__ and
1657     __DTOR_LIST__.  The crt*.o files are passed directly to the linker
1658    on its command line, by gcc.  */
1659
1660 /* The list needs two elements:  one is ignored (the old count); the
1661    second is the terminating zero.  Since both values are zero, this
1662    declaration is not initialized, and it becomes `common'.  */
1663
1664 #ifdef L_ctor_list
1665 #include "gbl-ctors.h"
1666 func_ptr __CTOR_LIST__[2];
1667 #endif
1668
1669 #ifdef L_dtor_list
1670 #include "gbl-ctors.h"
1671 func_ptr __DTOR_LIST__[2];
1672 #endif