OSDN Git Service

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