OSDN Git Service

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