OSDN Git Service

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