OSDN Git Service

weaken C++ free-store functions
[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;
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 extern void __default_new_handler (void);
1608
1609 void * __builtin_new (size_t sz) __attribute__ ((weak));
1610 void *
1611 __builtin_new (size_t sz)
1612 {
1613   void *p;
1614   vfp handler = (__new_handler) ? __new_handler : __default_new_handler;
1615
1616   /* malloc (0) is unpredictable; avoid it.  */
1617   if (sz == 0)
1618     sz = 1;
1619   p = (void *) malloc (sz);
1620   while (p == 0)
1621     {
1622       (*handler) ();
1623       p = (void *) malloc (sz);
1624     }
1625   
1626   return p;
1627 }
1628 #endif /* L_op_new */
1629
1630 #ifdef L_op_vnew
1631 /* void * operator new [] (size_t), described in 17.3.3.6.  This function
1632    is used by C++ programs to allocate a block of memory for an array.  */
1633
1634 extern void * __builtin_new (size_t);
1635
1636 void * __builtin_vec_new (size_t sz) __attribute__ ((weak));
1637 void *
1638 __builtin_vec_new (size_t sz)
1639 {
1640   return __builtin_new (sz);
1641 }
1642 #endif /* L_op_vnew */
1643
1644 #ifdef L_new_handler
1645 /* set_new_handler (fvoid_t *) and the default new handler, described in
1646    17.3.3.2 and 17.3.3.5.  These functions define the result of a failure
1647    to allocate the amount of memory requested from operator new or new []. */
1648
1649 #ifndef inhibit_libc
1650 /* This gets us __GNU_LIBRARY__.  */
1651 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1652 #include <stdio.h>
1653
1654 #ifdef __GNU_LIBRARY__
1655   /* Avoid forcing the library's meaning of `write' on the user program
1656      by using the "internal" name (for use within the library)  */
1657 #define write(fd, buf, n)       __write((fd), (buf), (n))
1658 #endif
1659 #endif /* inhibit_libc */
1660
1661 typedef void (*vfp)(void);
1662 void __default_new_handler (void);
1663
1664 vfp __new_handler = (vfp)0;
1665
1666 vfp
1667 set_new_handler (vfp handler)
1668 {
1669   vfp prev_handler;
1670
1671   prev_handler = __new_handler;
1672   if (handler == 0) handler = __default_new_handler;
1673   __new_handler = handler;
1674   return prev_handler;
1675 }
1676
1677 #define MESSAGE "Virtual memory exceeded in `new'\n"
1678
1679 void
1680 __default_new_handler ()
1681 {
1682 #ifndef inhibit_libc
1683   /* don't use fprintf (stderr, ...) because it may need to call malloc.  */
1684   /* This should really print the name of the program, but that is hard to
1685      do.  We need a standard, clean way to get at the name.  */
1686   write (2, MESSAGE, sizeof (MESSAGE));
1687 #endif
1688   /* don't call exit () because that may call global destructors which
1689      may cause a loop.  */
1690   _exit (-1);
1691 }
1692 #endif
1693
1694 #ifdef L_op_delete
1695 /* operator delete (void *), described in 17.3.3.3.  This function is used
1696    by C++ programs to return to the free store a block of memory allocated
1697    as a single object. */
1698
1699 void __builtin_delete (void *ptr) __attribute__ ((weak));
1700 void
1701 __builtin_delete (void *ptr)
1702 {
1703   if (ptr)
1704     free (ptr);
1705 }
1706 #endif
1707
1708 #ifdef L_op_vdel
1709 /* operator delete [] (void *), described in 17.3.3.4.  This function is
1710    used by C++ programs to return to the free store a block of memory
1711    allocated as an array. */
1712
1713 extern void __builtin_delete (void *);
1714
1715 void __builtin_vec_delete (void *ptr) __attribute__ ((weak));
1716 void
1717 __builtin_vec_delete (void *ptr)
1718 {
1719   __builtin_delete (ptr);
1720 }
1721 #endif
1722
1723 /* End of C++ free-store management functions */
1724 \f
1725 #ifdef L_shtab
1726 unsigned int __shtab[] = {
1727     0x00000001, 0x00000002, 0x00000004, 0x00000008,
1728     0x00000010, 0x00000020, 0x00000040, 0x00000080,
1729     0x00000100, 0x00000200, 0x00000400, 0x00000800,
1730     0x00001000, 0x00002000, 0x00004000, 0x00008000,
1731     0x00010000, 0x00020000, 0x00040000, 0x00080000,
1732     0x00100000, 0x00200000, 0x00400000, 0x00800000,
1733     0x01000000, 0x02000000, 0x04000000, 0x08000000,
1734     0x10000000, 0x20000000, 0x40000000, 0x80000000
1735   };
1736 #endif
1737 \f
1738 #ifdef L_clear_cache
1739 /* Clear part of an instruction cache.  */
1740
1741 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1742
1743 void
1744 __clear_cache (beg, end)
1745      char *beg, *end;
1746 {
1747 #ifdef CLEAR_INSN_CACHE 
1748   CLEAR_INSN_CACHE (beg, end);
1749 #else
1750 #ifdef INSN_CACHE_SIZE
1751   static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1752   static int initialized;
1753   int offset;
1754   void *start_addr
1755   void *end_addr;
1756   typedef (*function_ptr) ();
1757
1758 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1759   /* It's cheaper to clear the whole cache.
1760      Put in a series of jump instructions so that calling the beginning
1761      of the cache will clear the whole thing.  */
1762
1763   if (! initialized)
1764     {
1765       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1766                  & -INSN_CACHE_LINE_WIDTH);
1767       int end_ptr = ptr + INSN_CACHE_SIZE;
1768
1769       while (ptr < end_ptr)
1770         {
1771           *(INSTRUCTION_TYPE *)ptr
1772             = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1773           ptr += INSN_CACHE_LINE_WIDTH;
1774         }
1775       *(INSTRUCTION_TYPE *)(ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1776
1777       initialized = 1;
1778     }
1779
1780   /* Call the beginning of the sequence.  */
1781   (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1782                     & -INSN_CACHE_LINE_WIDTH))
1783    ());
1784
1785 #else /* Cache is large.  */
1786
1787   if (! initialized)
1788     {
1789       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1790                  & -INSN_CACHE_LINE_WIDTH);
1791
1792       while (ptr < (int) array + sizeof array)
1793         {
1794           *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1795           ptr += INSN_CACHE_LINE_WIDTH;
1796         }
1797
1798       initialized = 1;
1799     }
1800
1801   /* Find the location in array that occupies the same cache line as BEG.  */
1802
1803   offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1804   start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1805                  & -INSN_CACHE_PLANE_SIZE)
1806                 + offset);
1807
1808   /* Compute the cache alignment of the place to stop clearing.  */
1809 #if 0  /* This is not needed for gcc's purposes.  */
1810   /* If the block to clear is bigger than a cache plane,
1811      we clear the entire cache, and OFFSET is already correct.  */ 
1812   if (end < beg + INSN_CACHE_PLANE_SIZE)
1813 #endif
1814     offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1815                & -INSN_CACHE_LINE_WIDTH)
1816               & (INSN_CACHE_PLANE_SIZE - 1));
1817
1818 #if INSN_CACHE_DEPTH > 1
1819   end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1820   if (end_addr <= start_addr)
1821     end_addr += INSN_CACHE_PLANE_SIZE;
1822
1823   for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1824     {
1825       int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1826       int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1827
1828       while (addr != stop)
1829         {
1830           /* Call the return instruction at ADDR.  */
1831           ((function_ptr) addr) ();
1832
1833           addr += INSN_CACHE_LINE_WIDTH;
1834         }
1835     }
1836 #else /* just one plane */
1837   do
1838     {
1839       /* Call the return instruction at START_ADDR.  */
1840       ((function_ptr) start_addr) ();
1841
1842       start_addr += INSN_CACHE_LINE_WIDTH;
1843     }
1844   while ((start_addr % INSN_CACHE_SIZE) != offset);
1845 #endif /* just one plane */
1846 #endif /* Cache is large */
1847 #endif /* Cache exists */
1848 #endif /* CLEAR_INSN_CACHE */
1849 }
1850
1851 #endif /* L_clear_cache */
1852 \f
1853 #ifdef L_trampoline
1854
1855 /* Jump to a trampoline, loading the static chain address.  */
1856
1857 #ifdef TRANSFER_FROM_TRAMPOLINE 
1858 TRANSFER_FROM_TRAMPOLINE 
1859 #endif
1860
1861 #if defined (NeXT) && defined (__MACH__)
1862
1863 /* Make stack executable so we can call trampolines on stack.
1864    This is called from INITIALIZE_TRAMPOLINE in next.h.  */
1865 #ifdef NeXTStep21
1866  #include <mach.h>
1867 #else
1868  #include <mach/mach.h>
1869 #endif
1870
1871 void
1872 __enable_execute_stack (addr)
1873      char *addr;
1874 {
1875   kern_return_t r;
1876   char *eaddr = addr + TRAMPOLINE_SIZE;
1877   vm_address_t a = (vm_address_t) addr;
1878
1879   /* turn on execute access on stack */
1880   r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
1881   if (r != KERN_SUCCESS)
1882     {
1883       mach_error("vm_protect VM_PROT_ALL", r);
1884       exit(1);
1885     }
1886
1887   /* We inline the i-cache invalidation for speed */
1888
1889 #ifdef CLEAR_INSN_CACHE
1890   CLEAR_INSN_CACHE (addr, eaddr);
1891 #else
1892   __clear_cache ((int) addr, (int) eaddr);
1893 #endif
1894
1895
1896 #endif /* defined (NeXT) && defined (__MACH__) */
1897
1898 #ifdef __convex__
1899
1900 /* Make stack executable so we can call trampolines on stack.
1901    This is called from INITIALIZE_TRAMPOLINE in convex.h.  */
1902
1903 #include <sys/mman.h>
1904 #include <sys/vmparam.h>
1905 #include <machine/machparam.h>
1906
1907 void
1908 __enable_execute_stack ()
1909 {
1910   int fp;
1911   static unsigned lowest = USRSTACK;
1912   unsigned current = (unsigned) &fp & -NBPG;
1913
1914   if (lowest > current)
1915     {
1916       unsigned len = lowest - current;
1917       mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
1918       lowest = current;
1919     }
1920
1921   /* Clear instruction cache in case an old trampoline is in it. */
1922   asm ("pich");
1923 }
1924 #endif /* __convex__ */
1925
1926 #ifdef __DOLPHIN__
1927
1928 /* Modified from the convex -code above. */
1929
1930 #include <sys/param.h>
1931 #include <errno.h>
1932 #include <sys/m88kbcs.h>
1933
1934 void
1935 __enable_execute_stack ()
1936 {
1937   int save_errno;
1938   static unsigned long lowest = USRSTACK;
1939   unsigned long current = (unsigned long) &save_errno & -NBPC;
1940   
1941   /* Ignore errno being set. memctl sets errno to EINVAL whenever the
1942      address is seen as 'negative'. That is the case with the stack.   */
1943
1944   save_errno=errno;
1945   if (lowest > current)
1946     {
1947       unsigned len=lowest-current;
1948       memctl(current,len,MCT_TEXT);
1949       lowest = current;
1950     }
1951   else
1952     memctl(current,NBPC,MCT_TEXT);
1953   errno=save_errno;
1954 }
1955
1956 #endif /* __DOLPHIN__ */
1957
1958 #ifdef __pyr__
1959
1960 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1961 #include <stdio.h>
1962 #include <sys/mman.h>
1963 #include <sys/types.h>
1964 #include <sys/param.h>
1965 #include <sys/vmmac.h>
1966
1967 /* Modified from the convex -code above.
1968    mremap promises to clear the i-cache. */
1969
1970 void
1971 __enable_execute_stack ()
1972 {
1973   int fp;
1974   if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
1975                 PROT_READ|PROT_WRITE|PROT_EXEC))
1976     {
1977       perror ("mprotect in __enable_execute_stack");
1978       fflush (stderr);
1979       abort ();
1980     }
1981 }
1982 #endif /* __pyr__ */
1983 #endif /* L_trampoline */
1984 \f
1985 #ifdef L__main
1986
1987 #include "gbl-ctors.h"
1988 /* Some systems use __main in a way incompatible with its use in gcc, in these
1989    cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
1990    give the same symbol without quotes for an alternative entry point.  You
1991    must define both, or niether. */
1992 #ifndef NAME__MAIN
1993 #define NAME__MAIN "__main"
1994 #define SYMBOL__MAIN __main
1995 #endif
1996
1997 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
1998 /* Run all the global destructors on exit from the program.  */
1999
2000 void
2001 __do_global_dtors ()
2002 {
2003 #ifdef DO_GLOBAL_DTORS_BODY
2004   DO_GLOBAL_DTORS_BODY;
2005 #else
2006   func_ptr *p;
2007   for (p = __DTOR_LIST__ + 1; *p; )
2008     (*p++) ();
2009 #endif
2010 }
2011 #endif
2012
2013 #ifndef INIT_SECTION_ASM_OP
2014 /* Run all the global constructors on entry to the program.  */
2015
2016 #ifndef ON_EXIT
2017 #define ON_EXIT(a, b)
2018 #else
2019 /* Make sure the exit routine is pulled in to define the globals as
2020    bss symbols, just in case the linker does not automatically pull
2021    bss definitions from the library.  */
2022
2023 extern int _exit_dummy_decl;
2024 int *_exit_dummy_ref = &_exit_dummy_decl;
2025 #endif /* ON_EXIT */
2026
2027 void
2028 __do_global_ctors ()
2029 {
2030   DO_GLOBAL_CTORS_BODY;
2031   ON_EXIT (__do_global_dtors, 0);
2032 }
2033 #endif /* no INIT_SECTION_ASM_OP */
2034
2035 #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
2036 /* Subroutine called automatically by `main'.
2037    Compiling a global function named `main'
2038    produces an automatic call to this function at the beginning.
2039
2040    For many systems, this routine calls __do_global_ctors.
2041    For systems which support a .init section we use the .init section
2042    to run __do_global_ctors, so we need not do anything here.  */
2043
2044 void
2045 SYMBOL__MAIN ()
2046 {
2047   /* Support recursive calls to `main': run initializers just once.  */
2048   static int initialized;
2049   if (! initialized)
2050     {
2051       initialized = 1;
2052       __do_global_ctors ();
2053     }
2054 }
2055 #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
2056
2057 #endif /* L__main */
2058 \f
2059 #ifdef L_ctors
2060
2061 #include "gbl-ctors.h"
2062
2063 /* Provide default definitions for the lists of constructors and
2064    destructors, so that we don't get linker errors.  These symbols are
2065    intentionally bss symbols, so that gld and/or collect will provide
2066    the right values.  */
2067
2068 /* We declare the lists here with two elements each,
2069    so that they are valid empty lists if no other definition is loaded.  */
2070 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
2071 #ifdef __NeXT__
2072 /* After 2.3, try this definition on all systems.  */
2073 func_ptr __CTOR_LIST__[2] = {0, 0};
2074 func_ptr __DTOR_LIST__[2] = {0, 0};
2075 #else
2076 func_ptr __CTOR_LIST__[2];
2077 func_ptr __DTOR_LIST__[2];
2078 #endif
2079 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
2080 #endif /* L_ctors */
2081 \f
2082 #ifdef L_exit
2083
2084 #include "gbl-ctors.h"
2085
2086 #ifndef ON_EXIT
2087
2088 /* If we have no known way of registering our own __do_global_dtors
2089    routine so that it will be invoked at program exit time, then we
2090    have to define our own exit routine which will get this to happen.  */
2091
2092 extern void __do_global_dtors ();
2093 extern void _cleanup ();
2094 extern void _exit () __attribute__ ((noreturn));
2095
2096 void 
2097 exit (status)
2098      int status;
2099 {
2100 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2101   __do_global_dtors ();
2102 #endif
2103 #ifdef EXIT_BODY
2104   EXIT_BODY;
2105 #else
2106   _cleanup ();
2107 #endif
2108   _exit (status);
2109 }
2110
2111 #else
2112 int _exit_dummy_decl = 0;       /* prevent compiler & linker warnings */
2113 #endif
2114
2115 #endif /* L_exit */
2116 \f
2117 #ifdef L_eh
2118 typedef struct {
2119   void *start;
2120   void *end;
2121   void *exception_handler;
2122 } exception_table;
2123
2124 struct exception_table_node {
2125   exception_table *table;
2126   void *start;
2127   void *end;
2128   struct exception_table_node *next;
2129 };
2130
2131 static int except_table_pos;
2132 static void *except_pc;
2133 static struct exception_table_node *exception_table_list;
2134
2135 static exception_table *
2136 find_exception_table (pc)
2137      void* pc;
2138 {
2139   register struct exception_table_node *table = exception_table_list;
2140   for ( ; table != 0; table = table->next)
2141     {
2142       if (table->start <= pc && table->end > pc)
2143         return table->table;
2144     }
2145   return 0;
2146 }
2147
2148 /* this routine takes a pc, and the address of the exception handler associated
2149    with the closest exception table handler entry associated with that PC,
2150    or 0 if there are no table entries the PC fits in.  The algorithm works
2151    something like this:
2152
2153     while(current_entry exists) {
2154         if(current_entry.start < pc )
2155             current_entry = next_entry;
2156         else {
2157             if(prev_entry.start <= pc && prev_entry.end > pc) {
2158                 save pointer to prev_entry;
2159                 return prev_entry.exception_handler;
2160              }
2161             else return 0;
2162          }
2163      }
2164     return 0;
2165
2166    Assuming a correctly sorted table (ascending order) this routine should
2167    return the tighest match...
2168
2169    In the advent of a tie, we have to give the last entry, as it represents
2170    an inner block.
2171  */
2172
2173
2174 void *
2175 __find_first_exception_table_match(pc)
2176 void *pc;
2177 {
2178   exception_table *table = find_exception_table (pc);
2179   int pos = 0;
2180   int best = 0;
2181   if (table == 0)
2182     return (void*)0;
2183 #if 0
2184   printf("find_first_exception_table_match(): pc = %x!\n",pc);
2185 #endif
2186
2187   except_pc = pc;
2188
2189 #if 0
2190   /* We can't do this yet, as we don't know that the table is sorted.  */
2191   do {
2192     ++pos;
2193     if (table[pos].start > except_pc)
2194       /* found the first table[pos].start > except_pc, so the previous
2195          entry better be the one we want! */
2196       break;
2197   } while(table[pos].exception_handler != (void*)-1);
2198
2199   --pos;
2200   if (table[pos].start <= except_pc && table[pos].end > except_pc)
2201     {
2202       except_table_pos = pos;
2203 #if 0
2204       printf("find_first_eh_table_match(): found match: %x\n",table[pos].exception_handler);
2205 #endif
2206       return table[pos].exception_handler;
2207     }
2208 #else
2209   while (table[++pos].exception_handler != (void*)-1) {
2210     if (table[pos].start <= except_pc && table[pos].end > except_pc)
2211       {
2212         /* This can apply.  Make sure it is better or as good as the previous
2213            best.  */
2214         /* The best one ends first. */
2215         if (best == 0 || (table[pos].end <= table[best].end
2216                           /* The best one starts last.  */
2217                           && table[pos].start >= table[best].start))
2218           best = pos;
2219       }
2220   }
2221   if (best != 0)
2222     return table[best].exception_handler;
2223 #endif
2224
2225 #if 0
2226   printf("find_first_eh_table_match(): else: returning NULL!\n");
2227 #endif
2228   return (void*)0;
2229 }
2230
2231 void *
2232 __throw_type_match (void *catch_type, void *throw_type, void* obj)
2233 {
2234 #if 0
2235  printf("__throw_type_match (): catch_type = %s, throw_type = %s\n",
2236         catch_type, throw_type);
2237 #endif
2238  if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)
2239    return obj;
2240  return 0;
2241 }
2242
2243 void
2244 __register_exceptions (exception_table *table)
2245 {
2246   struct exception_table_node *node;
2247   exception_table *range = table + 1;
2248
2249   if (range->start == (void*)-1)
2250     return;
2251
2252   node = (struct exception_table_node*)
2253     malloc (sizeof (struct exception_table_node));
2254   node->table = table;
2255
2256   /* This look can be optimized away either if the table
2257      is sorted, or if we pass in extra parameters. */
2258   node->start = range->start;
2259   node->end = range->end;
2260   for (range++ ; range->start != (void*)(-1); range++)
2261     {
2262       if (range->start < node->start)
2263         node->start = range->start;
2264       if (range->end > node->end)
2265         node->end = range->end;
2266     }
2267
2268   node->next = exception_table_list;
2269   exception_table_list = node;
2270 }
2271
2272 #if #machine(i386)
2273 void
2274 __unwind_function(void *ptr)
2275 {
2276   asm("movl 8(%esp),%ecx");
2277   /* Undo current frame */
2278   asm("movl %ebp,%esp");
2279   asm("popl %ebp");
2280   asm("# like ret, but stay here");
2281   asm("addl $4,%esp");
2282   
2283   /* Now, undo previous frame. */
2284   /* This is a test routine, as we have to dynamically probe to find out
2285      what to pop for certain, this is just a guess. */
2286   asm("leal -16(%ebp),%esp");
2287   asm("pop %eax # really for popl %ebx");
2288   asm("pop %eax # really for popl %esi");
2289   asm("pop %eax # really for popl %edi");
2290   asm("movl %ebp,%esp");
2291   asm("popl %ebp");
2292
2293   asm("movl %ecx,0(%esp)");
2294   asm("ret");
2295 }
2296 #endif
2297
2298 #if #machine(rs6000)
2299 __unwind_function(void *ptr)
2300 {
2301   asm("mr 31,1");
2302   asm("l 1,0(1)");
2303   asm("l 31,-4(1)");
2304   asm("# br");
2305
2306   asm("mr 31,1");
2307   asm("l 1,0(1)");
2308   /* use 31 as a scratch register to restore the link register. */
2309   asm("l 31, 8(1);mtlr 31 # l lr,8(1)");
2310   asm("l 31,-4(1)");
2311   asm("# br");
2312   asm("mtctr 3;bctr # b 3");
2313 }
2314 #endif /* rs6000 */
2315
2316 #if #machine(powerpc)
2317 __unwind_function(void *ptr)
2318 {
2319   asm("mr 31,1");
2320   asm("lwz 1,0(1)");
2321   asm("lwz 31,-4(1)");
2322   asm("# br");
2323
2324   asm("mr 31,1");
2325   asm("lwz 1,0(1)");
2326   /* use 31 as a scratch register to restore the link register. */
2327   asm("lwz 31, 8(1);mtlr 31 # l lr,8(1)");
2328   asm("lwz 31,-4(1)");
2329   asm("# br");
2330   asm("mtctr 3;bctr # b 3");
2331 }
2332 #endif /* powerpc */
2333 #endif /* L_eh */
2334 \f
2335 #ifdef L_pure
2336 #ifndef inhibit_libc
2337 /* This gets us __GNU_LIBRARY__.  */
2338 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
2339 #include <stdio.h>
2340
2341 #ifdef __GNU_LIBRARY__
2342   /* Avoid forcing the library's meaning of `write' on the user program
2343      by using the "internal" name (for use within the library)  */
2344 #define write(fd, buf, n)       __write((fd), (buf), (n))
2345 #endif
2346 #endif /* inhibit_libc */
2347
2348 #define MESSAGE "pure virtual method called\n"
2349
2350 void
2351 __pure_virtual ()
2352 {
2353 #ifndef inhibit_libc
2354   write (2, MESSAGE, sizeof (MESSAGE) - 1);
2355 #endif
2356   _exit (-1);
2357 }
2358 #endif