OSDN Git Service

(__udiv_w_sdiv): If we don't have sdiv_qrnnd, define dummy variant of
[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, 1993, 1994, 1995 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, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22 /* As a special exception, if you link this library with other files,
23    some of which are compiled with GCC, to produce an executable,
24    this library does not by itself cause the resulting executable
25    to be covered by the GNU General Public License.
26    This exception does not however invalidate any other reasons why
27    the executable file might be covered by the GNU General Public License.  */
28
29 /* It is incorrect to include config.h here, because this file is being
30    compiled for the target, and hence definitions concerning only the host
31    do not apply.  */
32
33 #include "tconfig.h"
34 #include "machmode.h"
35 #include "defaults.h" 
36 #ifndef L_trampoline
37 #include <stddef.h>
38 #endif
39
40 /* Don't use `fancy_abort' here even if config.h says to use it.  */
41 #ifdef abort
42 #undef abort
43 #endif
44
45 #if (SUPPORTS_WEAK == 1) && defined (ASM_OUTPUT_DEF)
46 #define WEAK_ALIAS
47 #endif
48
49 /* Permit the tm.h file to select the endianness to use just for this
50    file.  This is used when the endianness is determined when the
51    compiler is run.  */
52
53 #ifndef LIBGCC2_WORDS_BIG_ENDIAN
54 #define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
55 #endif
56
57 /* In the first part of this file, we are interfacing to calls generated
58    by the compiler itself.  These calls pass values into these routines
59    which have very specific modes (rather than very specific types), and
60    these compiler-generated calls also expect any return values to have
61    very specific modes (rather than very specific types).  Thus, we need
62    to avoid using regular C language type names in this part of the file
63    because the sizes for those types can be configured to be anything.
64    Instead we use the following special type names.  */
65
66 typedef unsigned int UQItype    __attribute__ ((mode (QI)));
67 typedef          int SItype     __attribute__ ((mode (SI)));
68 typedef unsigned int USItype    __attribute__ ((mode (SI)));
69 typedef          int DItype     __attribute__ ((mode (DI)));
70 typedef unsigned int UDItype    __attribute__ ((mode (DI)));
71
72 typedef         float SFtype    __attribute__ ((mode (SF)));
73 typedef         float DFtype    __attribute__ ((mode (DF)));
74
75 #if LONG_DOUBLE_TYPE_SIZE == 96
76 typedef         float XFtype    __attribute__ ((mode (XF)));
77 #endif
78 #if LONG_DOUBLE_TYPE_SIZE == 128
79 typedef         float TFtype    __attribute__ ((mode (TF)));
80 #endif
81
82 typedef int word_type __attribute__ ((mode (__word__)));
83
84 /* Make sure that we don't accidentally use any normal C language built-in
85    type names in the first part of this file.  Instead we want to use *only*
86    the type names defined above.  The following macro definitions insure
87    that if we *do* accidentally use some normal C language built-in type name,
88    we will get a syntax error.  */
89
90 #define char bogus_type
91 #define short bogus_type
92 #define int bogus_type
93 #define long bogus_type
94 #define unsigned bogus_type
95 #define float bogus_type
96 #define double bogus_type
97
98 #define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
99
100 /* DIstructs are pairs of SItype values in the order determined by
101    LIBGCC2_WORDS_BIG_ENDIAN.  */
102
103 #if LIBGCC2_WORDS_BIG_ENDIAN
104   struct DIstruct {SItype high, low;};
105 #else
106   struct DIstruct {SItype low, high;};
107 #endif
108
109 /* We need this union to unpack/pack DImode values, since we don't have
110    any arithmetic yet.  Incoming DImode parameters are stored into the
111    `ll' field, and the unpacked result is read from the struct `s'.  */
112
113 typedef union
114 {
115   struct DIstruct s;
116   DItype ll;
117 } DIunion;
118
119 #if (defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_w_sdiv)\
120      || defined (L_divdi3) || defined (L_udivdi3) \
121      || defined (L_moddi3) || defined (L_umoddi3))
122
123 #include "longlong.h"
124
125 #endif /* udiv or mul */
126
127 extern DItype __fixunssfdi (SFtype a);
128 extern DItype __fixunsdfdi (DFtype a);
129 #if LONG_DOUBLE_TYPE_SIZE == 96
130 extern DItype __fixunsxfdi (XFtype a);
131 #endif
132 #if LONG_DOUBLE_TYPE_SIZE == 128
133 extern DItype __fixunstfdi (TFtype a);
134 #endif
135 \f
136 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
137 #if defined (L_divdi3) || defined (L_moddi3)
138 static inline
139 #endif
140 DItype
141 __negdi2 (u)
142      DItype u;
143 {
144   DIunion w;
145   DIunion uu;
146
147   uu.ll = u;
148
149   w.s.low = -uu.s.low;
150   w.s.high = -uu.s.high - ((USItype) w.s.low > 0);
151
152   return w.ll;
153 }
154 #endif
155 \f
156 #ifdef L_lshrdi3
157 DItype
158 __lshrdi3 (u, b)
159      DItype u;
160      word_type b;
161 {
162   DIunion w;
163   word_type bm;
164   DIunion uu;
165
166   if (b == 0)
167     return u;
168
169   uu.ll = u;
170
171   bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
172   if (bm <= 0)
173     {
174       w.s.high = 0;
175       w.s.low = (USItype)uu.s.high >> -bm;
176     }
177   else
178     {
179       USItype carries = (USItype)uu.s.high << bm;
180       w.s.high = (USItype)uu.s.high >> b;
181       w.s.low = ((USItype)uu.s.low >> b) | carries;
182     }
183
184   return w.ll;
185 }
186 #endif
187
188 #ifdef L_ashldi3
189 DItype
190 __ashldi3 (u, b)
191      DItype u;
192      word_type b;
193 {
194   DIunion w;
195   word_type bm;
196   DIunion uu;
197
198   if (b == 0)
199     return u;
200
201   uu.ll = u;
202
203   bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
204   if (bm <= 0)
205     {
206       w.s.low = 0;
207       w.s.high = (USItype)uu.s.low << -bm;
208     }
209   else
210     {
211       USItype carries = (USItype)uu.s.low >> bm;
212       w.s.low = (USItype)uu.s.low << b;
213       w.s.high = ((USItype)uu.s.high << b) | carries;
214     }
215
216   return w.ll;
217 }
218 #endif
219
220 #ifdef L_ashrdi3
221 DItype
222 __ashrdi3 (u, b)
223      DItype u;
224      word_type b;
225 {
226   DIunion w;
227   word_type bm;
228   DIunion uu;
229
230   if (b == 0)
231     return u;
232
233   uu.ll = u;
234
235   bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
236   if (bm <= 0)
237     {
238       /* w.s.high = 1..1 or 0..0 */
239       w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
240       w.s.low = uu.s.high >> -bm;
241     }
242   else
243     {
244       USItype carries = (USItype)uu.s.high << bm;
245       w.s.high = uu.s.high >> b;
246       w.s.low = ((USItype)uu.s.low >> b) | carries;
247     }
248
249   return w.ll;
250 }
251 #endif
252 \f
253 #ifdef L_ffsdi2
254 DItype
255 __ffsdi2 (u)
256      DItype u;
257 {
258   DIunion uu, w;
259   uu.ll = u;
260   w.s.high = 0;
261   w.s.low = ffs (uu.s.low);
262   if (w.s.low != 0)
263     return w.ll;
264   w.s.low = ffs (uu.s.high);
265   if (w.s.low != 0)
266     {
267       w.s.low += BITS_PER_UNIT * sizeof (SItype);
268       return w.ll;
269     }
270   return w.ll;
271 }
272 #endif
273 \f
274 #ifdef L_muldi3
275 DItype
276 __muldi3 (u, v)
277      DItype u, v;
278 {
279   DIunion w;
280   DIunion uu, vv;
281
282   uu.ll = u,
283   vv.ll = v;
284
285   w.ll = __umulsidi3 (uu.s.low, vv.s.low);
286   w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
287                + (USItype) uu.s.high * (USItype) vv.s.low);
288
289   return w.ll;
290 }
291 #endif
292 \f
293 #ifdef L_udiv_w_sdiv
294 #if defined (sdiv_qrnnd)
295 USItype
296 __udiv_w_sdiv (rp, a1, a0, d)
297      USItype *rp, a1, a0, d;
298 {
299   USItype q, r;
300   USItype c0, c1, b1;
301
302   if ((SItype) d >= 0)
303     {
304       if (a1 < d - a1 - (a0 >> (SI_TYPE_SIZE - 1)))
305         {
306           /* dividend, divisor, and quotient are nonnegative */
307           sdiv_qrnnd (q, r, a1, a0, d);
308         }
309       else
310         {
311           /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
312           sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (SI_TYPE_SIZE - 1));
313           /* Divide (c1*2^32 + c0) by d */
314           sdiv_qrnnd (q, r, c1, c0, d);
315           /* Add 2^31 to quotient */
316           q += (USItype) 1 << (SI_TYPE_SIZE - 1);
317         }
318     }
319   else
320     {
321       b1 = d >> 1;                      /* d/2, between 2^30 and 2^31 - 1 */
322       c1 = a1 >> 1;                     /* A/2 */
323       c0 = (a1 << (SI_TYPE_SIZE - 1)) + (a0 >> 1);
324
325       if (a1 < b1)                      /* A < 2^32*b1, so A/2 < 2^31*b1 */
326         {
327           sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
328
329           r = 2*r + (a0 & 1);           /* Remainder from A/(2*b1) */
330           if ((d & 1) != 0)
331             {
332               if (r >= q)
333                 r = r - q;
334               else if (q - r <= d)
335                 {
336                   r = r - q + d;
337                   q--;
338                 }
339               else
340                 {
341                   r = r - q + 2*d;
342                   q -= 2;
343                 }
344             }
345         }
346       else if (c1 < b1)                 /* So 2^31 <= (A/2)/b1 < 2^32 */
347         {
348           c1 = (b1 - 1) - c1;
349           c0 = ~c0;                     /* logical NOT */
350
351           sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
352
353           q = ~q;                       /* (A/2)/b1 */
354           r = (b1 - 1) - r;
355
356           r = 2*r + (a0 & 1);           /* A/(2*b1) */
357
358           if ((d & 1) != 0)
359             {
360               if (r >= q)
361                 r = r - q;
362               else if (q - r <= d)
363                 {
364                   r = r - q + d;
365                   q--;
366                 }
367               else
368                 {
369                   r = r - q + 2*d;
370                   q -= 2;
371                 }
372             }
373         }
374       else                              /* Implies c1 = b1 */
375         {                               /* Hence a1 = d - 1 = 2*b1 - 1 */
376           if (a0 >= -d)
377             {
378               q = -1;
379               r = a0 + d;
380             }
381           else
382             {
383               q = -2;
384               r = a0 + 2*d;
385             }
386         }
387     }
388
389   *rp = r;
390   return q;
391 }
392 #else
393 /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv.  */
394 USItype
395 __udiv_w_sdiv (rp, a1, a0, d)
396      USItype *rp, a1, a0, d;
397 {}
398 #endif
399 #endif
400 \f
401 #if (defined (L_udivdi3) || defined (L_divdi3) || \
402      defined (L_umoddi3) || defined (L_moddi3))
403 #define L_udivmoddi4
404 #endif
405
406 #ifdef L_udivmoddi4
407 static const UQItype __clz_tab[] =
408 {
409   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,
410   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,
411   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,
412   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,
413   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,
414   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,
415   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
416   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
417 };
418
419 #if (defined (L_udivdi3) || defined (L_divdi3) || \
420      defined (L_umoddi3) || defined (L_moddi3))
421 static inline
422 #endif
423 UDItype
424 __udivmoddi4 (n, d, rp)
425      UDItype n, d;
426      UDItype *rp;
427 {
428   DIunion ww;
429   DIunion nn, dd;
430   DIunion rr;
431   USItype d0, d1, n0, n1, n2;
432   USItype q0, q1;
433   USItype b, bm;
434
435   nn.ll = n;
436   dd.ll = d;
437
438   d0 = dd.s.low;
439   d1 = dd.s.high;
440   n0 = nn.s.low;
441   n1 = nn.s.high;
442
443 #if !UDIV_NEEDS_NORMALIZATION
444   if (d1 == 0)
445     {
446       if (d0 > n1)
447         {
448           /* 0q = nn / 0D */
449
450           udiv_qrnnd (q0, n0, n1, n0, d0);
451           q1 = 0;
452
453           /* Remainder in n0.  */
454         }
455       else
456         {
457           /* qq = NN / 0d */
458
459           if (d0 == 0)
460             d0 = 1 / d0;        /* Divide intentionally by zero.  */
461
462           udiv_qrnnd (q1, n1, 0, n1, d0);
463           udiv_qrnnd (q0, n0, n1, n0, d0);
464
465           /* Remainder in n0.  */
466         }
467
468       if (rp != 0)
469         {
470           rr.s.low = n0;
471           rr.s.high = 0;
472           *rp = rr.ll;
473         }
474     }
475
476 #else /* UDIV_NEEDS_NORMALIZATION */
477
478   if (d1 == 0)
479     {
480       if (d0 > n1)
481         {
482           /* 0q = nn / 0D */
483
484           count_leading_zeros (bm, d0);
485
486           if (bm != 0)
487             {
488               /* Normalize, i.e. make the most significant bit of the
489                  denominator set.  */
490
491               d0 = d0 << bm;
492               n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
493               n0 = n0 << bm;
494             }
495
496           udiv_qrnnd (q0, n0, n1, n0, d0);
497           q1 = 0;
498
499           /* Remainder in n0 >> bm.  */
500         }
501       else
502         {
503           /* qq = NN / 0d */
504
505           if (d0 == 0)
506             d0 = 1 / d0;        /* Divide intentionally by zero.  */
507
508           count_leading_zeros (bm, d0);
509
510           if (bm == 0)
511             {
512               /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
513                  conclude (the most significant bit of n1 is set) /\ (the
514                  leading quotient digit q1 = 1).
515
516                  This special case is necessary, not an optimization.
517                  (Shifts counts of SI_TYPE_SIZE are undefined.)  */
518
519               n1 -= d0;
520               q1 = 1;
521             }
522           else
523             {
524               /* Normalize.  */
525
526               b = SI_TYPE_SIZE - bm;
527
528               d0 = d0 << bm;
529               n2 = n1 >> b;
530               n1 = (n1 << bm) | (n0 >> b);
531               n0 = n0 << bm;
532
533               udiv_qrnnd (q1, n1, n2, n1, d0);
534             }
535
536           /* n1 != d0... */
537
538           udiv_qrnnd (q0, n0, n1, n0, d0);
539
540           /* Remainder in n0 >> bm.  */
541         }
542
543       if (rp != 0)
544         {
545           rr.s.low = n0 >> bm;
546           rr.s.high = 0;
547           *rp = rr.ll;
548         }
549     }
550 #endif /* UDIV_NEEDS_NORMALIZATION */
551
552   else
553     {
554       if (d1 > n1)
555         {
556           /* 00 = nn / DD */
557
558           q0 = 0;
559           q1 = 0;
560
561           /* Remainder in n1n0.  */
562           if (rp != 0)
563             {
564               rr.s.low = n0;
565               rr.s.high = n1;
566               *rp = rr.ll;
567             }
568         }
569       else
570         {
571           /* 0q = NN / dd */
572
573           count_leading_zeros (bm, d1);
574           if (bm == 0)
575             {
576               /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
577                  conclude (the most significant bit of n1 is set) /\ (the
578                  quotient digit q0 = 0 or 1).
579
580                  This special case is necessary, not an optimization.  */
581
582               /* The condition on the next line takes advantage of that
583                  n1 >= d1 (true due to program flow).  */
584               if (n1 > d1 || n0 >= d0)
585                 {
586                   q0 = 1;
587                   sub_ddmmss (n1, n0, n1, n0, d1, d0);
588                 }
589               else
590                 q0 = 0;
591
592               q1 = 0;
593
594               if (rp != 0)
595                 {
596                   rr.s.low = n0;
597                   rr.s.high = n1;
598                   *rp = rr.ll;
599                 }
600             }
601           else
602             {
603               USItype m1, m0;
604               /* Normalize.  */
605
606               b = SI_TYPE_SIZE - bm;
607
608               d1 = (d1 << bm) | (d0 >> b);
609               d0 = d0 << bm;
610               n2 = n1 >> b;
611               n1 = (n1 << bm) | (n0 >> b);
612               n0 = n0 << bm;
613
614               udiv_qrnnd (q0, n1, n2, n1, d1);
615               umul_ppmm (m1, m0, q0, d0);
616
617               if (m1 > n1 || (m1 == n1 && m0 > n0))
618                 {
619                   q0--;
620                   sub_ddmmss (m1, m0, m1, m0, d1, d0);
621                 }
622
623               q1 = 0;
624
625               /* Remainder in (n1n0 - m1m0) >> bm.  */
626               if (rp != 0)
627                 {
628                   sub_ddmmss (n1, n0, n1, n0, m1, m0);
629                   rr.s.low = (n1 << b) | (n0 >> bm);
630                   rr.s.high = n1 >> bm;
631                   *rp = rr.ll;
632                 }
633             }
634         }
635     }
636
637   ww.s.low = q0;
638   ww.s.high = q1;
639   return ww.ll;
640 }
641 #endif
642
643 #ifdef L_divdi3
644 UDItype __udivmoddi4 ();
645
646 DItype
647 __divdi3 (u, v)
648      DItype u, v;
649 {
650   word_type c = 0;
651   DIunion uu, vv;
652   DItype w;
653
654   uu.ll = u;
655   vv.ll = v;
656
657   if (uu.s.high < 0)
658     c = ~c,
659     uu.ll = __negdi2 (uu.ll);
660   if (vv.s.high < 0)
661     c = ~c,
662     vv.ll = __negdi2 (vv.ll);
663
664   w = __udivmoddi4 (uu.ll, vv.ll, (UDItype *) 0);
665   if (c)
666     w = __negdi2 (w);
667
668   return w;
669 }
670 #endif
671
672 #ifdef L_moddi3
673 UDItype __udivmoddi4 ();
674 DItype
675 __moddi3 (u, v)
676      DItype u, v;
677 {
678   word_type c = 0;
679   DIunion uu, vv;
680   DItype w;
681
682   uu.ll = u;
683   vv.ll = v;
684
685   if (uu.s.high < 0)
686     c = ~c,
687     uu.ll = __negdi2 (uu.ll);
688   if (vv.s.high < 0)
689     vv.ll = __negdi2 (vv.ll);
690
691   (void) __udivmoddi4 (uu.ll, vv.ll, &w);
692   if (c)
693     w = __negdi2 (w);
694
695   return w;
696 }
697 #endif
698
699 #ifdef L_umoddi3
700 UDItype __udivmoddi4 ();
701 UDItype
702 __umoddi3 (u, v)
703      UDItype u, v;
704 {
705   UDItype w;
706
707   (void) __udivmoddi4 (u, v, &w);
708
709   return w;
710 }
711 #endif
712
713 #ifdef L_udivdi3
714 UDItype __udivmoddi4 ();
715 UDItype
716 __udivdi3 (n, d)
717      UDItype n, d;
718 {
719   return __udivmoddi4 (n, d, (UDItype *) 0);
720 }
721 #endif
722 \f
723 #ifdef L_cmpdi2
724 word_type
725 __cmpdi2 (a, b)
726      DItype a, b;
727 {
728   DIunion au, bu;
729
730   au.ll = a, bu.ll = b;
731
732   if (au.s.high < bu.s.high)
733     return 0;
734   else if (au.s.high > bu.s.high)
735     return 2;
736   if ((USItype) au.s.low < (USItype) bu.s.low)
737     return 0;
738   else if ((USItype) au.s.low > (USItype) bu.s.low)
739     return 2;
740   return 1;
741 }
742 #endif
743
744 #ifdef L_ucmpdi2
745 word_type
746 __ucmpdi2 (a, b)
747      DItype a, b;
748 {
749   DIunion au, bu;
750
751   au.ll = a, bu.ll = b;
752
753   if ((USItype) au.s.high < (USItype) bu.s.high)
754     return 0;
755   else if ((USItype) au.s.high > (USItype) bu.s.high)
756     return 2;
757   if ((USItype) au.s.low < (USItype) bu.s.low)
758     return 0;
759   else if ((USItype) au.s.low > (USItype) bu.s.low)
760     return 2;
761   return 1;
762 }
763 #endif
764 \f
765 #if defined(L_fixunstfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
766 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
767 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
768
769 DItype
770 __fixunstfdi (a)
771      TFtype a;
772 {
773   TFtype b;
774   UDItype v;
775
776   if (a < 0)
777     return 0;
778
779   /* Compute high word of result, as a flonum.  */
780   b = (a / HIGH_WORD_COEFF);
781   /* Convert that to fixed (but not to DItype!),
782      and shift it into the high word.  */
783   v = (USItype) b;
784   v <<= WORD_SIZE;
785   /* Remove high part from the TFtype, leaving the low part as flonum.  */
786   a -= (TFtype)v;
787   /* Convert that to fixed (but not to DItype!) and add it in.
788      Sometimes A comes out negative.  This is significant, since
789      A has more bits than a long int does.  */
790   if (a < 0)
791     v -= (USItype) (- a);
792   else
793     v += (USItype) a;
794   return v;
795 }
796 #endif
797
798 #if defined(L_fixtfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
799 DItype
800 __fixtfdi (a)
801      TFtype a;
802 {
803   if (a < 0)
804     return - __fixunstfdi (-a);
805   return __fixunstfdi (a);
806 }
807 #endif
808
809 #if defined(L_fixunsxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
810 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
811 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
812
813 DItype
814 __fixunsxfdi (a)
815      XFtype a;
816 {
817   XFtype b;
818   UDItype v;
819
820   if (a < 0)
821     return 0;
822
823   /* Compute high word of result, as a flonum.  */
824   b = (a / HIGH_WORD_COEFF);
825   /* Convert that to fixed (but not to DItype!),
826      and shift it into the high word.  */
827   v = (USItype) b;
828   v <<= WORD_SIZE;
829   /* Remove high part from the XFtype, leaving the low part as flonum.  */
830   a -= (XFtype)v;
831   /* Convert that to fixed (but not to DItype!) and add it in.
832      Sometimes A comes out negative.  This is significant, since
833      A has more bits than a long int does.  */
834   if (a < 0)
835     v -= (USItype) (- a);
836   else
837     v += (USItype) a;
838   return v;
839 }
840 #endif
841
842 #if defined(L_fixxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
843 DItype
844 __fixxfdi (a)
845      XFtype a;
846 {
847   if (a < 0)
848     return - __fixunsxfdi (-a);
849   return __fixunsxfdi (a);
850 }
851 #endif
852
853 #ifdef L_fixunsdfdi
854 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
855 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
856
857 DItype
858 __fixunsdfdi (a)
859      DFtype a;
860 {
861   DFtype b;
862   UDItype v;
863
864   if (a < 0)
865     return 0;
866
867   /* Compute high word of result, as a flonum.  */
868   b = (a / HIGH_WORD_COEFF);
869   /* Convert that to fixed (but not to DItype!),
870      and shift it into the high word.  */
871   v = (USItype) b;
872   v <<= WORD_SIZE;
873   /* Remove high part from the DFtype, leaving the low part as flonum.  */
874   a -= (DFtype)v;
875   /* Convert that to fixed (but not to DItype!) and add it in.
876      Sometimes A comes out negative.  This is significant, since
877      A has more bits than a long int does.  */
878   if (a < 0)
879     v -= (USItype) (- a);
880   else
881     v += (USItype) a;
882   return v;
883 }
884 #endif
885
886 #ifdef L_fixdfdi
887 DItype
888 __fixdfdi (a)
889      DFtype a;
890 {
891   if (a < 0)
892     return - __fixunsdfdi (-a);
893   return __fixunsdfdi (a);
894 }
895 #endif
896
897 #ifdef L_fixunssfdi
898 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
899 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
900
901 DItype
902 __fixunssfdi (SFtype original_a)
903 {
904   /* Convert the SFtype to a DFtype, because that is surely not going
905      to lose any bits.  Some day someone else can write a faster version
906      that avoids converting to DFtype, and verify it really works right.  */
907   DFtype a = original_a;
908   DFtype b;
909   UDItype v;
910
911   if (a < 0)
912     return 0;
913
914   /* Compute high word of result, as a flonum.  */
915   b = (a / HIGH_WORD_COEFF);
916   /* Convert that to fixed (but not to DItype!),
917      and shift it into the high word.  */
918   v = (USItype) b;
919   v <<= WORD_SIZE;
920   /* Remove high part from the DFtype, leaving the low part as flonum.  */
921   a -= (DFtype)v;
922   /* Convert that to fixed (but not to DItype!) and add it in.
923      Sometimes A comes out negative.  This is significant, since
924      A has more bits than a long int does.  */
925   if (a < 0)
926     v -= (USItype) (- a);
927   else
928     v += (USItype) a;
929   return v;
930 }
931 #endif
932
933 #ifdef L_fixsfdi
934 DItype
935 __fixsfdi (SFtype a)
936 {
937   if (a < 0)
938     return - __fixunssfdi (-a);
939   return __fixunssfdi (a);
940 }
941 #endif
942
943 #if defined(L_floatdixf) && (LONG_DOUBLE_TYPE_SIZE == 96)
944 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
945 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
946 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
947
948 XFtype
949 __floatdixf (u)
950      DItype u;
951 {
952   XFtype d;
953   SItype negate = 0;
954
955   if (u < 0)
956     u = -u, negate = 1;
957
958   d = (USItype) (u >> WORD_SIZE);
959   d *= HIGH_HALFWORD_COEFF;
960   d *= HIGH_HALFWORD_COEFF;
961   d += (USItype) (u & (HIGH_WORD_COEFF - 1));
962
963   return (negate ? -d : d);
964 }
965 #endif
966
967 #if defined(L_floatditf) && (LONG_DOUBLE_TYPE_SIZE == 128)
968 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
969 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
970 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
971
972 TFtype
973 __floatditf (u)
974      DItype u;
975 {
976   TFtype d;
977   SItype negate = 0;
978
979   if (u < 0)
980     u = -u, negate = 1;
981
982   d = (USItype) (u >> WORD_SIZE);
983   d *= HIGH_HALFWORD_COEFF;
984   d *= HIGH_HALFWORD_COEFF;
985   d += (USItype) (u & (HIGH_WORD_COEFF - 1));
986
987   return (negate ? -d : d);
988 }
989 #endif
990
991 #ifdef L_floatdidf
992 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
993 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
994 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
995
996 DFtype
997 __floatdidf (u)
998      DItype u;
999 {
1000   DFtype d;
1001   SItype negate = 0;
1002
1003   if (u < 0)
1004     u = -u, negate = 1;
1005
1006   d = (USItype) (u >> WORD_SIZE);
1007   d *= HIGH_HALFWORD_COEFF;
1008   d *= HIGH_HALFWORD_COEFF;
1009   d += (USItype) (u & (HIGH_WORD_COEFF - 1));
1010
1011   return (negate ? -d : d);
1012 }
1013 #endif
1014
1015 #ifdef L_floatdisf
1016 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
1017 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
1018 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
1019 #define DI_SIZE (sizeof (DItype) * BITS_PER_UNIT)
1020
1021 /* Define codes for all the float formats that we know of.  Note
1022    that this is copied from real.h.  */
1023    
1024 #define UNKNOWN_FLOAT_FORMAT 0
1025 #define IEEE_FLOAT_FORMAT 1
1026 #define VAX_FLOAT_FORMAT 2
1027 #define IBM_FLOAT_FORMAT 3
1028
1029 /* Default to IEEE float if not specified.  Nearly all machines use it.  */
1030 #ifndef HOST_FLOAT_FORMAT
1031 #define HOST_FLOAT_FORMAT       IEEE_FLOAT_FORMAT
1032 #endif
1033
1034 #if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1035 #define DF_SIZE 53
1036 #define SF_SIZE 24
1037 #endif
1038
1039 #if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
1040 #define DF_SIZE 56
1041 #define SF_SIZE 24
1042 #endif
1043
1044 #if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
1045 #define DF_SIZE 56
1046 #define SF_SIZE 24
1047 #endif
1048
1049 SFtype
1050 __floatdisf (u)
1051      DItype u;
1052 {
1053   /* Do the calculation in DFmode
1054      so that we don't lose any of the precision of the high word
1055      while multiplying it.  */
1056   DFtype f;
1057   SItype negate = 0;
1058
1059   if (u < 0)
1060     u = -u, negate = 1;
1061
1062   /* Protect against double-rounding error.
1063      Represent any low-order bits, that might be truncated in DFmode,
1064      by a bit that won't be lost.  The bit can go in anywhere below the
1065      rounding position of the SFmode.  A fixed mask and bit position
1066      handles all usual configurations.  It doesn't handle the case
1067      of 128-bit DImode, however.  */
1068   if (DF_SIZE < DI_SIZE
1069       && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1070     {
1071 #define REP_BIT ((USItype) 1 << (DI_SIZE - DF_SIZE))
1072       if (u >= ((UDItype) 1 << DF_SIZE))
1073         {
1074           if ((USItype) u & (REP_BIT - 1))
1075             u |= REP_BIT;
1076         }
1077     }
1078   f = (USItype) (u >> WORD_SIZE);
1079   f *= HIGH_HALFWORD_COEFF;
1080   f *= HIGH_HALFWORD_COEFF;
1081   f += (USItype) (u & (HIGH_WORD_COEFF - 1));
1082
1083   return (SFtype) (negate ? -f : f);
1084 }
1085 #endif
1086
1087 #if defined(L_fixunsxfsi) && LONG_DOUBLE_TYPE_SIZE == 96
1088 /* Reenable the normal types, in case limits.h needs them.  */
1089 #undef char
1090 #undef short
1091 #undef int
1092 #undef long
1093 #undef unsigned
1094 #undef float
1095 #undef double
1096 #include <limits.h>
1097
1098 USItype
1099 __fixunsxfsi (a)
1100      XFtype a;
1101 {
1102   if (a >= - (DFtype) LONG_MIN)
1103     return (SItype) (a + LONG_MIN) - LONG_MIN;
1104   return (SItype) a;
1105 }
1106 #endif
1107
1108 #ifdef L_fixunsdfsi
1109 /* Reenable the normal types, in case limits.h needs them.  */
1110 #undef char
1111 #undef short
1112 #undef int
1113 #undef long
1114 #undef unsigned
1115 #undef float
1116 #undef double
1117 #include <limits.h>
1118
1119 USItype
1120 __fixunsdfsi (a)
1121      DFtype a;
1122 {
1123   if (a >= - (DFtype) LONG_MIN)
1124     return (SItype) (a + LONG_MIN) - LONG_MIN;
1125   return (SItype) a;
1126 }
1127 #endif
1128
1129 #ifdef L_fixunssfsi
1130 /* Reenable the normal types, in case limits.h needs them.  */
1131 #undef char
1132 #undef short
1133 #undef int
1134 #undef long
1135 #undef unsigned
1136 #undef float
1137 #undef double
1138 #include <limits.h>
1139
1140 USItype
1141 __fixunssfsi (SFtype a)
1142 {
1143   if (a >= - (SFtype) LONG_MIN)
1144     return (SItype) (a + LONG_MIN) - LONG_MIN;
1145   return (SItype) a;
1146 }
1147 #endif
1148 \f
1149 /* From here on down, the routines use normal data types.  */
1150
1151 #define SItype bogus_type
1152 #define USItype bogus_type
1153 #define DItype bogus_type
1154 #define UDItype bogus_type
1155 #define SFtype bogus_type
1156 #define DFtype bogus_type
1157
1158 #undef char
1159 #undef short
1160 #undef int
1161 #undef long
1162 #undef unsigned
1163 #undef float
1164 #undef double
1165 \f
1166 #ifdef L__gcc_bcmp
1167
1168 /* Like bcmp except the sign is meaningful.
1169    Result is negative if S1 is less than S2,
1170    positive if S1 is greater, 0 if S1 and S2 are equal.  */
1171
1172 int
1173 __gcc_bcmp (s1, s2, size)
1174      unsigned char *s1, *s2;
1175      size_t size;
1176 {
1177   while (size > 0)
1178     {
1179       unsigned char c1 = *s1++, c2 = *s2++;
1180       if (c1 != c2)
1181         return c1 - c2;
1182       size--;
1183     }
1184   return 0;
1185 }
1186
1187 #endif
1188 \f\f
1189 #ifdef L_varargs
1190 #ifdef __i860__
1191 #if defined(__svr4__) || defined(__alliant__)
1192         asm ("  .text");
1193         asm ("  .align  4");
1194
1195 /* The Alliant needs the added underscore.  */
1196         asm (".globl    __builtin_saveregs");
1197 asm ("__builtin_saveregs:");
1198         asm (".globl    ___builtin_saveregs");
1199 asm ("___builtin_saveregs:");
1200
1201         asm ("  andnot  0x0f,%sp,%sp"); /* round down to 16-byte boundary */
1202         asm ("  adds    -96,%sp,%sp");  /* allocate stack space for reg save
1203                                            area and also for a new va_list
1204                                            structure */
1205         /* Save all argument registers in the arg reg save area.  The
1206            arg reg save area must have the following layout (according
1207            to the svr4 ABI):
1208
1209                 struct {
1210                   union  {
1211                     float freg[8];
1212                     double dreg[4];
1213                   } float_regs;
1214                   long  ireg[12];
1215                 };
1216         */
1217
1218         asm ("  fst.q   %f8,  0(%sp)"); /* save floating regs (f8-f15)  */
1219         asm ("  fst.q   %f12,16(%sp)"); 
1220
1221         asm ("  st.l    %r16,32(%sp)"); /* save integer regs (r16-r27) */
1222         asm ("  st.l    %r17,36(%sp)"); 
1223         asm ("  st.l    %r18,40(%sp)");
1224         asm ("  st.l    %r19,44(%sp)");
1225         asm ("  st.l    %r20,48(%sp)");
1226         asm ("  st.l    %r21,52(%sp)");
1227         asm ("  st.l    %r22,56(%sp)");
1228         asm ("  st.l    %r23,60(%sp)");
1229         asm ("  st.l    %r24,64(%sp)");
1230         asm ("  st.l    %r25,68(%sp)");
1231         asm ("  st.l    %r26,72(%sp)");
1232         asm ("  st.l    %r27,76(%sp)");
1233
1234         asm ("  adds    80,%sp,%r16");  /* compute the address of the new
1235                                            va_list structure.  Put in into
1236                                            r16 so that it will be returned
1237                                            to the caller.  */
1238
1239         /* Initialize all fields of the new va_list structure.  This
1240            structure looks like:
1241
1242                 typedef struct {
1243                     unsigned long       ireg_used;
1244                     unsigned long       freg_used;
1245                     long                *reg_base;
1246                     long                *mem_ptr;
1247                 } va_list;
1248         */
1249
1250         asm ("  st.l    %r0, 0(%r16)"); /* nfixed */
1251         asm ("  st.l    %r0, 4(%r16)"); /* nfloating */
1252         asm ("  st.l    %sp, 8(%r16)"); /* __va_ctl points to __va_struct.  */
1253         asm ("  bri     %r1");          /* delayed return */
1254         asm ("  st.l    %r28,12(%r16)"); /* pointer to overflow args */
1255
1256 #else /* not __svr4__ */
1257 #if defined(__PARAGON__)
1258         /*
1259          *      we'll use SVR4-ish varargs but need SVR3.2 assembler syntax,
1260          *      and we stand a better chance of hooking into libraries
1261          *      compiled by PGI.  [andyp@ssd.intel.com]
1262          */
1263         asm ("  .text");
1264         asm ("  .align  4");
1265         asm (".globl    __builtin_saveregs");
1266 asm ("__builtin_saveregs:");
1267         asm (".globl    ___builtin_saveregs");
1268 asm ("___builtin_saveregs:");
1269
1270         asm ("  andnot  0x0f,sp,sp");   /* round down to 16-byte boundary */
1271         asm ("  adds    -96,sp,sp");    /* allocate stack space for reg save
1272                                            area and also for a new va_list
1273                                            structure */
1274         /* Save all argument registers in the arg reg save area.  The
1275            arg reg save area must have the following layout (according
1276            to the svr4 ABI):
1277
1278                 struct {
1279                   union  {
1280                     float freg[8];
1281                     double dreg[4];
1282                   } float_regs;
1283                   long  ireg[12];
1284                 };
1285         */
1286
1287         asm ("  fst.q   f8,  0(sp)");
1288         asm ("  fst.q   f12,16(sp)"); 
1289         asm ("  st.l    r16,32(sp)");
1290         asm ("  st.l    r17,36(sp)"); 
1291         asm ("  st.l    r18,40(sp)");
1292         asm ("  st.l    r19,44(sp)");
1293         asm ("  st.l    r20,48(sp)");
1294         asm ("  st.l    r21,52(sp)");
1295         asm ("  st.l    r22,56(sp)");
1296         asm ("  st.l    r23,60(sp)");
1297         asm ("  st.l    r24,64(sp)");
1298         asm ("  st.l    r25,68(sp)");
1299         asm ("  st.l    r26,72(sp)");
1300         asm ("  st.l    r27,76(sp)");
1301
1302         asm ("  adds    80,sp,r16");  /* compute the address of the new
1303                                            va_list structure.  Put in into
1304                                            r16 so that it will be returned
1305                                            to the caller.  */
1306
1307         /* Initialize all fields of the new va_list structure.  This
1308            structure looks like:
1309
1310                 typedef struct {
1311                     unsigned long       ireg_used;
1312                     unsigned long       freg_used;
1313                     long                *reg_base;
1314                     long                *mem_ptr;
1315                 } va_list;
1316         */
1317
1318         asm ("  st.l    r0, 0(r16)"); /* nfixed */
1319         asm ("  st.l    r0, 4(r16)"); /* nfloating */
1320         asm ("  st.l    sp, 8(r16)"); /* __va_ctl points to __va_struct.  */
1321         asm ("  bri     r1");           /* delayed return */
1322         asm ("   st.l   r28,12(r16)"); /* pointer to overflow args */
1323 #else /* not __PARAGON__ */
1324         asm ("  .text");
1325         asm ("  .align  4");
1326
1327         asm (".globl    ___builtin_saveregs");
1328         asm ("___builtin_saveregs:");
1329         asm ("  mov     sp,r30");
1330         asm ("  andnot  0x0f,sp,sp");
1331         asm ("  adds    -96,sp,sp");  /* allocate sufficient space on the stack */
1332
1333 /* Fill in the __va_struct.  */
1334         asm ("  st.l    r16, 0(sp)"); /* save integer regs (r16-r27) */
1335         asm ("  st.l    r17, 4(sp)"); /* int    fixed[12] */
1336         asm ("  st.l    r18, 8(sp)");
1337         asm ("  st.l    r19,12(sp)");
1338         asm ("  st.l    r20,16(sp)");
1339         asm ("  st.l    r21,20(sp)");
1340         asm ("  st.l    r22,24(sp)");
1341         asm ("  st.l    r23,28(sp)");
1342         asm ("  st.l    r24,32(sp)");
1343         asm ("  st.l    r25,36(sp)");
1344         asm ("  st.l    r26,40(sp)");
1345         asm ("  st.l    r27,44(sp)");
1346
1347         asm ("  fst.q   f8, 48(sp)"); /* save floating regs (f8-f15) */
1348         asm ("  fst.q   f12,64(sp)"); /* int floating[8] */
1349
1350 /* Fill in the __va_ctl.  */
1351         asm ("  st.l    sp, 80(sp)"); /* __va_ctl points to __va_struct.  */
1352         asm ("  st.l    r28,84(sp)"); /* pointer to more args */
1353         asm ("  st.l    r0, 88(sp)"); /* nfixed */
1354         asm ("  st.l    r0, 92(sp)"); /* nfloating */
1355
1356         asm ("  adds    80,sp,r16");  /* return address of the __va_ctl.  */
1357         asm ("  bri     r1");
1358         asm ("  mov     r30,sp");
1359                                 /* recover stack and pass address to start 
1360                                    of data.  */
1361 #endif /* not __PARAGON__ */
1362 #endif /* not __svr4__ */
1363 #else /* not __i860__ */
1364 #ifdef __sparc__
1365         asm (".global __builtin_saveregs");
1366         asm ("__builtin_saveregs:");
1367         asm (".global ___builtin_saveregs");
1368         asm ("___builtin_saveregs:");
1369 #ifdef NEED_PROC_COMMAND
1370         asm (".proc 020");
1371 #endif
1372         asm ("st %i0,[%fp+68]");
1373         asm ("st %i1,[%fp+72]");
1374         asm ("st %i2,[%fp+76]");
1375         asm ("st %i3,[%fp+80]");
1376         asm ("st %i4,[%fp+84]");
1377         asm ("retl");
1378         asm ("st %i5,[%fp+88]");
1379 #ifdef NEED_TYPE_COMMAND
1380         asm (".type __builtin_saveregs,#function");
1381         asm (".size __builtin_saveregs,.-__builtin_saveregs");
1382 #endif
1383 #else /* not __sparc__ */
1384 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1385
1386   asm ("        .text");
1387   asm ("        .ent __builtin_saveregs");
1388   asm ("        .globl __builtin_saveregs");
1389   asm ("__builtin_saveregs:");
1390   asm ("        sw      $4,0($30)");
1391   asm ("        sw      $5,4($30)");
1392   asm ("        sw      $6,8($30)");
1393   asm ("        sw      $7,12($30)");
1394   asm ("        j       $31");
1395   asm ("        .end __builtin_saveregs");
1396 #else /* not __mips__, etc. */
1397
1398 void *
1399 __builtin_saveregs ()
1400 {
1401   abort ();
1402 }
1403
1404 #endif /* not __mips__ */
1405 #endif /* not __sparc__ */
1406 #endif /* not __i860__ */
1407 #endif
1408 \f
1409 #ifdef L_eprintf
1410 #ifndef inhibit_libc
1411
1412 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1413 #include <stdio.h>
1414 /* This is used by the `assert' macro.  */
1415 void
1416 __eprintf (string, expression, line, filename)
1417      const char *string;
1418      const char *expression;
1419      int line;
1420      const char *filename;
1421 {
1422   fprintf (stderr, string, expression, line, filename);
1423   fflush (stderr);
1424   abort ();
1425 }
1426
1427 #endif
1428 #endif
1429
1430 #ifdef L_bb
1431
1432 /* Structure emitted by -a  */
1433 struct bb
1434 {
1435   long zero_word;
1436   const char *filename;
1437   long *counts;
1438   long ncounts;
1439   struct bb *next;
1440   const unsigned long *addresses;
1441
1442   /* Older GCC's did not emit these fields.  */
1443   long nwords;
1444   const char **functions;
1445   const long *line_nums;
1446   const char **filenames;
1447 };
1448
1449 #ifdef BLOCK_PROFILER_CODE
1450 BLOCK_PROFILER_CODE
1451 #else
1452 #ifndef inhibit_libc
1453
1454 /* Simple minded basic block profiling output dumper for
1455    systems that don't provide tcov support.  At present,
1456    it requires atexit and stdio.  */
1457
1458 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1459 #include <stdio.h>
1460 char *ctime ();
1461
1462 #ifdef HAVE_ATEXIT
1463 #ifdef WINNT
1464 extern int atexit (void (*) (void));
1465 #else
1466 extern void atexit (void (*) (void));
1467 #endif
1468 #define ON_EXIT(FUNC,ARG) atexit ((FUNC))
1469 #else
1470 #ifdef sun
1471 extern void on_exit (void*, void*);
1472 #define ON_EXIT(FUNC,ARG) on_exit ((FUNC), (ARG))
1473 #endif
1474 #endif
1475
1476 static struct bb *bb_head;
1477
1478 /* Return the number of digits needed to print a value */
1479 /* __inline__ */ static int num_digits (long value, int base)
1480 {
1481   int minus = (value < 0 && base != 16);
1482   unsigned long v = (minus) ? -value : value;
1483   int ret = minus;
1484
1485   do
1486     {
1487       v /= base;
1488       ret++;
1489     }
1490   while (v);
1491
1492   return ret;
1493 }
1494
1495 void
1496 __bb_exit_func (void)
1497 {
1498   FILE *file = fopen ("bb.out", "a");
1499   long time_value;
1500
1501   if (!file)
1502     perror ("bb.out");
1503
1504   else
1505     {
1506       struct bb *ptr;
1507
1508       /* This is somewhat type incorrect, but it avoids worrying about
1509          exactly where time.h is included from.  It should be ok unless
1510          a void * differs from other pointer formats, or if sizeof(long)
1511          is < sizeof (time_t).  It would be nice if we could assume the
1512          use of rationale standards here.  */
1513
1514       time((void *) &time_value);
1515       fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value));
1516
1517       /* We check the length field explicitly in order to allow compatibility
1518          with older GCC's which did not provide it.  */
1519
1520       for (ptr = bb_head; ptr != (struct bb *)0; ptr = ptr->next)
1521         {
1522           int i;
1523           int func_p    = (ptr->nwords >= sizeof (struct bb) && ptr->nwords <= 1000);
1524           int line_p    = (func_p && ptr->line_nums);
1525           int file_p    = (func_p && ptr->filenames);
1526           long ncounts  = ptr->ncounts;
1527           long cnt_max  = 0;
1528           long line_max = 0;
1529           long addr_max = 0;
1530           int file_len  = 0;
1531           int func_len  = 0;
1532           int blk_len   = num_digits (ncounts, 10);
1533           int cnt_len;
1534           int line_len;
1535           int addr_len;
1536
1537           fprintf (file, "File %s, %ld basic blocks \n\n",
1538                    ptr->filename, ncounts);
1539
1540           /* Get max values for each field.  */
1541           for (i = 0; i < ncounts; i++)
1542             {
1543               const char *p;
1544               int len;
1545
1546               if (cnt_max < ptr->counts[i])
1547                 cnt_max = ptr->counts[i];
1548
1549               if (addr_max < ptr->addresses[i])
1550                 addr_max = ptr->addresses[i];
1551
1552               if (line_p && line_max < ptr->line_nums[i])
1553                 line_max = ptr->line_nums[i];
1554
1555               if (func_p)
1556                 {
1557                   p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>";
1558                   len = strlen (p);
1559                   if (func_len < len)
1560                     func_len = len;
1561                 }
1562
1563               if (file_p)
1564                 {
1565                   p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>";
1566                   len = strlen (p);
1567                   if (file_len < len)
1568                     file_len = len;
1569                 }
1570             }
1571
1572           addr_len = num_digits (addr_max, 16);
1573           cnt_len  = num_digits (cnt_max, 10);
1574           line_len = num_digits (line_max, 10);
1575
1576           /* Now print out the basic block information.  */
1577           for (i = 0; i < ncounts; i++)
1578             {
1579               fprintf (file,
1580                        "    Block #%*d: executed %*ld time(s) address= 0x%.*lx",
1581                        blk_len, i+1,
1582                        cnt_len, ptr->counts[i],
1583                        addr_len, ptr->addresses[i]);
1584
1585               if (func_p)
1586                 fprintf (file, " function= %-*s", func_len,
1587                          (ptr->functions[i]) ? ptr->functions[i] : "<none>");
1588
1589               if (line_p)
1590                 fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]);
1591
1592               if (file_p)
1593                 fprintf (file, " file= %s",
1594                          (ptr->filenames[i]) ? ptr->filenames[i] : "<none>");
1595
1596               fprintf (file, "\n");
1597             }
1598
1599           fprintf (file, "\n");
1600           fflush (file);
1601         }
1602
1603       fprintf (file, "\n\n");
1604       fclose (file);
1605     }
1606 }
1607
1608 void
1609 __bb_init_func (struct bb *blocks)
1610 {
1611   /* User is supposed to check whether the first word is non-0,
1612      but just in case.... */
1613
1614   if (blocks->zero_word)
1615     return;
1616
1617 #ifdef ON_EXIT
1618   /* Initialize destructor.  */
1619   if (!bb_head)
1620     ON_EXIT (__bb_exit_func, 0);
1621 #endif
1622
1623   /* Set up linked list.  */
1624   blocks->zero_word = 1;
1625   blocks->next = bb_head;
1626   bb_head = blocks;
1627 }
1628
1629 #endif /* not inhibit_libc */
1630 #endif /* not BLOCK_PROFILER_CODE */
1631 #endif /* L_bb */
1632 \f
1633 /* Default free-store management functions for C++, per sections 12.5 and
1634    17.3.3 of the Working Paper. */
1635
1636 #ifdef L_op_new
1637 /* operator new (size_t), described in 17.3.3.5.  This function is used by
1638    C++ programs to allocate a block of memory to hold a single object. */
1639
1640 typedef void (*vfp)(void);
1641 extern vfp __new_handler;
1642 extern void __default_new_handler (void);
1643
1644 #ifdef WEAK_ALIAS
1645 void * __builtin_new (size_t sz)
1646      __attribute__ ((weak, alias ("___builtin_new")));
1647 void *
1648 ___builtin_new (size_t sz)
1649 #else
1650 void *
1651 __builtin_new (size_t sz)
1652 #endif
1653 {
1654   void *p;
1655   vfp handler = (__new_handler) ? __new_handler : __default_new_handler;
1656
1657   /* malloc (0) is unpredictable; avoid it.  */
1658   if (sz == 0)
1659     sz = 1;
1660   p = (void *) malloc (sz);
1661   while (p == 0)
1662     {
1663       (*handler) ();
1664       p = (void *) malloc (sz);
1665     }
1666   
1667   return p;
1668 }
1669 #endif /* L_op_new */
1670
1671 #ifdef L_op_vnew
1672 /* void * operator new [] (size_t), described in 17.3.3.6.  This function
1673    is used by C++ programs to allocate a block of memory for an array.  */
1674
1675 extern void * __builtin_new (size_t);
1676
1677 #ifdef WEAK_ALIAS
1678 void * __builtin_vec_new (size_t sz)
1679      __attribute__ ((weak, alias ("___builtin_vec_new")));
1680 void *
1681 ___builtin_vec_new (size_t sz)
1682 #else
1683 void *
1684 __builtin_vec_new (size_t sz)
1685 #endif
1686 {
1687   return __builtin_new (sz);
1688 }
1689 #endif /* L_op_vnew */
1690
1691 #ifdef L_new_handler
1692 /* set_new_handler (fvoid_t *) and the default new handler, described in
1693    17.3.3.2 and 17.3.3.5.  These functions define the result of a failure
1694    to allocate the amount of memory requested from operator new or new []. */
1695
1696 #ifndef inhibit_libc
1697 /* This gets us __GNU_LIBRARY__.  */
1698 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1699 #include <stdio.h>
1700
1701 #ifdef __GNU_LIBRARY__
1702   /* Avoid forcing the library's meaning of `write' on the user program
1703      by using the "internal" name (for use within the library)  */
1704 #define write(fd, buf, n)       __write((fd), (buf), (n))
1705 #endif
1706 #endif /* inhibit_libc */
1707
1708 typedef void (*vfp)(void);
1709 void __default_new_handler (void);
1710
1711 vfp __new_handler = (vfp)0;
1712
1713 vfp
1714 set_new_handler (vfp handler)
1715 {
1716   vfp prev_handler;
1717
1718   prev_handler = __new_handler;
1719   if (handler == 0) handler = __default_new_handler;
1720   __new_handler = handler;
1721   return prev_handler;
1722 }
1723
1724 #define MESSAGE "Virtual memory exceeded in `new'\n"
1725
1726 void
1727 __default_new_handler ()
1728 {
1729 #ifndef inhibit_libc
1730   /* don't use fprintf (stderr, ...) because it may need to call malloc.  */
1731   /* This should really print the name of the program, but that is hard to
1732      do.  We need a standard, clean way to get at the name.  */
1733   write (2, MESSAGE, sizeof (MESSAGE));
1734 #endif
1735   /* don't call exit () because that may call global destructors which
1736      may cause a loop.  */
1737   _exit (-1);
1738 }
1739 #endif
1740
1741 #ifdef L_op_delete
1742 /* operator delete (void *), described in 17.3.3.3.  This function is used
1743    by C++ programs to return to the free store a block of memory allocated
1744    as a single object. */
1745
1746 #ifdef WEAK_ALIAS
1747 void __builtin_delete (void *ptr)
1748      __attribute__ ((weak, alias ("___builtin_delete")));
1749 void
1750 ___builtin_delete (void *ptr)
1751 #else
1752 void
1753 __builtin_delete (void *ptr)
1754 #endif
1755 {
1756   if (ptr)
1757     free (ptr);
1758 }
1759 #endif
1760
1761 #ifdef L_op_vdel
1762 /* operator delete [] (void *), described in 17.3.3.4.  This function is
1763    used by C++ programs to return to the free store a block of memory
1764    allocated as an array. */
1765
1766 extern void __builtin_delete (void *);
1767
1768 #ifdef WEAK_ALIAS
1769 void __builtin_vec_delete (void *ptr)
1770      __attribute__ ((weak, alias ("___builtin_vec_delete")));
1771 void
1772 ___builtin_vec_delete (void *ptr)
1773 #else
1774 void
1775 __builtin_vec_delete (void *ptr)
1776 #endif
1777 {
1778   __builtin_delete (ptr);
1779 }
1780 #endif
1781
1782 /* End of C++ free-store management functions */
1783 \f
1784 #ifdef L_shtab
1785 unsigned int __shtab[] = {
1786     0x00000001, 0x00000002, 0x00000004, 0x00000008,
1787     0x00000010, 0x00000020, 0x00000040, 0x00000080,
1788     0x00000100, 0x00000200, 0x00000400, 0x00000800,
1789     0x00001000, 0x00002000, 0x00004000, 0x00008000,
1790     0x00010000, 0x00020000, 0x00040000, 0x00080000,
1791     0x00100000, 0x00200000, 0x00400000, 0x00800000,
1792     0x01000000, 0x02000000, 0x04000000, 0x08000000,
1793     0x10000000, 0x20000000, 0x40000000, 0x80000000
1794   };
1795 #endif
1796 \f
1797 #ifdef L_clear_cache
1798 /* Clear part of an instruction cache.  */
1799
1800 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1801
1802 void
1803 __clear_cache (beg, end)
1804      char *beg, *end;
1805 {
1806 #ifdef CLEAR_INSN_CACHE 
1807   CLEAR_INSN_CACHE (beg, end);
1808 #else
1809 #ifdef INSN_CACHE_SIZE
1810   static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1811   static int initialized;
1812   int offset;
1813   void *start_addr
1814   void *end_addr;
1815   typedef (*function_ptr) ();
1816
1817 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1818   /* It's cheaper to clear the whole cache.
1819      Put in a series of jump instructions so that calling the beginning
1820      of the cache will clear the whole thing.  */
1821
1822   if (! initialized)
1823     {
1824       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1825                  & -INSN_CACHE_LINE_WIDTH);
1826       int end_ptr = ptr + INSN_CACHE_SIZE;
1827
1828       while (ptr < end_ptr)
1829         {
1830           *(INSTRUCTION_TYPE *)ptr
1831             = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1832           ptr += INSN_CACHE_LINE_WIDTH;
1833         }
1834       *(INSTRUCTION_TYPE *)(ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1835
1836       initialized = 1;
1837     }
1838
1839   /* Call the beginning of the sequence.  */
1840   (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1841                     & -INSN_CACHE_LINE_WIDTH))
1842    ());
1843
1844 #else /* Cache is large.  */
1845
1846   if (! initialized)
1847     {
1848       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1849                  & -INSN_CACHE_LINE_WIDTH);
1850
1851       while (ptr < (int) array + sizeof array)
1852         {
1853           *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1854           ptr += INSN_CACHE_LINE_WIDTH;
1855         }
1856
1857       initialized = 1;
1858     }
1859
1860   /* Find the location in array that occupies the same cache line as BEG.  */
1861
1862   offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1863   start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1864                  & -INSN_CACHE_PLANE_SIZE)
1865                 + offset);
1866
1867   /* Compute the cache alignment of the place to stop clearing.  */
1868 #if 0  /* This is not needed for gcc's purposes.  */
1869   /* If the block to clear is bigger than a cache plane,
1870      we clear the entire cache, and OFFSET is already correct.  */ 
1871   if (end < beg + INSN_CACHE_PLANE_SIZE)
1872 #endif
1873     offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1874                & -INSN_CACHE_LINE_WIDTH)
1875               & (INSN_CACHE_PLANE_SIZE - 1));
1876
1877 #if INSN_CACHE_DEPTH > 1
1878   end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1879   if (end_addr <= start_addr)
1880     end_addr += INSN_CACHE_PLANE_SIZE;
1881
1882   for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1883     {
1884       int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1885       int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1886
1887       while (addr != stop)
1888         {
1889           /* Call the return instruction at ADDR.  */
1890           ((function_ptr) addr) ();
1891
1892           addr += INSN_CACHE_LINE_WIDTH;
1893         }
1894     }
1895 #else /* just one plane */
1896   do
1897     {
1898       /* Call the return instruction at START_ADDR.  */
1899       ((function_ptr) start_addr) ();
1900
1901       start_addr += INSN_CACHE_LINE_WIDTH;
1902     }
1903   while ((start_addr % INSN_CACHE_SIZE) != offset);
1904 #endif /* just one plane */
1905 #endif /* Cache is large */
1906 #endif /* Cache exists */
1907 #endif /* CLEAR_INSN_CACHE */
1908 }
1909
1910 #endif /* L_clear_cache */
1911 \f
1912 #ifdef L_trampoline
1913
1914 /* Jump to a trampoline, loading the static chain address.  */
1915
1916 #ifdef TRANSFER_FROM_TRAMPOLINE 
1917 TRANSFER_FROM_TRAMPOLINE 
1918 #endif
1919
1920 #if defined (NeXT) && defined (__MACH__)
1921
1922 /* Make stack executable so we can call trampolines on stack.
1923    This is called from INITIALIZE_TRAMPOLINE in next.h.  */
1924 #ifdef NeXTStep21
1925  #include <mach.h>
1926 #else
1927  #include <mach/mach.h>
1928 #endif
1929
1930 void
1931 __enable_execute_stack (addr)
1932      char *addr;
1933 {
1934   kern_return_t r;
1935   char *eaddr = addr + TRAMPOLINE_SIZE;
1936   vm_address_t a = (vm_address_t) addr;
1937
1938   /* turn on execute access on stack */
1939   r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
1940   if (r != KERN_SUCCESS)
1941     {
1942       mach_error("vm_protect VM_PROT_ALL", r);
1943       exit(1);
1944     }
1945
1946   /* We inline the i-cache invalidation for speed */
1947
1948 #ifdef CLEAR_INSN_CACHE
1949   CLEAR_INSN_CACHE (addr, eaddr);
1950 #else
1951   __clear_cache ((int) addr, (int) eaddr);
1952 #endif
1953
1954
1955 #endif /* defined (NeXT) && defined (__MACH__) */
1956
1957 #ifdef __convex__
1958
1959 /* Make stack executable so we can call trampolines on stack.
1960    This is called from INITIALIZE_TRAMPOLINE in convex.h.  */
1961
1962 #include <sys/mman.h>
1963 #include <sys/vmparam.h>
1964 #include <machine/machparam.h>
1965
1966 void
1967 __enable_execute_stack ()
1968 {
1969   int fp;
1970   static unsigned lowest = USRSTACK;
1971   unsigned current = (unsigned) &fp & -NBPG;
1972
1973   if (lowest > current)
1974     {
1975       unsigned len = lowest - current;
1976       mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
1977       lowest = current;
1978     }
1979
1980   /* Clear instruction cache in case an old trampoline is in it. */
1981   asm ("pich");
1982 }
1983 #endif /* __convex__ */
1984
1985 #ifdef __DOLPHIN__
1986
1987 /* Modified from the convex -code above. */
1988
1989 #include <sys/param.h>
1990 #include <errno.h>
1991 #include <sys/m88kbcs.h>
1992
1993 void
1994 __enable_execute_stack ()
1995 {
1996   int save_errno;
1997   static unsigned long lowest = USRSTACK;
1998   unsigned long current = (unsigned long) &save_errno & -NBPC;
1999   
2000   /* Ignore errno being set. memctl sets errno to EINVAL whenever the
2001      address is seen as 'negative'. That is the case with the stack.   */
2002
2003   save_errno=errno;
2004   if (lowest > current)
2005     {
2006       unsigned len=lowest-current;
2007       memctl(current,len,MCT_TEXT);
2008       lowest = current;
2009     }
2010   else
2011     memctl(current,NBPC,MCT_TEXT);
2012   errno=save_errno;
2013 }
2014
2015 #endif /* __DOLPHIN__ */
2016
2017 #ifdef __pyr__
2018
2019 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
2020 #include <stdio.h>
2021 #include <sys/mman.h>
2022 #include <sys/types.h>
2023 #include <sys/param.h>
2024 #include <sys/vmmac.h>
2025
2026 /* Modified from the convex -code above.
2027    mremap promises to clear the i-cache. */
2028
2029 void
2030 __enable_execute_stack ()
2031 {
2032   int fp;
2033   if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
2034                 PROT_READ|PROT_WRITE|PROT_EXEC))
2035     {
2036       perror ("mprotect in __enable_execute_stack");
2037       fflush (stderr);
2038       abort ();
2039     }
2040 }
2041 #endif /* __pyr__ */
2042 #endif /* L_trampoline */
2043 \f
2044 #ifdef L__main
2045
2046 #include "gbl-ctors.h"
2047 /* Some systems use __main in a way incompatible with its use in gcc, in these
2048    cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2049    give the same symbol without quotes for an alternative entry point.  You
2050    must define both, or neither. */
2051 #ifndef NAME__MAIN
2052 #define NAME__MAIN "__main"
2053 #define SYMBOL__MAIN __main
2054 #endif
2055
2056 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2057 /* Run all the global destructors on exit from the program.  */
2058
2059 void
2060 __do_global_dtors ()
2061 {
2062 #ifdef DO_GLOBAL_DTORS_BODY
2063   DO_GLOBAL_DTORS_BODY;
2064 #else
2065   func_ptr *p;
2066   for (p = __DTOR_LIST__ + 1; *p; )
2067     (*p++) ();
2068 #endif
2069 }
2070 #endif
2071
2072 #ifndef INIT_SECTION_ASM_OP
2073 /* Run all the global constructors on entry to the program.  */
2074
2075 #ifndef ON_EXIT
2076 #define ON_EXIT(a, b)
2077 #else
2078 /* Make sure the exit routine is pulled in to define the globals as
2079    bss symbols, just in case the linker does not automatically pull
2080    bss definitions from the library.  */
2081
2082 extern int _exit_dummy_decl;
2083 int *_exit_dummy_ref = &_exit_dummy_decl;
2084 #endif /* ON_EXIT */
2085
2086 void
2087 __do_global_ctors ()
2088 {
2089   DO_GLOBAL_CTORS_BODY;
2090   ON_EXIT (__do_global_dtors, 0);
2091 }
2092 #endif /* no INIT_SECTION_ASM_OP */
2093
2094 #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
2095 /* Subroutine called automatically by `main'.
2096    Compiling a global function named `main'
2097    produces an automatic call to this function at the beginning.
2098
2099    For many systems, this routine calls __do_global_ctors.
2100    For systems which support a .init section we use the .init section
2101    to run __do_global_ctors, so we need not do anything here.  */
2102
2103 void
2104 SYMBOL__MAIN ()
2105 {
2106   /* Support recursive calls to `main': run initializers just once.  */
2107   static int initialized;
2108   if (! initialized)
2109     {
2110       initialized = 1;
2111       __do_global_ctors ();
2112     }
2113 }
2114 #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
2115
2116 #endif /* L__main */
2117 \f
2118 #ifdef L_ctors
2119
2120 #include "gbl-ctors.h"
2121
2122 /* Provide default definitions for the lists of constructors and
2123    destructors, so that we don't get linker errors.  These symbols are
2124    intentionally bss symbols, so that gld and/or collect will provide
2125    the right values.  */
2126
2127 /* We declare the lists here with two elements each,
2128    so that they are valid empty lists if no other definition is loaded.  */
2129 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
2130 #ifdef __NeXT__
2131 /* After 2.3, try this definition on all systems.  */
2132 func_ptr __CTOR_LIST__[2] = {0, 0};
2133 func_ptr __DTOR_LIST__[2] = {0, 0};
2134 #else
2135 func_ptr __CTOR_LIST__[2];
2136 func_ptr __DTOR_LIST__[2];
2137 #endif
2138 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
2139 #endif /* L_ctors */
2140 \f
2141 #ifdef L_exit
2142
2143 #include "gbl-ctors.h"
2144
2145 #ifndef ON_EXIT
2146
2147 /* If we have no known way of registering our own __do_global_dtors
2148    routine so that it will be invoked at program exit time, then we
2149    have to define our own exit routine which will get this to happen.  */
2150
2151 extern void __do_global_dtors ();
2152 extern void _cleanup ();
2153 extern void _exit () __attribute__ ((noreturn));
2154
2155 void 
2156 exit (status)
2157      int status;
2158 {
2159 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2160   __do_global_dtors ();
2161 #endif
2162 #ifdef EXIT_BODY
2163   EXIT_BODY;
2164 #else
2165   _cleanup ();
2166 #endif
2167   _exit (status);
2168 }
2169
2170 #else
2171 int _exit_dummy_decl = 0;       /* prevent compiler & linker warnings */
2172 #endif
2173
2174 #endif /* L_exit */
2175 \f
2176 #ifdef L_eh
2177 typedef struct {
2178   void *start;
2179   void *end;
2180   void *exception_handler;
2181 } exception_table;
2182
2183 struct exception_table_node {
2184   exception_table *table;
2185   void *start;
2186   void *end;
2187   struct exception_table_node *next;
2188 };
2189
2190 static int except_table_pos;
2191 static void *except_pc;
2192 static struct exception_table_node *exception_table_list;
2193
2194 static exception_table *
2195 find_exception_table (pc)
2196      void* pc;
2197 {
2198   register struct exception_table_node *table = exception_table_list;
2199   for ( ; table != 0; table = table->next)
2200     {
2201       if (table->start <= pc && table->end > pc)
2202         return table->table;
2203     }
2204   return 0;
2205 }
2206
2207 /* this routine takes a pc, and the address of the exception handler associated
2208    with the closest exception table handler entry associated with that PC,
2209    or 0 if there are no table entries the PC fits in.  The algorithm works
2210    something like this:
2211
2212     while(current_entry exists) {
2213         if(current_entry.start < pc )
2214             current_entry = next_entry;
2215         else {
2216             if(prev_entry.start <= pc && prev_entry.end > pc) {
2217                 save pointer to prev_entry;
2218                 return prev_entry.exception_handler;
2219              }
2220             else return 0;
2221          }
2222      }
2223     return 0;
2224
2225    Assuming a correctly sorted table (ascending order) this routine should
2226    return the tightest match...
2227
2228    In the advent of a tie, we have to give the last entry, as it represents
2229    an inner block.
2230  */
2231
2232
2233 void *
2234 __find_first_exception_table_match(pc)
2235 void *pc;
2236 {
2237   exception_table *table = find_exception_table (pc);
2238   int pos = 0;
2239   int best = 0;
2240   if (table == 0)
2241     return (void*)0;
2242 #if 0
2243   printf("find_first_exception_table_match(): pc = %x!\n",pc);
2244 #endif
2245
2246   except_pc = pc;
2247
2248 #if 0
2249   /* We can't do this yet, as we don't know that the table is sorted.  */
2250   do {
2251     ++pos;
2252     if (table[pos].start > except_pc)
2253       /* found the first table[pos].start > except_pc, so the previous
2254          entry better be the one we want! */
2255       break;
2256   } while(table[pos].exception_handler != (void*)-1);
2257
2258   --pos;
2259   if (table[pos].start <= except_pc && table[pos].end > except_pc)
2260     {
2261       except_table_pos = pos;
2262 #if 0
2263       printf("find_first_eh_table_match(): found match: %x\n",table[pos].exception_handler);
2264 #endif
2265       return table[pos].exception_handler;
2266     }
2267 #else
2268   while (table[++pos].exception_handler != (void*)-1) {
2269     if (table[pos].start <= except_pc && table[pos].end > except_pc)
2270       {
2271         /* This can apply.  Make sure it is better or as good as the previous
2272            best.  */
2273         /* The best one ends first. */
2274         if (best == 0 || (table[pos].end <= table[best].end
2275                           /* The best one starts last.  */
2276                           && table[pos].start >= table[best].start))
2277           best = pos;
2278       }
2279   }
2280   if (best != 0)
2281     return table[best].exception_handler;
2282 #endif
2283
2284 #if 0
2285   printf("find_first_eh_table_match(): else: returning NULL!\n");
2286 #endif
2287   return (void*)0;
2288 }
2289
2290 void *
2291 __throw_type_match (void *catch_type, void *throw_type, void* obj)
2292 {
2293 #if 0
2294  printf("__throw_type_match (): catch_type = %s, throw_type = %s\n",
2295         catch_type, throw_type);
2296 #endif
2297  if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)
2298    return obj;
2299  return 0;
2300 }
2301
2302 void
2303 __register_exceptions (exception_table *table)
2304 {
2305   struct exception_table_node *node;
2306   exception_table *range = table + 1;
2307
2308   if (range->start == (void*)-1)
2309     return;
2310
2311   node = (struct exception_table_node*)
2312     malloc (sizeof (struct exception_table_node));
2313   node->table = table;
2314
2315   /* This look can be optimized away either if the table
2316      is sorted, or if we pass in extra parameters. */
2317   node->start = range->start;
2318   node->end = range->end;
2319   for (range++ ; range->start != (void*)(-1); range++)
2320     {
2321       if (range->start < node->start)
2322         node->start = range->start;
2323       if (range->end > node->end)
2324         node->end = range->end;
2325     }
2326
2327   node->next = exception_table_list;
2328   exception_table_list = node;
2329 }
2330
2331 #if #machine(i386)
2332 void
2333 __unwind_function(void *ptr)
2334 {
2335   asm("movl 8(%esp),%ecx");
2336   /* Undo current frame */
2337   asm("movl %ebp,%esp");
2338   asm("popl %ebp");
2339   /* like ret, but stay here */
2340   asm("addl $4,%esp");
2341   
2342   /* Now, undo previous frame. */
2343   /* This is a test routine, as we have to dynamically probe to find out
2344      what to pop for certain, this is just a guess. */
2345   asm("leal -16(%ebp),%esp");
2346   asm("pop %eax"); /* really for popl %ebx */
2347   asm("pop %eax"); /* really for popl %esi */
2348   asm("pop %eax"); /* really for popl %edi */
2349   asm("movl %ebp,%esp");
2350   asm("popl %ebp");
2351
2352   asm("movl %ecx,0(%esp)");
2353   asm("ret");
2354 }
2355 #endif
2356
2357 #if #machine(rs6000)
2358 __unwind_function(void *ptr)
2359 {
2360   asm("mr 31,1");
2361   asm("l 1,0(1)");
2362   asm("l 31,-4(1)");
2363   asm("# br");
2364
2365   asm("mr 31,1");
2366   asm("l 1,0(1)");
2367   /* use 31 as a scratch register to restore the link register. */
2368   asm("l 31, 8(1);mtlr 31 # l lr,8(1)");
2369   asm("l 31,-4(1)");
2370   asm("# br");
2371   asm("mtctr 3;bctr # b 3");
2372 }
2373 #endif /* rs6000 */
2374
2375 #if #machine(powerpc)
2376 __unwind_function(void *ptr)
2377 {
2378   asm("mr 31,1");
2379   asm("lwz 1,0(1)");
2380   asm("lwz 31,-4(1)");
2381   asm("# br");
2382
2383   asm("mr 31,1");
2384   asm("lwz 1,0(1)");
2385   /* use 31 as a scratch register to restore the link register. */
2386   asm("lwz 31, 8(1);mtlr 31 # l lr,8(1)");
2387   asm("lwz 31,-4(1)");
2388   asm("# br");
2389   asm("mtctr 3;bctr # b 3");
2390 }
2391 #endif /* powerpc */
2392 #endif /* L_eh */
2393 \f
2394 #ifdef L_pure
2395 #ifndef inhibit_libc
2396 /* This gets us __GNU_LIBRARY__.  */
2397 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
2398 #include <stdio.h>
2399
2400 #ifdef __GNU_LIBRARY__
2401   /* Avoid forcing the library's meaning of `write' on the user program
2402      by using the "internal" name (for use within the library)  */
2403 #define write(fd, buf, n)       __write((fd), (buf), (n))
2404 #endif
2405 #endif /* inhibit_libc */
2406
2407 #define MESSAGE "pure virtual method called\n"
2408
2409 void
2410 __pure_virtual ()
2411 {
2412 #ifndef inhibit_libc
2413   write (2, MESSAGE, sizeof (MESSAGE) - 1);
2414 #endif
2415   _exit (-1);
2416 }
2417 #endif