OSDN Git Service

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