OSDN Git Service

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