OSDN Git Service

(__main): Use macro SYMBOL__MAIN instead of invoking directly.
[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 LONG_DOUBLE_TYPE_SIZE == 96
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 #if defined(L_fixunsxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
807 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
808 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
809
810 DItype
811 __fixunsxfdi (a)
812      XFtype a;
813 {
814   XFtype 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 XFtype, leaving the low part as flonum.  */
827   a -= (XFtype)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 #if defined(L_fixxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
840 DItype
841 __fixxfdi (a)
842      XFtype a;
843 {
844   if (a < 0)
845     return - __fixunsxfdi (-a);
846   return __fixunsxfdi (a);
847 }
848 #endif
849
850 #ifdef L_fixunsdfdi
851 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
852 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
853
854 DItype
855 __fixunsdfdi (a)
856      DFtype a;
857 {
858   DFtype b;
859   UDItype v;
860
861   if (a < 0)
862     return 0;
863
864   /* Compute high word of result, as a flonum.  */
865   b = (a / HIGH_WORD_COEFF);
866   /* Convert that to fixed (but not to DItype!),
867      and shift it into the high word.  */
868   v = (USItype) b;
869   v <<= WORD_SIZE;
870   /* Remove high part from the DFtype, leaving the low part as flonum.  */
871   a -= (DFtype)v;
872   /* Convert that to fixed (but not to DItype!) and add it in.
873      Sometimes A comes out negative.  This is significant, since
874      A has more bits than a long int does.  */
875   if (a < 0)
876     v -= (USItype) (- a);
877   else
878     v += (USItype) a;
879   return v;
880 }
881 #endif
882
883 #ifdef L_fixdfdi
884 DItype
885 __fixdfdi (a)
886      DFtype a;
887 {
888   if (a < 0)
889     return - __fixunsdfdi (-a);
890   return __fixunsdfdi (a);
891 }
892 #endif
893
894 #ifdef L_fixunssfdi
895 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
896 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
897
898 DItype
899 __fixunssfdi (SFtype original_a)
900 {
901   /* Convert the SFtype to a DFtype, because that is surely not going
902      to lose any bits.  Some day someone else can write a faster version
903      that avoids converting to DFtype, and verify it really works right.  */
904   DFtype a = original_a;
905   DFtype b;
906   UDItype v;
907
908   if (a < 0)
909     return 0;
910
911   /* Compute high word of result, as a flonum.  */
912   b = (a / HIGH_WORD_COEFF);
913   /* Convert that to fixed (but not to DItype!),
914      and shift it into the high word.  */
915   v = (USItype) b;
916   v <<= WORD_SIZE;
917   /* Remove high part from the DFtype, leaving the low part as flonum.  */
918   a -= (DFtype)v;
919   /* Convert that to fixed (but not to DItype!) and add it in.
920      Sometimes A comes out negative.  This is significant, since
921      A has more bits than a long int does.  */
922   if (a < 0)
923     v -= (USItype) (- a);
924   else
925     v += (USItype) a;
926   return v;
927 }
928 #endif
929
930 #ifdef L_fixsfdi
931 DItype
932 __fixsfdi (SFtype a)
933 {
934   if (a < 0)
935     return - __fixunssfdi (-a);
936   return __fixunssfdi (a);
937 }
938 #endif
939
940 #if defined(L_floatdixf) && (LONG_DOUBLE_TYPE_SIZE == 96)
941 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
942 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
943 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
944
945 XFtype
946 __floatdixf (u)
947      DItype u;
948 {
949   XFtype d;
950   SItype negate = 0;
951
952   if (u < 0)
953     u = -u, negate = 1;
954
955   d = (USItype) (u >> WORD_SIZE);
956   d *= HIGH_HALFWORD_COEFF;
957   d *= HIGH_HALFWORD_COEFF;
958   d += (USItype) (u & (HIGH_WORD_COEFF - 1));
959
960   return (negate ? -d : d);
961 }
962 #endif
963
964 #if defined(L_floatditf) && (LONG_DOUBLE_TYPE_SIZE == 128)
965 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
966 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
967 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
968
969 TFtype
970 __floatditf (u)
971      DItype u;
972 {
973   TFtype d;
974   SItype negate = 0;
975
976   if (u < 0)
977     u = -u, negate = 1;
978
979   d = (USItype) (u >> WORD_SIZE);
980   d *= HIGH_HALFWORD_COEFF;
981   d *= HIGH_HALFWORD_COEFF;
982   d += (USItype) (u & (HIGH_WORD_COEFF - 1));
983
984   return (negate ? -d : d);
985 }
986 #endif
987
988 #ifdef L_floatdidf
989 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
990 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
991 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
992
993 DFtype
994 __floatdidf (u)
995      DItype u;
996 {
997   DFtype d;
998   SItype negate = 0;
999
1000   if (u < 0)
1001     u = -u, negate = 1;
1002
1003   d = (USItype) (u >> WORD_SIZE);
1004   d *= HIGH_HALFWORD_COEFF;
1005   d *= HIGH_HALFWORD_COEFF;
1006   d += (USItype) (u & (HIGH_WORD_COEFF - 1));
1007
1008   return (negate ? -d : d);
1009 }
1010 #endif
1011
1012 #ifdef L_floatdisf
1013 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
1014 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
1015 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
1016
1017 SFtype
1018 __floatdisf (u)
1019      DItype u;
1020 {
1021   /* Do the calculation in DFmode
1022      so that we don't lose any of the precision of the high word
1023      while multiplying it.  */
1024   DFtype f;
1025   SItype negate = 0;
1026
1027   if (u < 0)
1028     u = -u, negate = 1;
1029
1030   f = (USItype) (u >> WORD_SIZE);
1031   f *= HIGH_HALFWORD_COEFF;
1032   f *= HIGH_HALFWORD_COEFF;
1033   f += (USItype) (u & (HIGH_WORD_COEFF - 1));
1034
1035   return (SFtype) (negate ? -f : f);
1036 }
1037 #endif
1038
1039 #if defined(L_fixunsxfsi) && LONG_DOUBLE_TYPE_SIZE == 96
1040 #include "glimits.h"
1041
1042 USItype
1043 __fixunsxfsi (a)
1044      XFtype a;
1045 {
1046   if (a >= - (DFtype) LONG_MIN)
1047     return (SItype) (a + LONG_MIN) - LONG_MIN;
1048   return (SItype) a;
1049 }
1050 #endif
1051
1052 #ifdef L_fixunsdfsi
1053 #include "glimits.h"
1054
1055 USItype
1056 __fixunsdfsi (a)
1057      DFtype a;
1058 {
1059   if (a >= - (DFtype) LONG_MIN)
1060     return (SItype) (a + LONG_MIN) - LONG_MIN;
1061   return (SItype) a;
1062 }
1063 #endif
1064
1065 #ifdef L_fixunssfsi
1066 #include "glimits.h"
1067
1068 USItype
1069 __fixunssfsi (SFtype a)
1070 {
1071   if (a >= - (SFtype) LONG_MIN)
1072     return (SItype) (a + LONG_MIN) - LONG_MIN;
1073   return (SItype) a;
1074 }
1075 #endif
1076 \f
1077 /* From here on down, the routines use normal data types.  */
1078
1079 #define SItype bogus_type
1080 #define USItype bogus_type
1081 #define DItype bogus_type
1082 #define UDItype bogus_type
1083 #define SFtype bogus_type
1084 #define DFtype bogus_type
1085
1086 #undef char
1087 #undef short
1088 #undef int
1089 #undef long
1090 #undef unsigned
1091 #undef float
1092 #undef double
1093 \f
1094 #ifdef L__gcc_bcmp
1095
1096 /* Like bcmp except the sign is meaningful.
1097    Reult is negative if S1 is less than S2,
1098    positive if S1 is greater, 0 if S1 and S2 are equal.  */
1099
1100 int
1101 __gcc_bcmp (s1, s2, size)
1102      unsigned char *s1, *s2;
1103      size_t size;
1104 {
1105   while (size > 0)
1106     {
1107       unsigned char c1 = *s1++, c2 = *s2++;
1108       if (c1 != c2)
1109         return c1 - c2;
1110       size--;
1111     }
1112   return 0;
1113 }
1114
1115 #endif
1116 \f\f
1117 #ifdef L_varargs
1118 #ifdef __i860__
1119 #if defined(__svr4__) || defined(__alliant__)
1120         asm ("  .text");
1121         asm ("  .align  4");
1122
1123 /* The Alliant needs the added underscore.  */
1124         asm (".globl    __builtin_saveregs");
1125 asm ("__builtin_saveregs:");
1126         asm (".globl    ___builtin_saveregs");
1127 asm ("___builtin_saveregs:");
1128
1129         asm ("  andnot  0x0f,%sp,%sp"); /* round down to 16-byte boundary */
1130         asm ("  adds    -96,%sp,%sp");  /* allocate stack space for reg save
1131                                            area and also for a new va_list
1132                                            structure */
1133         /* Save all argument registers in the arg reg save area.  The
1134            arg reg save area must have the following layout (according
1135            to the svr4 ABI):
1136
1137                 struct {
1138                   union  {
1139                     float freg[8];
1140                     double dreg[4];
1141                   } float_regs;
1142                   long  ireg[12];
1143                 };
1144         */
1145
1146         asm ("  fst.q   %f8,  0(%sp)"); /* save floating regs (f8-f15)  */
1147         asm ("  fst.q   %f12,16(%sp)"); 
1148
1149         asm ("  st.l    %r16,32(%sp)"); /* save integer regs (r16-r27) */
1150         asm ("  st.l    %r17,36(%sp)"); 
1151         asm ("  st.l    %r18,40(%sp)");
1152         asm ("  st.l    %r19,44(%sp)");
1153         asm ("  st.l    %r20,48(%sp)");
1154         asm ("  st.l    %r21,52(%sp)");
1155         asm ("  st.l    %r22,56(%sp)");
1156         asm ("  st.l    %r23,60(%sp)");
1157         asm ("  st.l    %r24,64(%sp)");
1158         asm ("  st.l    %r25,68(%sp)");
1159         asm ("  st.l    %r26,72(%sp)");
1160         asm ("  st.l    %r27,76(%sp)");
1161
1162         asm ("  adds    80,%sp,%r16");  /* compute the address of the new
1163                                            va_list structure.  Put in into
1164                                            r16 so that it will be returned
1165                                            to the caller.  */
1166
1167         /* Initialize all fields of the new va_list structure.  This
1168            structure looks like:
1169
1170                 typedef struct {
1171                     unsigned long       ireg_used;
1172                     unsigned long       freg_used;
1173                     long                *reg_base;
1174                     long                *mem_ptr;
1175                 } va_list;
1176         */
1177
1178         asm ("  st.l    %r0, 0(%r16)"); /* nfixed */
1179         asm ("  st.l    %r0, 4(%r16)"); /* nfloating */
1180         asm ("  st.l    %sp, 8(%r16)"); /* __va_ctl points to __va_struct.  */
1181         asm ("  bri     %r1");          /* delayed return */
1182         asm ("  st.l    %r28,12(%r16)"); /* pointer to overflow args */
1183
1184 #else /* not __svr4__ */
1185         asm ("  .text");
1186         asm ("  .align  4");
1187
1188         asm (".globl    ___builtin_saveregs");
1189         asm ("___builtin_saveregs:");
1190         asm ("  mov     sp,r30");
1191         asm ("  andnot  0x0f,sp,sp");
1192         asm ("  adds    -96,sp,sp");  /* allocate sufficient space on the stack */
1193
1194 /* Fill in the __va_struct.  */
1195         asm ("  st.l    r16, 0(sp)"); /* save integer regs (r16-r27) */
1196         asm ("  st.l    r17, 4(sp)"); /* int    fixed[12] */
1197         asm ("  st.l    r18, 8(sp)");
1198         asm ("  st.l    r19,12(sp)");
1199         asm ("  st.l    r20,16(sp)");
1200         asm ("  st.l    r21,20(sp)");
1201         asm ("  st.l    r22,24(sp)");
1202         asm ("  st.l    r23,28(sp)");
1203         asm ("  st.l    r24,32(sp)");
1204         asm ("  st.l    r25,36(sp)");
1205         asm ("  st.l    r26,40(sp)");
1206         asm ("  st.l    r27,44(sp)");
1207
1208         asm ("  fst.q   f8, 48(sp)"); /* save floating regs (f8-f15) */
1209         asm ("  fst.q   f12,64(sp)"); /* int floating[8] */
1210
1211 /* Fill in the __va_ctl.  */
1212         asm ("  st.l    sp, 80(sp)"); /* __va_ctl points to __va_struct.  */
1213         asm ("  st.l    r28,84(sp)"); /* pointer to more args */
1214         asm ("  st.l    r0, 88(sp)"); /* nfixed */
1215         asm ("  st.l    r0, 92(sp)"); /* nfloating */
1216
1217         asm ("  adds    80,sp,r16");  /* return address of the __va_ctl.  */
1218         asm ("  bri     r1");
1219         asm ("  mov     r30,sp");
1220                                 /* recover stack and pass address to start 
1221                                    of data.  */
1222 #endif /* not __svr4__ */
1223 #else /* not __i860__ */
1224 #ifdef __sparc__
1225         asm (".global __builtin_saveregs");
1226         asm ("__builtin_saveregs:");
1227         asm (".global ___builtin_saveregs");
1228         asm ("___builtin_saveregs:");
1229 #ifdef NEED_PROC_COMMAND
1230         asm (".proc 020");
1231 #endif
1232         asm ("st %i0,[%fp+68]");
1233         asm ("st %i1,[%fp+72]");
1234         asm ("st %i2,[%fp+76]");
1235         asm ("st %i3,[%fp+80]");
1236         asm ("st %i4,[%fp+84]");
1237         asm ("retl");
1238         asm ("st %i5,[%fp+88]");
1239 #ifdef NEED_TYPE_COMMAND
1240         asm (".type __builtin_saveregs,#function");
1241         asm (".size __builtin_saveregs,.-__builtin_saveregs");
1242 #endif
1243 #else /* not __sparc__ */
1244 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1245
1246   asm ("        .text");
1247   asm ("        .ent __builtin_saveregs");
1248   asm ("        .globl __builtin_saveregs");
1249   asm ("__builtin_saveregs:");
1250   asm ("        sw      $4,0($30)");
1251   asm ("        sw      $5,4($30)");
1252   asm ("        sw      $6,8($30)");
1253   asm ("        sw      $7,12($30)");
1254   asm ("        j       $31");
1255   asm ("        .end __builtin_saveregs");
1256 #else /* not __mips__, etc. */
1257 __builtin_saveregs ()
1258 {
1259   abort ();
1260 }
1261 #endif /* not __mips__ */
1262 #endif /* not __sparc__ */
1263 #endif /* not __i860__ */
1264 #endif
1265 \f
1266 #ifdef L_eprintf
1267 #ifndef inhibit_libc
1268
1269 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1270 #include <stdio.h>
1271 /* This is used by the `assert' macro.  */
1272 void
1273 __eprintf (string, expression, line, filename)
1274      const char *string;
1275      const char *expression;
1276      int line;
1277      const char *filename;
1278 {
1279   fprintf (stderr, string, expression, line, filename);
1280   fflush (stderr);
1281   abort ();
1282 }
1283
1284 #endif
1285 #endif
1286
1287 #ifdef L_bb
1288 /* Avoid warning from ranlib about empty object file.  */
1289 void
1290 __bb_avoid_warning ()
1291 {}
1292
1293 #if defined (__sun__) && defined (__mc68000__)
1294 struct bb
1295 {
1296   int initialized;
1297   char *filename;
1298   int *counts;
1299   int ncounts;
1300   int zero_word;
1301   int *addresses;
1302 };
1303
1304 extern int ___tcov_init;
1305
1306 __bb_init_func (blocks)
1307         struct bb *blocks;
1308 {
1309   if (! ___tcov_init)
1310     ___tcov_init_func ();
1311
1312   ___bb_link (blocks->filename, blocks->counts, blocks->ncounts);
1313 }
1314
1315 #endif
1316 #endif
1317 \f
1318 /* frills for C++ */
1319
1320 #ifdef L_op_new
1321 typedef void (*vfp)(void);
1322
1323 extern vfp __new_handler;
1324
1325 /* void * operator new (size_t sz) */
1326 void *
1327 __builtin_new (size_t sz)
1328 {
1329   void *p;
1330
1331   /* malloc (0) is unpredictable; avoid it.  */
1332   if (sz == 0)
1333     sz = 1;
1334   p = (void *) malloc (sz);
1335   if (p == 0)
1336     (*__new_handler) ();
1337   return p;
1338 }
1339 #endif /* L_op_new */
1340
1341 #ifdef L_new_handler
1342
1343 #ifndef inhibit_libc
1344 /* This gets us __GNU_LIBRARY__.  */
1345 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1346 #include <stdio.h>
1347
1348 #ifdef __GNU_LIBRARY__
1349   /* Avoid forcing the library's meaning of `write' on the user program
1350      by using the "internal" name (for use within the library)  */
1351 #define write(fd, buf, n)       __write((fd), (buf), (n))
1352 #endif
1353 #endif /* inhibit_libc */
1354
1355 typedef void (*vfp)(void);
1356
1357 extern void *__builtin_new (size_t);
1358 static void default_new_handler (void);
1359
1360 vfp __new_handler = default_new_handler;
1361
1362 vfp
1363 __set_new_handler (handler)
1364      vfp handler;
1365 {
1366   vfp prev_handler;
1367
1368   prev_handler = __new_handler;
1369   if (handler == 0) handler = default_new_handler;
1370   __new_handler = handler;
1371   return prev_handler;
1372 }
1373
1374 vfp
1375 set_new_handler (handler)
1376      vfp handler;
1377 {
1378   return __set_new_handler (handler);
1379 }
1380
1381 #define MESSAGE "Virtual memory exceeded in `new'\n"
1382
1383 static void
1384 default_new_handler ()
1385 {
1386   /* don't use fprintf (stderr, ...) because it may need to call malloc.  */
1387   /* This should really print the name of the program, but that is hard to
1388      do.  We need a standard, clean way to get at the name.  */
1389   write (2, MESSAGE, sizeof (MESSAGE));
1390   /* don't call exit () because that may call global destructors which
1391      may cause a loop.  */
1392   _exit (-1);
1393 }
1394 #endif
1395
1396 #ifdef L_op_delete
1397 /* void operator delete (void *ptr) */
1398 void
1399 __builtin_delete (void *ptr)
1400 {
1401   if (ptr)
1402     free (ptr);
1403 }
1404 #endif
1405 \f
1406 #ifdef L_shtab
1407 unsigned int __shtab[] = {
1408     0x00000001, 0x00000002, 0x00000004, 0x00000008,
1409     0x00000010, 0x00000020, 0x00000040, 0x00000080,
1410     0x00000100, 0x00000200, 0x00000400, 0x00000800,
1411     0x00001000, 0x00002000, 0x00004000, 0x00008000,
1412     0x00010000, 0x00020000, 0x00040000, 0x00080000,
1413     0x00100000, 0x00200000, 0x00400000, 0x00800000,
1414     0x01000000, 0x02000000, 0x04000000, 0x08000000,
1415     0x10000000, 0x20000000, 0x40000000, 0x80000000
1416   };
1417 #endif
1418 \f
1419 #ifdef L_clear_cache
1420 /* Clear part of an instruction cache.  */
1421
1422 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1423
1424 void
1425 __clear_cache (beg, end)
1426      char *beg, *end;
1427 {
1428 #ifdef INSN_CACHE_SIZE
1429   static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1430   static int initialized = 0;
1431   int offset;
1432   void *start_addr
1433   void *end_addr;
1434   typedef (*function_ptr) ();
1435
1436 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1437   /* It's cheaper to clear the whole cache.
1438      Put in a series of jump instructions so that calling the beginning
1439      of the cache will clear the whole thing.  */
1440
1441   if (! initialized)
1442     {
1443       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1444                  & -INSN_CACHE_LINE_WIDTH);
1445       int end_ptr = ptr + INSN_CACHE_SIZE;
1446
1447       while (ptr < end_ptr)
1448         {
1449           *(INSTRUCTION_TYPE *)ptr
1450             = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1451           ptr += INSN_CACHE_LINE_WIDTH;
1452         }
1453       *(INSTRUCTION_TYPE *)(ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1454
1455       initialized = 1;
1456     }
1457
1458   /* Call the beginning of the sequence.  */
1459   (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1460                     & -INSN_CACHE_LINE_WIDTH))
1461    ());
1462
1463 #else /* Cache is large.  */
1464
1465   if (! initialized)
1466     {
1467       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1468                  & -INSN_CACHE_LINE_WIDTH);
1469
1470       while (ptr < (int) array + sizeof array)
1471         {
1472           *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1473           ptr += INSN_CACHE_LINE_WIDTH;
1474         }
1475
1476       initialized = 1;
1477     }
1478
1479   /* Find the location in array that occupies the same cache line as BEG.  */
1480
1481   offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1482   start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1483                  & -INSN_CACHE_PLANE_SIZE)
1484                 + offset);
1485
1486   /* Compute the cache alignment of the place to stop clearing.  */
1487 #if 0  /* This is not needed for gcc's purposes.  */
1488   /* If the block to clear is bigger than a cache plane,
1489      we clear the entire cache, and OFFSET is already correct.  */ 
1490   if (end < beg + INSN_CACHE_PLANE_SIZE)
1491 #endif
1492     offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1493                & -INSN_CACHE_LINE_WIDTH)
1494               & (INSN_CACHE_PLANE_SIZE - 1));
1495
1496 #if INSN_CACHE_DEPTH > 1
1497   end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1498   if (end_addr <= start_addr)
1499     end_addr += INSN_CACHE_PLANE_SIZE;
1500
1501   for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1502     {
1503       int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1504       int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1505
1506       while (addr != stop)
1507         {
1508           /* Call the return instruction at ADDR.  */
1509           ((function_ptr) addr) ();
1510
1511           addr += INSN_CACHE_LINE_WIDTH;
1512         }
1513     }
1514 #else /* just one plane */
1515   do
1516     {
1517       /* Call the return instruction at START_ADDR.  */
1518       ((function_ptr) start_addr) ();
1519
1520       start_addr += INSN_CACHE_LINE_WIDTH;
1521     }
1522   while ((start_addr % INSN_CACHE_SIZE) != offset);
1523 #endif /* just one plane */
1524 #endif /* Cache is large */
1525 #endif /* Cache exists */
1526 }
1527
1528 #endif /* L_clear_cache */
1529 \f
1530 #ifdef L_trampoline
1531
1532 /* Jump to a trampoline, loading the static chain address.  */
1533
1534 #ifdef TRANSFER_FROM_TRAMPOLINE 
1535 TRANSFER_FROM_TRAMPOLINE 
1536 #endif
1537
1538 #ifdef __convex__
1539
1540 /* Make stack executable so we can call trampolines on stack.
1541    This is called from INITIALIZE_TRAMPOLINE in convex.h.  */
1542
1543 #include <sys/mman.h>
1544 #include <sys/vmparam.h>
1545 #include <machine/machparam.h>
1546
1547 void
1548 __enable_execute_stack ()
1549 {
1550   int fp;
1551   static unsigned lowest = USRSTACK;
1552   unsigned current = (unsigned) &fp & -NBPG;
1553
1554   if (lowest > current)
1555     {
1556       unsigned len = lowest - current;
1557       mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
1558       lowest = current;
1559     }
1560
1561   /* Clear instruction cache in case an old trampoline is in it. */
1562   asm ("pich");
1563 }
1564 #endif /* __convex__ */
1565
1566 #ifdef __pyr__
1567
1568 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1569 #include <stdio.h>
1570 #include <sys/mman.h>
1571 #include <sys/types.h>
1572 #include <sys/param.h>
1573 #include <sys/vmmac.h>
1574
1575 /* Modified from the convex -code above.
1576    mremap promises to clear the i-cache. */
1577
1578 void
1579 __enable_execute_stack ()
1580 {
1581   int fp;
1582   if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
1583                 PROT_READ|PROT_WRITE|PROT_EXEC))
1584     {
1585       perror ("mprotect in __enable_execute_stack");
1586       fflush (stderr);
1587       abort ();
1588     }
1589 }
1590 #endif /* __pyr__ */
1591 #endif /* L_trampoline */
1592 \f
1593 #ifdef L__main
1594
1595 #include "gbl-ctors.h"
1596 /* Some systems use __main in a way incompatible with its use in gcc, in these
1597    cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
1598    give the same symbol without quotes for an alternative entry point.  You
1599    must define both, or niether. */
1600 #ifndef NAME__MAIN
1601 #define NAME__MAIN "__main"
1602 #define SYMBOL__MAIN __main
1603 #endif
1604
1605 /* Run all the global destructors on exit from the program.  */
1606
1607 void
1608 __do_global_dtors ()
1609 {
1610 #ifdef DO_GLOBAL_DTORS_BODY
1611   DO_GLOBAL_DTORS_BODY;
1612 #else
1613   unsigned nptrs = (unsigned HOST_WIDE_INT) __DTOR_LIST__[0];
1614   unsigned i;
1615
1616   /* Some systems place the number of pointers
1617      in the first word of the table.
1618      On other systems, that word is -1.
1619      In all cases, the table is null-terminated.  */
1620
1621   /* If the length is not recorded, count up to the null.  */
1622   if (nptrs == -1)
1623     for (nptrs = 0; __DTOR_LIST__[nptrs + 1] != 0; nptrs++);
1624
1625   /* GNU LD format.  */
1626   for (i = nptrs; i >= 1; i--)
1627     __DTOR_LIST__[i] ();
1628 #endif
1629 }
1630
1631 #ifndef INIT_SECTION_ASM_OP
1632 /* Run all the global constructors on entry to the program.  */
1633
1634 #ifndef ON_EXIT
1635 #define ON_EXIT(a, b)
1636 #else
1637 /* Make sure the exit routine is pulled in to define the globals as
1638    bss symbols, just in case the linker does not automatically pull
1639    bss definitions from the library.  */
1640
1641 extern int _exit_dummy_decl;
1642 int *_exit_dummy_ref = &_exit_dummy_decl;
1643 #endif /* ON_EXIT */
1644
1645 void
1646 __do_global_ctors ()
1647 {
1648   DO_GLOBAL_CTORS_BODY;
1649   ON_EXIT (__do_global_dtors, 0);
1650 }
1651 #endif /* no INIT_SECTION_ASM_OP */
1652
1653 #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
1654 /* Subroutine called automatically by `main'.
1655    Compiling a global function named `main'
1656    produces an automatic call to this function at the beginning.
1657
1658    For many systems, this routine calls __do_global_ctors.
1659    For systems which support a .init section we use the .init section
1660    to run __do_global_ctors, so we need not do anything here.  */
1661
1662 void
1663 SYMBOL__MAIN ()
1664 {
1665   /* Support recursive calls to `main': run initializers just once.  */
1666   static int initialized = 0;
1667   if (! initialized)
1668     {
1669       initialized = 1;
1670       __do_global_ctors ();
1671     }
1672 }
1673 #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
1674
1675 #endif /* L__main */
1676 \f
1677 #ifdef L_ctors
1678
1679 #include "gbl-ctors.h"
1680
1681 /* Provide default definitions for the lists of constructors and
1682    destructors, so that we don't get linker errors.  These symbols are
1683    intentionally bss symbols, so that gld and/or collect will provide
1684    the right values.  */
1685
1686 /* We declare the lists here with two elements each,
1687    so that they are valid empty lists if no other definition is loaded.  */
1688 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
1689 #ifdef __NeXT__
1690 /* After 2.3, try this definition on all systems.  */
1691 func_ptr __CTOR_LIST__[2] = {0, 0};
1692 func_ptr __DTOR_LIST__[2] = {0, 0};
1693 #else
1694 func_ptr __CTOR_LIST__[2];
1695 func_ptr __DTOR_LIST__[2];
1696 #endif
1697 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1698 #endif /* L_ctors */
1699 \f
1700 #ifdef L_exit
1701
1702 #include "gbl-ctors.h"
1703
1704 #ifndef ON_EXIT
1705
1706 /* If we have no known way of registering our own __do_global_dtors
1707    routine so that it will be invoked at program exit time, then we
1708    have to define our own exit routine which will get this to happen.  */
1709
1710 extern void __do_global_dtors ();
1711 extern void _cleanup ();
1712 extern volatile void _exit ();
1713
1714 void 
1715 exit (status)
1716      int status;
1717 {
1718   __do_global_dtors ();
1719 #ifdef EXIT_BODY
1720   EXIT_BODY;
1721 #else
1722   _cleanup ();
1723 #endif
1724   _exit (status);
1725 }
1726
1727 #else
1728 int _exit_dummy_decl = 0;       /* prevent compiler & linker warnings */
1729 #endif
1730
1731 #endif /* L_exit */
1732 \f
1733 /* In a.out systems, we need to have these dummy constructor and destructor
1734    lists in the library.
1735
1736    When using `collect', the first link will resolve __CTOR_LIST__
1737    and __DTOR_LIST__ to these symbols.  We will then run "nm" on the
1738    result, build the correct __CTOR_LIST__ and __DTOR_LIST__, and relink.
1739    Since we don't do the second link if no constructors existed, these
1740    dummies must be fully functional empty lists.
1741
1742    When using `gnu ld', these symbols will be used if there are no
1743    constructors.  If there are constructors, the N_SETV symbol defined
1744    by the linker from the N_SETT's in input files will define __CTOR_LIST__
1745    and __DTOR_LIST__ rather than its being allocated as common storage
1746    by the definitions below.
1747
1748    When using a linker that supports constructor and destructor segments,
1749    these definitions will not be used, since crtbegin.o and crtend.o
1750    (from crtstuff.c) will have already defined __CTOR_LIST__ and
1751     __DTOR_LIST__.  The crt*.o files are passed directly to the linker
1752    on its command line, by gcc.  */
1753
1754 /* The list needs two elements:  one is ignored (the old count); the
1755    second is the terminating zero.  Since both values are zero, this
1756    declaration is not initialized, and it becomes `common'.  */
1757
1758 #ifdef L_ctor_list
1759 #include "gbl-ctors.h"
1760 func_ptr __CTOR_LIST__[2];
1761 #endif
1762
1763 #ifdef L_dtor_list
1764 #include "gbl-ctors.h"
1765 func_ptr __DTOR_LIST__[2];
1766 #endif