OSDN Git Service

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