OSDN Git Service

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