OSDN Git Service

(__clear_cache): add case for new CLEAR_INSN_CACHE.
[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 #ifndef inhibit_libc
1317
1318 /* Simple minded basic block profiling output dumper for
1319    systems that don't provde tcov support.  At present,
1320    it requires atexit and stdio.  */
1321
1322 #include <stdio.h>
1323
1324 #ifdef HAVE_ATEXIT
1325 extern void atexit (void (*) (void));
1326 #define ON_EXIT(FUNC,ARG) atexit ((FUNC))
1327 #else
1328 #ifdef sun
1329 extern void on_exit (void*, void*);
1330 #define ON_EXIT(FUNC,ARG) on_exit ((FUNC), (ARG))
1331 #endif
1332 #endif
1333
1334 static struct bb *bb_head = (struct bb *)0;
1335
1336 /* Return the number of digits needed to print a value */
1337 /* __inline__ */ static int num_digits (long value, int base)
1338 {
1339   int minus = (value < 0 && base != 16);
1340   unsigned long v = (minus) ? -value : value;
1341   int ret = minus;
1342
1343   do
1344     {
1345       v /= base;
1346       ret++;
1347     }
1348   while (v);
1349
1350   return ret;
1351 }
1352
1353 void
1354 __bb_exit_func (void)
1355 {
1356   FILE *file = fopen ("bb.out", "a");
1357   long time_value;
1358
1359   if (!file)
1360     perror ("bb.out");
1361
1362   else
1363     {
1364       struct bb *ptr;
1365
1366       /* This is somewhat type incorrect, but it avoids worrying about
1367          exactly where time.h is included from.  It should be ok unless
1368          a void * differs from other pointer formats, or if sizeof(long)
1369          is < sizeof (time_t).  It would be nice if we could assume the
1370          use of rationale standards here.  */
1371
1372       time((void *) &time_value);
1373       fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value));
1374
1375       /* We check the length field explicitly in order to allow compatibility
1376          with older GCC's which did not provide it.  */
1377
1378       for (ptr = bb_head; ptr != (struct bb *)0; ptr = ptr->next)
1379         {
1380           int i;
1381           int func_p    = (ptr->nwords >= sizeof (struct bb) && ptr->nwords <= 1000);
1382           int line_p    = (func_p && ptr->line_nums);
1383           int file_p    = (func_p && ptr->filenames);
1384           long ncounts  = ptr->ncounts;
1385           long cnt_max  = 0;
1386           long line_max = 0;
1387           long addr_max = 0;
1388           int file_len  = 0;
1389           int func_len  = 0;
1390           int blk_len   = num_digits (ncounts, 10);
1391           int cnt_len;
1392           int line_len;
1393           int addr_len;
1394
1395           fprintf (file, "File %s, %ld basic blocks \n\n",
1396                    ptr->filename, ncounts);
1397
1398           /* Get max values for each field.  */
1399           for (i = 0; i < ncounts; i++)
1400             {
1401               const char *p;
1402               int len;
1403
1404               if (cnt_max < ptr->counts[i])
1405                 cnt_max = ptr->counts[i];
1406
1407               if (addr_max < ptr->addresses[i])
1408                 addr_max = ptr->addresses[i];
1409
1410               if (line_p && line_max < ptr->line_nums[i])
1411                 line_max = ptr->line_nums[i];
1412
1413               if (func_p)
1414                 {
1415                   p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>";
1416                   len = strlen (p);
1417                   if (func_len < len)
1418                     func_len = len;
1419                 }
1420
1421               if (file_p)
1422                 {
1423                   p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>";
1424                   len = strlen (p);
1425                   if (file_len < len)
1426                     file_len = len;
1427                 }
1428             }
1429
1430           addr_len = num_digits (addr_max, 16);
1431           cnt_len  = num_digits (cnt_max, 10);
1432           line_len = num_digits (line_max, 10);
1433
1434           /* Now print out the basic block information.  */
1435           for (i = 0; i < ncounts; i++)
1436             {
1437               fprintf (file,
1438                        "    Block #%*d: executed %*ld time(s) address= 0x%.*lx",
1439                        blk_len, i+1,
1440                        cnt_len, ptr->counts[i],
1441                        addr_len, ptr->addresses[i]);
1442
1443               if (func_p)
1444                 fprintf (file, " function= %-*s", func_len,
1445                          (ptr->functions[i]) ? ptr->functions[i] : "<none>");
1446
1447               if (line_p)
1448                 fprintf (file, " line= %*d", line_len, ptr->line_nums[i]);
1449
1450               if (file_p)
1451                 fprintf (file, " file= %s",
1452                          (ptr->filenames[i]) ? ptr->filenames[i] : "<none>");
1453
1454               fprintf (file, "\n");
1455             }
1456
1457           fprintf (file, "\n");
1458           fflush (file);
1459         }
1460
1461       fprintf (file, "\n\n");
1462       fclose (file);
1463     }
1464 }
1465
1466 void
1467 __bb_init_func (struct bb *blocks)
1468 {
1469   /* User is supposed to check whether the first word is non-0,
1470      but just in case.... */
1471
1472   if (blocks->zero_word)
1473     return;
1474
1475 #ifdef ON_EXIT
1476   /* Initialize destructor.  */
1477   if (!bb_head)
1478     ON_EXIT (__bb_exit_func, 0);
1479 #endif
1480
1481   /* Set up linked list.  */
1482   blocks->zero_word = 1;
1483   blocks->next = bb_head;
1484   bb_head = blocks;
1485 }
1486
1487 #endif /* not inhibit_libc */
1488 #endif /* not BLOCK_PROFILER_CODE */
1489 #endif /* L_bb */
1490 \f
1491 /* frills for C++ */
1492
1493 #ifdef L_op_new
1494 typedef void (*vfp)(void);
1495
1496 extern vfp __new_handler;
1497
1498 /* void * operator new (size_t sz) */
1499 void *
1500 __builtin_new (size_t sz)
1501 {
1502   void *p;
1503
1504   /* malloc (0) is unpredictable; avoid it.  */
1505   if (sz == 0)
1506     sz = 1;
1507   p = (void *) malloc (sz);
1508   if (p == 0)
1509     (*__new_handler) ();
1510   return p;
1511 }
1512 #endif /* L_op_new */
1513
1514 #ifdef L_new_handler
1515
1516 #ifndef inhibit_libc
1517 /* This gets us __GNU_LIBRARY__.  */
1518 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1519 #include <stdio.h>
1520
1521 #ifdef __GNU_LIBRARY__
1522   /* Avoid forcing the library's meaning of `write' on the user program
1523      by using the "internal" name (for use within the library)  */
1524 #define write(fd, buf, n)       __write((fd), (buf), (n))
1525 #endif
1526 #endif /* inhibit_libc */
1527
1528 typedef void (*vfp)(void);
1529
1530 extern void *__builtin_new (size_t);
1531 static void default_new_handler (void);
1532
1533 vfp __new_handler = default_new_handler;
1534
1535 vfp
1536 __set_new_handler (handler)
1537      vfp handler;
1538 {
1539   vfp prev_handler;
1540
1541   prev_handler = __new_handler;
1542   if (handler == 0) handler = default_new_handler;
1543   __new_handler = handler;
1544   return prev_handler;
1545 }
1546
1547 vfp
1548 set_new_handler (handler)
1549      vfp handler;
1550 {
1551   return __set_new_handler (handler);
1552 }
1553
1554 #define MESSAGE "Virtual memory exceeded in `new'\n"
1555
1556 static void
1557 default_new_handler ()
1558 {
1559   /* don't use fprintf (stderr, ...) because it may need to call malloc.  */
1560   /* This should really print the name of the program, but that is hard to
1561      do.  We need a standard, clean way to get at the name.  */
1562   write (2, MESSAGE, sizeof (MESSAGE));
1563   /* don't call exit () because that may call global destructors which
1564      may cause a loop.  */
1565   _exit (-1);
1566 }
1567 #endif
1568
1569 #ifdef L_op_delete
1570 /* void operator delete (void *ptr) */
1571 void
1572 __builtin_delete (void *ptr)
1573 {
1574   if (ptr)
1575     free (ptr);
1576 }
1577 #endif
1578 \f
1579 #ifdef L_shtab
1580 unsigned int __shtab[] = {
1581     0x00000001, 0x00000002, 0x00000004, 0x00000008,
1582     0x00000010, 0x00000020, 0x00000040, 0x00000080,
1583     0x00000100, 0x00000200, 0x00000400, 0x00000800,
1584     0x00001000, 0x00002000, 0x00004000, 0x00008000,
1585     0x00010000, 0x00020000, 0x00040000, 0x00080000,
1586     0x00100000, 0x00200000, 0x00400000, 0x00800000,
1587     0x01000000, 0x02000000, 0x04000000, 0x08000000,
1588     0x10000000, 0x20000000, 0x40000000, 0x80000000
1589   };
1590 #endif
1591 \f
1592 #ifdef L_clear_cache
1593 /* Clear part of an instruction cache.  */
1594
1595 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1596
1597 void
1598 __clear_cache (beg, end)
1599      char *beg, *end;
1600 {
1601 #ifdef CLEAR_INSN_CACHE 
1602   CLEAR_INSN_CACHE (beg, end);
1603 #else
1604 #ifdef INSN_CACHE_SIZE
1605   static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1606   static int initialized = 0;
1607   int offset;
1608   void *start_addr
1609   void *end_addr;
1610   typedef (*function_ptr) ();
1611
1612 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1613   /* It's cheaper to clear the whole cache.
1614      Put in a series of jump instructions so that calling the beginning
1615      of the cache will clear the whole thing.  */
1616
1617   if (! initialized)
1618     {
1619       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1620                  & -INSN_CACHE_LINE_WIDTH);
1621       int end_ptr = ptr + INSN_CACHE_SIZE;
1622
1623       while (ptr < end_ptr)
1624         {
1625           *(INSTRUCTION_TYPE *)ptr
1626             = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1627           ptr += INSN_CACHE_LINE_WIDTH;
1628         }
1629       *(INSTRUCTION_TYPE *)(ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1630
1631       initialized = 1;
1632     }
1633
1634   /* Call the beginning of the sequence.  */
1635   (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1636                     & -INSN_CACHE_LINE_WIDTH))
1637    ());
1638
1639 #else /* Cache is large.  */
1640
1641   if (! initialized)
1642     {
1643       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1644                  & -INSN_CACHE_LINE_WIDTH);
1645
1646       while (ptr < (int) array + sizeof array)
1647         {
1648           *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1649           ptr += INSN_CACHE_LINE_WIDTH;
1650         }
1651
1652       initialized = 1;
1653     }
1654
1655   /* Find the location in array that occupies the same cache line as BEG.  */
1656
1657   offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1658   start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1659                  & -INSN_CACHE_PLANE_SIZE)
1660                 + offset);
1661
1662   /* Compute the cache alignment of the place to stop clearing.  */
1663 #if 0  /* This is not needed for gcc's purposes.  */
1664   /* If the block to clear is bigger than a cache plane,
1665      we clear the entire cache, and OFFSET is already correct.  */ 
1666   if (end < beg + INSN_CACHE_PLANE_SIZE)
1667 #endif
1668     offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1669                & -INSN_CACHE_LINE_WIDTH)
1670               & (INSN_CACHE_PLANE_SIZE - 1));
1671
1672 #if INSN_CACHE_DEPTH > 1
1673   end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1674   if (end_addr <= start_addr)
1675     end_addr += INSN_CACHE_PLANE_SIZE;
1676
1677   for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1678     {
1679       int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1680       int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1681
1682       while (addr != stop)
1683         {
1684           /* Call the return instruction at ADDR.  */
1685           ((function_ptr) addr) ();
1686
1687           addr += INSN_CACHE_LINE_WIDTH;
1688         }
1689     }
1690 #else /* just one plane */
1691   do
1692     {
1693       /* Call the return instruction at START_ADDR.  */
1694       ((function_ptr) start_addr) ();
1695
1696       start_addr += INSN_CACHE_LINE_WIDTH;
1697     }
1698   while ((start_addr % INSN_CACHE_SIZE) != offset);
1699 #endif /* just one plane */
1700 #endif /* Cache is large */
1701 #endif /* Cache exists */
1702 #endif /* CLEAR_INSN_CACHE */
1703 }
1704
1705 #endif /* L_clear_cache */
1706 \f
1707 #ifdef L_trampoline
1708
1709 /* Jump to a trampoline, loading the static chain address.  */
1710
1711 #ifdef TRANSFER_FROM_TRAMPOLINE 
1712 TRANSFER_FROM_TRAMPOLINE 
1713 #endif
1714
1715 #ifdef __convex__
1716
1717 /* Make stack executable so we can call trampolines on stack.
1718    This is called from INITIALIZE_TRAMPOLINE in convex.h.  */
1719
1720 #include <sys/mman.h>
1721 #include <sys/vmparam.h>
1722 #include <machine/machparam.h>
1723
1724 void
1725 __enable_execute_stack ()
1726 {
1727   int fp;
1728   static unsigned lowest = USRSTACK;
1729   unsigned current = (unsigned) &fp & -NBPG;
1730
1731   if (lowest > current)
1732     {
1733       unsigned len = lowest - current;
1734       mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
1735       lowest = current;
1736     }
1737
1738   /* Clear instruction cache in case an old trampoline is in it. */
1739   asm ("pich");
1740 }
1741 #endif /* __convex__ */
1742
1743 #ifdef __pyr__
1744
1745 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1746 #include <stdio.h>
1747 #include <sys/mman.h>
1748 #include <sys/types.h>
1749 #include <sys/param.h>
1750 #include <sys/vmmac.h>
1751
1752 /* Modified from the convex -code above.
1753    mremap promises to clear the i-cache. */
1754
1755 void
1756 __enable_execute_stack ()
1757 {
1758   int fp;
1759   if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
1760                 PROT_READ|PROT_WRITE|PROT_EXEC))
1761     {
1762       perror ("mprotect in __enable_execute_stack");
1763       fflush (stderr);
1764       abort ();
1765     }
1766 }
1767 #endif /* __pyr__ */
1768 #endif /* L_trampoline */
1769 \f
1770 #ifdef L__main
1771
1772 #include "gbl-ctors.h"
1773 /* Some systems use __main in a way incompatible with its use in gcc, in these
1774    cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
1775    give the same symbol without quotes for an alternative entry point.  You
1776    must define both, or niether. */
1777 #ifndef NAME__MAIN
1778 #define NAME__MAIN "__main"
1779 #define SYMBOL__MAIN __main
1780 #endif
1781
1782 /* Run all the global destructors on exit from the program.  */
1783
1784 void
1785 __do_global_dtors ()
1786 {
1787 #ifdef DO_GLOBAL_DTORS_BODY
1788   DO_GLOBAL_DTORS_BODY;
1789 #else
1790   unsigned nptrs = (unsigned HOST_WIDE_INT) __DTOR_LIST__[0];
1791   unsigned i;
1792
1793   /* Some systems place the number of pointers
1794      in the first word of the table.
1795      On other systems, that word is -1.
1796      In all cases, the table is null-terminated.  */
1797
1798   /* If the length is not recorded, count up to the null.  */
1799   if (nptrs == -1)
1800     for (nptrs = 0; __DTOR_LIST__[nptrs + 1] != 0; nptrs++);
1801
1802   /* GNU LD format.  */
1803   for (i = nptrs; i >= 1; i--)
1804     __DTOR_LIST__[i] ();
1805 #endif
1806 }
1807
1808 #ifndef INIT_SECTION_ASM_OP
1809 /* Run all the global constructors on entry to the program.  */
1810
1811 #ifndef ON_EXIT
1812 #define ON_EXIT(a, b)
1813 #else
1814 /* Make sure the exit routine is pulled in to define the globals as
1815    bss symbols, just in case the linker does not automatically pull
1816    bss definitions from the library.  */
1817
1818 extern int _exit_dummy_decl;
1819 int *_exit_dummy_ref = &_exit_dummy_decl;
1820 #endif /* ON_EXIT */
1821
1822 void
1823 __do_global_ctors ()
1824 {
1825   DO_GLOBAL_CTORS_BODY;
1826   ON_EXIT (__do_global_dtors, 0);
1827 }
1828 #endif /* no INIT_SECTION_ASM_OP */
1829
1830 #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
1831 /* Subroutine called automatically by `main'.
1832    Compiling a global function named `main'
1833    produces an automatic call to this function at the beginning.
1834
1835    For many systems, this routine calls __do_global_ctors.
1836    For systems which support a .init section we use the .init section
1837    to run __do_global_ctors, so we need not do anything here.  */
1838
1839 void
1840 SYMBOL__MAIN ()
1841 {
1842   /* Support recursive calls to `main': run initializers just once.  */
1843   static int initialized = 0;
1844   if (! initialized)
1845     {
1846       initialized = 1;
1847       __do_global_ctors ();
1848     }
1849 }
1850 #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
1851
1852 #endif /* L__main */
1853 \f
1854 #ifdef L_ctors
1855
1856 #include "gbl-ctors.h"
1857
1858 /* Provide default definitions for the lists of constructors and
1859    destructors, so that we don't get linker errors.  These symbols are
1860    intentionally bss symbols, so that gld and/or collect will provide
1861    the right values.  */
1862
1863 /* We declare the lists here with two elements each,
1864    so that they are valid empty lists if no other definition is loaded.  */
1865 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
1866 #ifdef __NeXT__
1867 /* After 2.3, try this definition on all systems.  */
1868 func_ptr __CTOR_LIST__[2] = {0, 0};
1869 func_ptr __DTOR_LIST__[2] = {0, 0};
1870 #else
1871 func_ptr __CTOR_LIST__[2];
1872 func_ptr __DTOR_LIST__[2];
1873 #endif
1874 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1875 #endif /* L_ctors */
1876 \f
1877 #ifdef L_exit
1878
1879 #include "gbl-ctors.h"
1880
1881 #ifndef ON_EXIT
1882
1883 /* If we have no known way of registering our own __do_global_dtors
1884    routine so that it will be invoked at program exit time, then we
1885    have to define our own exit routine which will get this to happen.  */
1886
1887 extern void __do_global_dtors ();
1888 extern void _cleanup ();
1889 extern volatile void _exit ();
1890
1891 void 
1892 exit (status)
1893      int status;
1894 {
1895   __do_global_dtors ();
1896 #ifdef EXIT_BODY
1897   EXIT_BODY;
1898 #else
1899   _cleanup ();
1900 #endif
1901   _exit (status);
1902 }
1903
1904 #else
1905 int _exit_dummy_decl = 0;       /* prevent compiler & linker warnings */
1906 #endif
1907
1908 #endif /* L_exit */
1909 \f
1910 /* In a.out systems, we need to have these dummy constructor and destructor
1911    lists in the library.
1912
1913    When using `collect', the first link will resolve __CTOR_LIST__
1914    and __DTOR_LIST__ to these symbols.  We will then run "nm" on the
1915    result, build the correct __CTOR_LIST__ and __DTOR_LIST__, and relink.
1916    Since we don't do the second link if no constructors existed, these
1917    dummies must be fully functional empty lists.
1918
1919    When using `gnu ld', these symbols will be used if there are no
1920    constructors.  If there are constructors, the N_SETV symbol defined
1921    by the linker from the N_SETT's in input files will define __CTOR_LIST__
1922    and __DTOR_LIST__ rather than its being allocated as common storage
1923    by the definitions below.
1924
1925    When using a linker that supports constructor and destructor segments,
1926    these definitions will not be used, since crtbegin.o and crtend.o
1927    (from crtstuff.c) will have already defined __CTOR_LIST__ and
1928     __DTOR_LIST__.  The crt*.o files are passed directly to the linker
1929    on its command line, by gcc.  */
1930
1931 /* The list needs two elements:  one is ignored (the old count); the
1932    second is the terminating zero.  Since both values are zero, this
1933    declaration is not initialized, and it becomes `common'.  */
1934
1935 #ifdef L_ctor_list
1936 #include "gbl-ctors.h"
1937 func_ptr __CTOR_LIST__[2];
1938 #endif
1939
1940 #ifdef L_dtor_list
1941 #include "gbl-ctors.h"
1942 func_ptr __DTOR_LIST__[2];
1943 #endif