OSDN Git Service

Declare malloc, free, and atexit if inhibit_libc is defined.
[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, 92-98, 1999 Free Software Foundation, Inc.
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22 /* As a special exception, if you link this library with other files,
23    some of which are compiled with GCC, to produce an executable,
24    this library does not by itself cause the resulting executable
25    to be covered by the GNU General Public License.
26    This exception does not however invalidate any other reasons why
27    the executable file might be covered by the GNU General Public License.  */
28
29 /* It is incorrect to include config.h here, because this file is being
30    compiled for the target, and hence definitions concerning only the host
31    do not apply.  */
32
33 #include "tconfig.h"
34
35 /* We disable this when inhibit_libc, so that gcc can still be built without
36    needing header files first.  */
37 /* ??? This is not a good solution, since prototypes may be required in
38    some cases for correct code.  See also frame.c.  */
39 #ifndef inhibit_libc
40 /* fixproto guarantees these system headers exist. */
41 #include <stdlib.h>
42 #include <unistd.h>
43
44 #else
45 #include <stddef.h>
46 #ifndef malloc
47 extern void *malloc (size_t);
48 #endif
49 #ifndef free
50 extern void free (void *);
51 #endif
52 #ifndef atexit
53 extern int atexit(void (*)(void));
54 #endif
55 #endif
56
57 #include "machmode.h"
58 #include "defaults.h" 
59 #if !defined(L_trampoline) && !defined(inhibit_libc)
60 #include <stddef.h>
61 #endif
62
63 /* Don't use `fancy_abort' here even if config.h says to use it.  */
64 #ifdef abort
65 #undef abort
66 #endif
67
68 /* In a cross-compilation situation, default to inhibiting compilation
69    of routines that use libc.  */
70
71 #if defined(CROSS_COMPILE) && !defined(inhibit_libc)
72 #define inhibit_libc
73 #endif
74
75 /* Permit the tm.h file to select the endianness to use just for this
76    file.  This is used when the endianness is determined when the
77    compiler is run.  */
78
79 #ifndef LIBGCC2_WORDS_BIG_ENDIAN
80 #define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
81 #endif
82
83 #ifndef LIBGCC2_LONG_DOUBLE_TYPE_SIZE
84 #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE LONG_DOUBLE_TYPE_SIZE
85 #endif
86
87 /* In the first part of this file, we are interfacing to calls generated
88    by the compiler itself.  These calls pass values into these routines
89    which have very specific modes (rather than very specific types), and
90    these compiler-generated calls also expect any return values to have
91    very specific modes (rather than very specific types).  Thus, we need
92    to avoid using regular C language type names in this part of the file
93    because the sizes for those types can be configured to be anything.
94    Instead we use the following special type names.  */
95
96 typedef unsigned int UQItype    __attribute__ ((mode (QI)));
97 typedef          int SItype     __attribute__ ((mode (SI)));
98 typedef unsigned int USItype    __attribute__ ((mode (SI)));
99 typedef          int DItype     __attribute__ ((mode (DI)));
100 typedef unsigned int UDItype    __attribute__ ((mode (DI)));
101
102 typedef         float SFtype    __attribute__ ((mode (SF)));
103 typedef         float DFtype    __attribute__ ((mode (DF)));
104
105 #if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
106 typedef         float XFtype    __attribute__ ((mode (XF)));
107 #endif
108 #if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128
109 typedef         float TFtype    __attribute__ ((mode (TF)));
110 #endif
111
112 typedef int word_type __attribute__ ((mode (__word__)));
113
114 /* Make sure that we don't accidentally use any normal C language built-in
115    type names in the first part of this file.  Instead we want to use *only*
116    the type names defined above.  The following macro definitions insure
117    that if we *do* accidentally use some normal C language built-in type name,
118    we will get a syntax error.  */
119
120 #define char bogus_type
121 #define short bogus_type
122 #define int bogus_type
123 #define long bogus_type
124 #define unsigned bogus_type
125 #define float bogus_type
126 #define double bogus_type
127
128 #define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
129
130 /* DIstructs are pairs of SItype values in the order determined by
131    LIBGCC2_WORDS_BIG_ENDIAN.  */
132
133 #if LIBGCC2_WORDS_BIG_ENDIAN
134   struct DIstruct {SItype high, low;};
135 #else
136   struct DIstruct {SItype low, high;};
137 #endif
138
139 /* We need this union to unpack/pack DImode values, since we don't have
140    any arithmetic yet.  Incoming DImode parameters are stored into the
141    `ll' field, and the unpacked result is read from the struct `s'.  */
142
143 typedef union
144 {
145   struct DIstruct s;
146   DItype ll;
147 } DIunion;
148
149 #if (defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_w_sdiv)\
150      || defined (L_divdi3) || defined (L_udivdi3) \
151      || defined (L_moddi3) || defined (L_umoddi3))
152
153 #include "longlong.h"
154
155 #endif /* udiv or mul */
156
157 extern DItype __fixunssfdi (SFtype a);
158 extern DItype __fixunsdfdi (DFtype a);
159 #if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
160 extern DItype __fixunsxfdi (XFtype a);
161 #endif
162 #if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128
163 extern DItype __fixunstfdi (TFtype a);
164 #endif
165 \f
166 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
167 #if defined (L_divdi3) || defined (L_moddi3)
168 static inline
169 #endif
170 DItype
171 __negdi2 (DItype u)
172 {
173   DIunion w;
174   DIunion uu;
175
176   uu.ll = u;
177
178   w.s.low = -uu.s.low;
179   w.s.high = -uu.s.high - ((USItype) w.s.low > 0);
180
181   return w.ll;
182 }
183 #endif
184 \f
185 /* Unless shift functions are defined whith full ANSI prototypes,
186    parameter b will be promoted to int if word_type is smaller than an int.  */
187 #ifdef L_lshrdi3
188 DItype
189 __lshrdi3 (DItype u, 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.high = 0;
204       w.s.low = (USItype)uu.s.high >> -bm;
205     }
206   else
207     {
208       USItype carries = (USItype)uu.s.high << bm;
209       w.s.high = (USItype)uu.s.high >> b;
210       w.s.low = ((USItype)uu.s.low >> b) | carries;
211     }
212
213   return w.ll;
214 }
215 #endif
216
217 #ifdef L_ashldi3
218 DItype
219 __ashldi3 (DItype u, word_type b)
220 {
221   DIunion w;
222   word_type bm;
223   DIunion uu;
224
225   if (b == 0)
226     return u;
227
228   uu.ll = u;
229
230   bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
231   if (bm <= 0)
232     {
233       w.s.low = 0;
234       w.s.high = (USItype)uu.s.low << -bm;
235     }
236   else
237     {
238       USItype carries = (USItype)uu.s.low >> bm;
239       w.s.low = (USItype)uu.s.low << b;
240       w.s.high = ((USItype)uu.s.high << b) | carries;
241     }
242
243   return w.ll;
244 }
245 #endif
246
247 #ifdef L_ashrdi3
248 DItype
249 __ashrdi3 (DItype u, word_type b)
250 {
251   DIunion w;
252   word_type bm;
253   DIunion uu;
254
255   if (b == 0)
256     return u;
257
258   uu.ll = u;
259
260   bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
261   if (bm <= 0)
262     {
263       /* w.s.high = 1..1 or 0..0 */
264       w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
265       w.s.low = uu.s.high >> -bm;
266     }
267   else
268     {
269       USItype carries = (USItype)uu.s.high << bm;
270       w.s.high = uu.s.high >> b;
271       w.s.low = ((USItype)uu.s.low >> b) | carries;
272     }
273
274   return w.ll;
275 }
276 #endif
277 \f
278 #ifdef L_ffsdi2
279 DItype
280 __ffsdi2 (DItype u)
281 {
282   DIunion uu, w;
283   uu.ll = u;
284   w.s.high = 0;
285   w.s.low = ffs (uu.s.low);
286   if (w.s.low != 0)
287     return w.ll;
288   w.s.low = ffs (uu.s.high);
289   if (w.s.low != 0)
290     {
291       w.s.low += BITS_PER_UNIT * sizeof (SItype);
292       return w.ll;
293     }
294   return w.ll;
295 }
296 #endif
297 \f
298 #ifdef L_muldi3
299 DItype
300 __muldi3 (DItype u, DItype v)
301 {
302   DIunion w;
303   DIunion uu, vv;
304
305   uu.ll = u,
306   vv.ll = v;
307
308   w.ll = __umulsidi3 (uu.s.low, vv.s.low);
309   w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
310                + (USItype) uu.s.high * (USItype) vv.s.low);
311
312   return w.ll;
313 }
314 #endif
315 \f
316 #ifdef L_udiv_w_sdiv
317 #if defined (sdiv_qrnnd)
318 USItype
319 __udiv_w_sdiv (USItype *rp, USItype a1, USItype a0, USItype d)
320 {
321   USItype q, r;
322   USItype c0, c1, b1;
323
324   if ((SItype) d >= 0)
325     {
326       if (a1 < d - a1 - (a0 >> (SI_TYPE_SIZE - 1)))
327         {
328           /* dividend, divisor, and quotient are nonnegative */
329           sdiv_qrnnd (q, r, a1, a0, d);
330         }
331       else
332         {
333           /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
334           sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (SI_TYPE_SIZE - 1));
335           /* Divide (c1*2^32 + c0) by d */
336           sdiv_qrnnd (q, r, c1, c0, d);
337           /* Add 2^31 to quotient */
338           q += (USItype) 1 << (SI_TYPE_SIZE - 1);
339         }
340     }
341   else
342     {
343       b1 = d >> 1;                      /* d/2, between 2^30 and 2^31 - 1 */
344       c1 = a1 >> 1;                     /* A/2 */
345       c0 = (a1 << (SI_TYPE_SIZE - 1)) + (a0 >> 1);
346
347       if (a1 < b1)                      /* A < 2^32*b1, so A/2 < 2^31*b1 */
348         {
349           sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
350
351           r = 2*r + (a0 & 1);           /* Remainder from A/(2*b1) */
352           if ((d & 1) != 0)
353             {
354               if (r >= q)
355                 r = r - q;
356               else if (q - r <= d)
357                 {
358                   r = r - q + d;
359                   q--;
360                 }
361               else
362                 {
363                   r = r - q + 2*d;
364                   q -= 2;
365                 }
366             }
367         }
368       else if (c1 < b1)                 /* So 2^31 <= (A/2)/b1 < 2^32 */
369         {
370           c1 = (b1 - 1) - c1;
371           c0 = ~c0;                     /* logical NOT */
372
373           sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
374
375           q = ~q;                       /* (A/2)/b1 */
376           r = (b1 - 1) - r;
377
378           r = 2*r + (a0 & 1);           /* A/(2*b1) */
379
380           if ((d & 1) != 0)
381             {
382               if (r >= q)
383                 r = r - q;
384               else if (q - r <= d)
385                 {
386                   r = r - q + d;
387                   q--;
388                 }
389               else
390                 {
391                   r = r - q + 2*d;
392                   q -= 2;
393                 }
394             }
395         }
396       else                              /* Implies c1 = b1 */
397         {                               /* Hence a1 = d - 1 = 2*b1 - 1 */
398           if (a0 >= -d)
399             {
400               q = -1;
401               r = a0 + d;
402             }
403           else
404             {
405               q = -2;
406               r = a0 + 2*d;
407             }
408         }
409     }
410
411   *rp = r;
412   return q;
413 }
414 #else
415 /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv.  */
416 USItype
417 __udiv_w_sdiv (USItype *rp __attribute__ ((__unused__)),
418                USItype a1 __attribute__ ((__unused__)),
419                USItype a0 __attribute__ ((__unused__)),
420                USItype d __attribute__ ((__unused__)))
421 {
422   return 0;
423 }
424 #endif
425 #endif
426 \f
427 #if (defined (L_udivdi3) || defined (L_divdi3) || \
428      defined (L_umoddi3) || defined (L_moddi3))
429 #define L_udivmoddi4
430 #endif
431
432 #ifdef L_udivmoddi4
433 static const UQItype __clz_tab[] =
434 {
435   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,
436   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,
437   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,
438   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,
439   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,
440   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,
441   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,
442   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,
443 };
444
445 #if (defined (L_udivdi3) || defined (L_divdi3) || \
446      defined (L_umoddi3) || defined (L_moddi3))
447 static inline
448 #endif
449 UDItype
450 __udivmoddi4 (UDItype n, UDItype d, UDItype *rp)
451 {
452   DIunion ww;
453   DIunion nn, dd;
454   DIunion rr;
455   USItype d0, d1, n0, n1, n2;
456   USItype q0, q1;
457   USItype b, bm;
458
459   nn.ll = n;
460   dd.ll = d;
461
462   d0 = dd.s.low;
463   d1 = dd.s.high;
464   n0 = nn.s.low;
465   n1 = nn.s.high;
466
467 #if !UDIV_NEEDS_NORMALIZATION
468   if (d1 == 0)
469     {
470       if (d0 > n1)
471         {
472           /* 0q = nn / 0D */
473
474           udiv_qrnnd (q0, n0, n1, n0, d0);
475           q1 = 0;
476
477           /* Remainder in n0.  */
478         }
479       else
480         {
481           /* qq = NN / 0d */
482
483           if (d0 == 0)
484             d0 = 1 / d0;        /* Divide intentionally by zero.  */
485
486           udiv_qrnnd (q1, n1, 0, n1, d0);
487           udiv_qrnnd (q0, n0, n1, n0, d0);
488
489           /* Remainder in n0.  */
490         }
491
492       if (rp != 0)
493         {
494           rr.s.low = n0;
495           rr.s.high = 0;
496           *rp = rr.ll;
497         }
498     }
499
500 #else /* UDIV_NEEDS_NORMALIZATION */
501
502   if (d1 == 0)
503     {
504       if (d0 > n1)
505         {
506           /* 0q = nn / 0D */
507
508           count_leading_zeros (bm, d0);
509
510           if (bm != 0)
511             {
512               /* Normalize, i.e. make the most significant bit of the
513                  denominator set.  */
514
515               d0 = d0 << bm;
516               n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
517               n0 = n0 << bm;
518             }
519
520           udiv_qrnnd (q0, n0, n1, n0, d0);
521           q1 = 0;
522
523           /* Remainder in n0 >> bm.  */
524         }
525       else
526         {
527           /* qq = NN / 0d */
528
529           if (d0 == 0)
530             d0 = 1 / d0;        /* Divide intentionally by zero.  */
531
532           count_leading_zeros (bm, d0);
533
534           if (bm == 0)
535             {
536               /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
537                  conclude (the most significant bit of n1 is set) /\ (the
538                  leading quotient digit q1 = 1).
539
540                  This special case is necessary, not an optimization.
541                  (Shifts counts of SI_TYPE_SIZE are undefined.)  */
542
543               n1 -= d0;
544               q1 = 1;
545             }
546           else
547             {
548               /* Normalize.  */
549
550               b = SI_TYPE_SIZE - bm;
551
552               d0 = d0 << bm;
553               n2 = n1 >> b;
554               n1 = (n1 << bm) | (n0 >> b);
555               n0 = n0 << bm;
556
557               udiv_qrnnd (q1, n1, n2, n1, d0);
558             }
559
560           /* n1 != d0...  */
561
562           udiv_qrnnd (q0, n0, n1, n0, d0);
563
564           /* Remainder in n0 >> bm.  */
565         }
566
567       if (rp != 0)
568         {
569           rr.s.low = n0 >> bm;
570           rr.s.high = 0;
571           *rp = rr.ll;
572         }
573     }
574 #endif /* UDIV_NEEDS_NORMALIZATION */
575
576   else
577     {
578       if (d1 > n1)
579         {
580           /* 00 = nn / DD */
581
582           q0 = 0;
583           q1 = 0;
584
585           /* Remainder in n1n0.  */
586           if (rp != 0)
587             {
588               rr.s.low = n0;
589               rr.s.high = n1;
590               *rp = rr.ll;
591             }
592         }
593       else
594         {
595           /* 0q = NN / dd */
596
597           count_leading_zeros (bm, d1);
598           if (bm == 0)
599             {
600               /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
601                  conclude (the most significant bit of n1 is set) /\ (the
602                  quotient digit q0 = 0 or 1).
603
604                  This special case is necessary, not an optimization.  */
605
606               /* The condition on the next line takes advantage of that
607                  n1 >= d1 (true due to program flow).  */
608               if (n1 > d1 || n0 >= d0)
609                 {
610                   q0 = 1;
611                   sub_ddmmss (n1, n0, n1, n0, d1, d0);
612                 }
613               else
614                 q0 = 0;
615
616               q1 = 0;
617
618               if (rp != 0)
619                 {
620                   rr.s.low = n0;
621                   rr.s.high = n1;
622                   *rp = rr.ll;
623                 }
624             }
625           else
626             {
627               USItype m1, m0;
628               /* Normalize.  */
629
630               b = SI_TYPE_SIZE - bm;
631
632               d1 = (d1 << bm) | (d0 >> b);
633               d0 = d0 << bm;
634               n2 = n1 >> b;
635               n1 = (n1 << bm) | (n0 >> b);
636               n0 = n0 << bm;
637
638               udiv_qrnnd (q0, n1, n2, n1, d1);
639               umul_ppmm (m1, m0, q0, d0);
640
641               if (m1 > n1 || (m1 == n1 && m0 > n0))
642                 {
643                   q0--;
644                   sub_ddmmss (m1, m0, m1, m0, d1, d0);
645                 }
646
647               q1 = 0;
648
649               /* Remainder in (n1n0 - m1m0) >> bm.  */
650               if (rp != 0)
651                 {
652                   sub_ddmmss (n1, n0, n1, n0, m1, m0);
653                   rr.s.low = (n1 << b) | (n0 >> bm);
654                   rr.s.high = n1 >> bm;
655                   *rp = rr.ll;
656                 }
657             }
658         }
659     }
660
661   ww.s.low = q0;
662   ww.s.high = q1;
663   return ww.ll;
664 }
665 #endif
666
667 #ifdef L_divdi3
668 UDItype __udivmoddi4 ();
669
670 DItype
671 __divdi3 (DItype u, DItype v)
672 {
673   word_type c = 0;
674   DIunion uu, vv;
675   DItype w;
676
677   uu.ll = u;
678   vv.ll = v;
679
680   if (uu.s.high < 0)
681     c = ~c,
682     uu.ll = __negdi2 (uu.ll);
683   if (vv.s.high < 0)
684     c = ~c,
685     vv.ll = __negdi2 (vv.ll);
686
687   w = __udivmoddi4 (uu.ll, vv.ll, (UDItype *) 0);
688   if (c)
689     w = __negdi2 (w);
690
691   return w;
692 }
693 #endif
694
695 #ifdef L_moddi3
696 UDItype __udivmoddi4 ();
697 DItype
698 __moddi3 (DItype u, DItype v)
699 {
700   word_type c = 0;
701   DIunion uu, vv;
702   DItype w;
703
704   uu.ll = u;
705   vv.ll = v;
706
707   if (uu.s.high < 0)
708     c = ~c,
709     uu.ll = __negdi2 (uu.ll);
710   if (vv.s.high < 0)
711     vv.ll = __negdi2 (vv.ll);
712
713   (void) __udivmoddi4 (uu.ll, vv.ll, &w);
714   if (c)
715     w = __negdi2 (w);
716
717   return w;
718 }
719 #endif
720
721 #ifdef L_umoddi3
722 UDItype __udivmoddi4 ();
723 UDItype
724 __umoddi3 (UDItype u, UDItype v)
725 {
726   UDItype w;
727
728   (void) __udivmoddi4 (u, v, &w);
729
730   return w;
731 }
732 #endif
733
734 #ifdef L_udivdi3
735 UDItype __udivmoddi4 ();
736 UDItype
737 __udivdi3 (UDItype n, UDItype d)
738 {
739   return __udivmoddi4 (n, d, (UDItype *) 0);
740 }
741 #endif
742 \f
743 #ifdef L_cmpdi2
744 word_type
745 __cmpdi2 (DItype a, DItype b)
746 {
747   DIunion au, bu;
748
749   au.ll = a, bu.ll = b;
750
751   if (au.s.high < bu.s.high)
752     return 0;
753   else if (au.s.high > bu.s.high)
754     return 2;
755   if ((USItype) au.s.low < (USItype) bu.s.low)
756     return 0;
757   else if ((USItype) au.s.low > (USItype) bu.s.low)
758     return 2;
759   return 1;
760 }
761 #endif
762
763 #ifdef L_ucmpdi2
764 word_type
765 __ucmpdi2 (DItype a, DItype b)
766 {
767   DIunion au, bu;
768
769   au.ll = a, bu.ll = b;
770
771   if ((USItype) au.s.high < (USItype) bu.s.high)
772     return 0;
773   else if ((USItype) au.s.high > (USItype) bu.s.high)
774     return 2;
775   if ((USItype) au.s.low < (USItype) bu.s.low)
776     return 0;
777   else if ((USItype) au.s.low > (USItype) bu.s.low)
778     return 2;
779   return 1;
780 }
781 #endif
782 \f
783 #if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
784 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
785 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
786
787 DItype
788 __fixunstfdi (TFtype a)
789 {
790   TFtype b;
791   UDItype v;
792
793   if (a < 0)
794     return 0;
795
796   /* Compute high word of result, as a flonum.  */
797   b = (a / HIGH_WORD_COEFF);
798   /* Convert that to fixed (but not to DItype!),
799      and shift it into the high word.  */
800   v = (USItype) b;
801   v <<= WORD_SIZE;
802   /* Remove high part from the TFtype, leaving the low part as flonum.  */
803   a -= (TFtype)v;
804   /* Convert that to fixed (but not to DItype!) and add it in.
805      Sometimes A comes out negative.  This is significant, since
806      A has more bits than a long int does.  */
807   if (a < 0)
808     v -= (USItype) (- a);
809   else
810     v += (USItype) a;
811   return v;
812 }
813 #endif
814
815 #if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
816 DItype
817 __fixtfdi (TFtype a)
818 {
819   if (a < 0)
820     return - __fixunstfdi (-a);
821   return __fixunstfdi (a);
822 }
823 #endif
824
825 #if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
826 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
827 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
828
829 DItype
830 __fixunsxfdi (XFtype a)
831 {
832   XFtype b;
833   UDItype v;
834
835   if (a < 0)
836     return 0;
837
838   /* Compute high word of result, as a flonum.  */
839   b = (a / HIGH_WORD_COEFF);
840   /* Convert that to fixed (but not to DItype!),
841      and shift it into the high word.  */
842   v = (USItype) b;
843   v <<= WORD_SIZE;
844   /* Remove high part from the XFtype, leaving the low part as flonum.  */
845   a -= (XFtype)v;
846   /* Convert that to fixed (but not to DItype!) and add it in.
847      Sometimes A comes out negative.  This is significant, since
848      A has more bits than a long int does.  */
849   if (a < 0)
850     v -= (USItype) (- a);
851   else
852     v += (USItype) a;
853   return v;
854 }
855 #endif
856
857 #if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
858 DItype
859 __fixxfdi (XFtype a)
860 {
861   if (a < 0)
862     return - __fixunsxfdi (-a);
863   return __fixunsxfdi (a);
864 }
865 #endif
866
867 #ifdef L_fixunsdfdi
868 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
869 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
870
871 DItype
872 __fixunsdfdi (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 (DFtype a)
902 {
903   if (a < 0)
904     return - __fixunsdfdi (-a);
905   return __fixunsdfdi (a);
906 }
907 #endif
908
909 #ifdef L_fixunssfdi
910 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
911 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
912
913 DItype
914 __fixunssfdi (SFtype original_a)
915 {
916   /* Convert the SFtype to a DFtype, because that is surely not going
917      to lose any bits.  Some day someone else can write a faster version
918      that avoids converting to DFtype, and verify it really works right.  */
919   DFtype a = original_a;
920   DFtype b;
921   UDItype v;
922
923   if (a < 0)
924     return 0;
925
926   /* Compute high word of result, as a flonum.  */
927   b = (a / HIGH_WORD_COEFF);
928   /* Convert that to fixed (but not to DItype!),
929      and shift it into the high word.  */
930   v = (USItype) b;
931   v <<= WORD_SIZE;
932   /* Remove high part from the DFtype, leaving the low part as flonum.  */
933   a -= (DFtype)v;
934   /* Convert that to fixed (but not to DItype!) and add it in.
935      Sometimes A comes out negative.  This is significant, since
936      A has more bits than a long int does.  */
937   if (a < 0)
938     v -= (USItype) (- a);
939   else
940     v += (USItype) a;
941   return v;
942 }
943 #endif
944
945 #ifdef L_fixsfdi
946 DItype
947 __fixsfdi (SFtype a)
948 {
949   if (a < 0)
950     return - __fixunssfdi (-a);
951   return __fixunssfdi (a);
952 }
953 #endif
954
955 #if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
956 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
957 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
958 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
959
960 XFtype
961 __floatdixf (DItype u)
962 {
963   XFtype d;
964
965   d = (SItype) (u >> WORD_SIZE);
966   d *= HIGH_HALFWORD_COEFF;
967   d *= HIGH_HALFWORD_COEFF;
968   d += (USItype) (u & (HIGH_WORD_COEFF - 1));
969
970   return d;
971 }
972 #endif
973
974 #if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
975 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
976 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
977 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
978
979 TFtype
980 __floatditf (DItype u)
981 {
982   TFtype d;
983
984   d = (SItype) (u >> WORD_SIZE);
985   d *= HIGH_HALFWORD_COEFF;
986   d *= HIGH_HALFWORD_COEFF;
987   d += (USItype) (u & (HIGH_WORD_COEFF - 1));
988
989   return d;
990 }
991 #endif
992
993 #ifdef L_floatdidf
994 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
995 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
996 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
997
998 DFtype
999 __floatdidf (DItype u)
1000 {
1001   DFtype d;
1002
1003   d = (SItype) (u >> WORD_SIZE);
1004   d *= HIGH_HALFWORD_COEFF;
1005   d *= HIGH_HALFWORD_COEFF;
1006   d += (USItype) (u & (HIGH_WORD_COEFF - 1));
1007
1008   return d;
1009 }
1010 #endif
1011
1012 #ifdef L_floatdisf
1013 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
1014 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
1015 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
1016 #define DI_SIZE (sizeof (DItype) * BITS_PER_UNIT)
1017
1018 /* Define codes for all the float formats that we know of.  Note
1019    that this is copied from real.h.  */
1020    
1021 #define UNKNOWN_FLOAT_FORMAT 0
1022 #define IEEE_FLOAT_FORMAT 1
1023 #define VAX_FLOAT_FORMAT 2
1024 #define IBM_FLOAT_FORMAT 3
1025
1026 /* Default to IEEE float if not specified.  Nearly all machines use it.  */
1027 #ifndef HOST_FLOAT_FORMAT
1028 #define HOST_FLOAT_FORMAT       IEEE_FLOAT_FORMAT
1029 #endif
1030
1031 #if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1032 #define DF_SIZE 53
1033 #define SF_SIZE 24
1034 #endif
1035
1036 #if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
1037 #define DF_SIZE 56
1038 #define SF_SIZE 24
1039 #endif
1040
1041 #if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
1042 #define DF_SIZE 56
1043 #define SF_SIZE 24
1044 #endif
1045
1046 SFtype
1047 __floatdisf (DItype u)
1048 {
1049   /* Do the calculation in DFmode
1050      so that we don't lose any of the precision of the high word
1051      while multiplying it.  */
1052   DFtype f;
1053
1054   /* Protect against double-rounding error.
1055      Represent any low-order bits, that might be truncated in DFmode,
1056      by a bit that won't be lost.  The bit can go in anywhere below the
1057      rounding position of the SFmode.  A fixed mask and bit position
1058      handles all usual configurations.  It doesn't handle the case
1059      of 128-bit DImode, however.  */
1060   if (DF_SIZE < DI_SIZE
1061       && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1062     {
1063 #define REP_BIT ((USItype) 1 << (DI_SIZE - DF_SIZE))
1064       if (! (- ((DItype) 1 << DF_SIZE) < u
1065              && u < ((DItype) 1 << DF_SIZE)))
1066         {
1067           if ((USItype) u & (REP_BIT - 1))
1068             u |= REP_BIT;
1069         }
1070     }
1071   f = (SItype) (u >> WORD_SIZE);
1072   f *= HIGH_HALFWORD_COEFF;
1073   f *= HIGH_HALFWORD_COEFF;
1074   f += (USItype) (u & (HIGH_WORD_COEFF - 1));
1075
1076   return (SFtype) f;
1077 }
1078 #endif
1079
1080 #if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
1081 /* Reenable the normal types, in case limits.h needs them.  */
1082 #undef char
1083 #undef short
1084 #undef int
1085 #undef long
1086 #undef unsigned
1087 #undef float
1088 #undef double
1089 #undef MIN
1090 #undef MAX
1091 #include <limits.h>
1092
1093 USItype
1094 __fixunsxfsi (XFtype a)
1095 {
1096   if (a >= - (DFtype) LONG_MIN)
1097     return (SItype) (a + LONG_MIN) - LONG_MIN;
1098   return (SItype) a;
1099 }
1100 #endif
1101
1102 #ifdef L_fixunsdfsi
1103 /* Reenable the normal types, in case limits.h needs them.  */
1104 #undef char
1105 #undef short
1106 #undef int
1107 #undef long
1108 #undef unsigned
1109 #undef float
1110 #undef double
1111 #undef MIN
1112 #undef MAX
1113 #include <limits.h>
1114
1115 USItype
1116 __fixunsdfsi (DFtype a)
1117 {
1118   if (a >= - (DFtype) LONG_MIN)
1119     return (SItype) (a + LONG_MIN) - LONG_MIN;
1120   return (SItype) a;
1121 }
1122 #endif
1123
1124 #ifdef L_fixunssfsi
1125 /* Reenable the normal types, in case limits.h needs them.  */
1126 #undef char
1127 #undef short
1128 #undef int
1129 #undef long
1130 #undef unsigned
1131 #undef float
1132 #undef double
1133 #undef MIN
1134 #undef MAX
1135 #include <limits.h>
1136
1137 USItype
1138 __fixunssfsi (SFtype a)
1139 {
1140   if (a >= - (SFtype) LONG_MIN)
1141     return (SItype) (a + LONG_MIN) - LONG_MIN;
1142   return (SItype) a;
1143 }
1144 #endif
1145 \f
1146 /* From here on down, the routines use normal data types.  */
1147
1148 #define SItype bogus_type
1149 #define USItype bogus_type
1150 #define DItype bogus_type
1151 #define UDItype bogus_type
1152 #define SFtype bogus_type
1153 #define DFtype bogus_type
1154
1155 #undef char
1156 #undef short
1157 #undef int
1158 #undef long
1159 #undef unsigned
1160 #undef float
1161 #undef double
1162 \f
1163 #ifdef L__gcc_bcmp
1164
1165 /* Like bcmp except the sign is meaningful.
1166    Result is negative if S1 is less than S2,
1167    positive if S1 is greater, 0 if S1 and S2 are equal.  */
1168
1169 int
1170 __gcc_bcmp (unsigned char *s1, unsigned char *s2, size_t size)
1171 {
1172   while (size > 0)
1173     {
1174       unsigned char c1 = *s1++, c2 = *s2++;
1175       if (c1 != c2)
1176         return c1 - c2;
1177       size--;
1178     }
1179   return 0;
1180 }
1181
1182 #endif
1183 \f\f
1184 #ifdef L__dummy
1185 void
1186 __dummy () {}
1187 #endif
1188
1189 #ifdef L_varargs
1190 #ifdef __i860__
1191 #if defined(__svr4__) || defined(__alliant__)
1192         asm ("  .text");
1193         asm ("  .align  4");
1194
1195 /* The Alliant needs the added underscore.  */
1196         asm (".globl    __builtin_saveregs");
1197 asm ("__builtin_saveregs:");
1198         asm (".globl    ___builtin_saveregs");
1199 asm ("___builtin_saveregs:");
1200
1201         asm ("  andnot  0x0f,%sp,%sp"); /* round down to 16-byte boundary */
1202         asm ("  adds    -96,%sp,%sp");  /* allocate stack space for reg save
1203                                            area and also for a new va_list
1204                                            structure */
1205         /* Save all argument registers in the arg reg save area.  The
1206            arg reg save area must have the following layout (according
1207            to the svr4 ABI):
1208
1209                 struct {
1210                   union  {
1211                     float freg[8];
1212                     double dreg[4];
1213                   } float_regs;
1214                   long  ireg[12];
1215                 };
1216         */
1217
1218         asm ("  fst.q   %f8,  0(%sp)"); /* save floating regs (f8-f15)  */
1219         asm ("  fst.q   %f12,16(%sp)"); 
1220
1221         asm ("  st.l    %r16,32(%sp)"); /* save integer regs (r16-r27) */
1222         asm ("  st.l    %r17,36(%sp)"); 
1223         asm ("  st.l    %r18,40(%sp)");
1224         asm ("  st.l    %r19,44(%sp)");
1225         asm ("  st.l    %r20,48(%sp)");
1226         asm ("  st.l    %r21,52(%sp)");
1227         asm ("  st.l    %r22,56(%sp)");
1228         asm ("  st.l    %r23,60(%sp)");
1229         asm ("  st.l    %r24,64(%sp)");
1230         asm ("  st.l    %r25,68(%sp)");
1231         asm ("  st.l    %r26,72(%sp)");
1232         asm ("  st.l    %r27,76(%sp)");
1233
1234         asm ("  adds    80,%sp,%r16");  /* compute the address of the new
1235                                            va_list structure.  Put in into
1236                                            r16 so that it will be returned
1237                                            to the caller.  */
1238
1239         /* Initialize all fields of the new va_list structure.  This
1240            structure looks like:
1241
1242                 typedef struct {
1243                     unsigned long       ireg_used;
1244                     unsigned long       freg_used;
1245                     long                *reg_base;
1246                     long                *mem_ptr;
1247                 } va_list;
1248         */
1249
1250         asm ("  st.l    %r0, 0(%r16)"); /* nfixed */
1251         asm ("  st.l    %r0, 4(%r16)"); /* nfloating */
1252         asm ("  st.l    %sp, 8(%r16)"); /* __va_ctl points to __va_struct.  */
1253         asm ("  bri     %r1");          /* delayed return */
1254         asm ("  st.l    %r28,12(%r16)"); /* pointer to overflow args */
1255
1256 #else /* not __svr4__ */
1257 #if defined(__PARAGON__)
1258         /*
1259          *      we'll use SVR4-ish varargs but need SVR3.2 assembler syntax,
1260          *      and we stand a better chance of hooking into libraries
1261          *      compiled by PGI.  [andyp@ssd.intel.com]
1262          */
1263         asm ("  .text");
1264         asm ("  .align  4");
1265         asm (".globl    __builtin_saveregs");
1266 asm ("__builtin_saveregs:");
1267         asm (".globl    ___builtin_saveregs");
1268 asm ("___builtin_saveregs:");
1269
1270         asm ("  andnot  0x0f,sp,sp");   /* round down to 16-byte boundary */
1271         asm ("  adds    -96,sp,sp");    /* allocate stack space for reg save
1272                                            area and also for a new va_list
1273                                            structure */
1274         /* Save all argument registers in the arg reg save area.  The
1275            arg reg save area must have the following layout (according
1276            to the svr4 ABI):
1277
1278                 struct {
1279                   union  {
1280                     float freg[8];
1281                     double dreg[4];
1282                   } float_regs;
1283                   long  ireg[12];
1284                 };
1285         */
1286
1287         asm ("  fst.q   f8,  0(sp)");
1288         asm ("  fst.q   f12,16(sp)"); 
1289         asm ("  st.l    r16,32(sp)");
1290         asm ("  st.l    r17,36(sp)"); 
1291         asm ("  st.l    r18,40(sp)");
1292         asm ("  st.l    r19,44(sp)");
1293         asm ("  st.l    r20,48(sp)");
1294         asm ("  st.l    r21,52(sp)");
1295         asm ("  st.l    r22,56(sp)");
1296         asm ("  st.l    r23,60(sp)");
1297         asm ("  st.l    r24,64(sp)");
1298         asm ("  st.l    r25,68(sp)");
1299         asm ("  st.l    r26,72(sp)");
1300         asm ("  st.l    r27,76(sp)");
1301
1302         asm ("  adds    80,sp,r16");  /* compute the address of the new
1303                                            va_list structure.  Put in into
1304                                            r16 so that it will be returned
1305                                            to the caller.  */
1306
1307         /* Initialize all fields of the new va_list structure.  This
1308            structure looks like:
1309
1310                 typedef struct {
1311                     unsigned long       ireg_used;
1312                     unsigned long       freg_used;
1313                     long                *reg_base;
1314                     long                *mem_ptr;
1315                 } va_list;
1316         */
1317
1318         asm ("  st.l    r0, 0(r16)"); /* nfixed */
1319         asm ("  st.l    r0, 4(r16)"); /* nfloating */
1320         asm ("  st.l    sp, 8(r16)"); /* __va_ctl points to __va_struct.  */
1321         asm ("  bri     r1");           /* delayed return */
1322         asm ("   st.l   r28,12(r16)"); /* pointer to overflow args */
1323 #else /* not __PARAGON__ */
1324         asm ("  .text");
1325         asm ("  .align  4");
1326
1327         asm (".globl    ___builtin_saveregs");
1328         asm ("___builtin_saveregs:");
1329         asm ("  mov     sp,r30");
1330         asm ("  andnot  0x0f,sp,sp");
1331         asm ("  adds    -96,sp,sp");  /* allocate sufficient space on the stack */
1332
1333 /* Fill in the __va_struct.  */
1334         asm ("  st.l    r16, 0(sp)"); /* save integer regs (r16-r27) */
1335         asm ("  st.l    r17, 4(sp)"); /* int    fixed[12] */
1336         asm ("  st.l    r18, 8(sp)");
1337         asm ("  st.l    r19,12(sp)");
1338         asm ("  st.l    r20,16(sp)");
1339         asm ("  st.l    r21,20(sp)");
1340         asm ("  st.l    r22,24(sp)");
1341         asm ("  st.l    r23,28(sp)");
1342         asm ("  st.l    r24,32(sp)");
1343         asm ("  st.l    r25,36(sp)");
1344         asm ("  st.l    r26,40(sp)");
1345         asm ("  st.l    r27,44(sp)");
1346
1347         asm ("  fst.q   f8, 48(sp)"); /* save floating regs (f8-f15) */
1348         asm ("  fst.q   f12,64(sp)"); /* int floating[8] */
1349
1350 /* Fill in the __va_ctl.  */
1351         asm ("  st.l    sp, 80(sp)"); /* __va_ctl points to __va_struct.  */
1352         asm ("  st.l    r28,84(sp)"); /* pointer to more args */
1353         asm ("  st.l    r0, 88(sp)"); /* nfixed */
1354         asm ("  st.l    r0, 92(sp)"); /* nfloating */
1355
1356         asm ("  adds    80,sp,r16");  /* return address of the __va_ctl.  */
1357         asm ("  bri     r1");
1358         asm ("  mov     r30,sp");
1359                                 /* recover stack and pass address to start 
1360                                    of data.  */
1361 #endif /* not __PARAGON__ */
1362 #endif /* not __svr4__ */
1363 #else /* not __i860__ */
1364 #ifdef __sparc__
1365         asm (".global __builtin_saveregs");
1366         asm ("__builtin_saveregs:");
1367         asm (".global ___builtin_saveregs");
1368         asm ("___builtin_saveregs:");
1369 #ifdef NEED_PROC_COMMAND
1370         asm (".proc 020");
1371 #endif
1372         asm ("st %i0,[%fp+68]");
1373         asm ("st %i1,[%fp+72]");
1374         asm ("st %i2,[%fp+76]");
1375         asm ("st %i3,[%fp+80]");
1376         asm ("st %i4,[%fp+84]");
1377         asm ("retl");
1378         asm ("st %i5,[%fp+88]");
1379 #ifdef NEED_TYPE_COMMAND
1380         asm (".type __builtin_saveregs,#function");
1381         asm (".size __builtin_saveregs,.-__builtin_saveregs");
1382 #endif
1383 #else /* not __sparc__ */
1384 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1385
1386   asm ("        .text");
1387 #ifdef __mips16
1388   asm ("        .set nomips16");
1389 #endif
1390   asm ("        .ent __builtin_saveregs");
1391   asm ("        .globl __builtin_saveregs");
1392   asm ("__builtin_saveregs:");
1393   asm ("        sw      $4,0($30)");
1394   asm ("        sw      $5,4($30)");
1395   asm ("        sw      $6,8($30)");
1396   asm ("        sw      $7,12($30)");
1397   asm ("        j       $31");
1398   asm ("        .end __builtin_saveregs");
1399 #else /* not __mips__, etc.  */
1400
1401 void *
1402 __builtin_saveregs ()
1403 {
1404   abort ();
1405 }
1406
1407 #endif /* not __mips__ */
1408 #endif /* not __sparc__ */
1409 #endif /* not __i860__ */
1410 #endif
1411 \f
1412 #ifdef L_eprintf
1413 #ifndef inhibit_libc
1414
1415 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1416 #include <stdio.h>
1417 /* This is used by the `assert' macro.  */
1418 extern void __eprintf (const char *, const char *, unsigned int, const char *)
1419   __attribute__ ((__noreturn__));
1420
1421 void
1422 __eprintf (const char *string, const char *expression,
1423            unsigned int line, const char *filename)
1424 {
1425   fprintf (stderr, string, expression, line, filename);
1426   fflush (stderr);
1427   abort ();
1428 }
1429
1430 #endif
1431 #endif
1432
1433 #ifdef L_bb
1434
1435 /* Structure emitted by -a  */
1436 struct bb
1437 {
1438   long zero_word;
1439   const char *filename;
1440   long *counts;
1441   long ncounts;
1442   struct bb *next;
1443   const unsigned long *addresses;
1444
1445   /* Older GCC's did not emit these fields.  */
1446   long nwords;
1447   const char **functions;
1448   const long *line_nums;
1449   const char **filenames;
1450   char *flags;
1451 };
1452
1453 #ifdef BLOCK_PROFILER_CODE
1454 BLOCK_PROFILER_CODE
1455 #else
1456 #ifndef inhibit_libc
1457
1458 /* Simple minded basic block profiling output dumper for
1459    systems that don't provide tcov support.  At present,
1460    it requires atexit and stdio.  */
1461
1462 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1463 #include <stdio.h>
1464 char *ctime ();
1465
1466 #include "gbl-ctors.h"
1467 #include "gcov-io.h"
1468 #include <string.h>
1469
1470 static struct bb *bb_head;
1471
1472 static int num_digits (long value, int base) __attribute__ ((const));
1473
1474 /* Return the number of digits needed to print a value */
1475 /* __inline__ */ static int num_digits (long value, int base)
1476 {
1477   int minus = (value < 0 && base != 16);
1478   unsigned long v = (minus) ? -value : value;
1479   int ret = minus;
1480
1481   do
1482     {
1483       v /= base;
1484       ret++;
1485     }
1486   while (v);
1487
1488   return ret;
1489 }
1490
1491 void
1492 __bb_exit_func (void)
1493 {
1494   FILE *da_file, *file;
1495   long time_value;
1496   int i;
1497
1498   if (bb_head == 0)
1499     return;
1500
1501   i = strlen (bb_head->filename) - 3;
1502
1503   if (!strcmp (bb_head->filename+i, ".da"))
1504     {
1505       /* Must be -fprofile-arcs not -a.
1506          Dump data in a form that gcov expects.  */
1507
1508       struct bb *ptr;
1509
1510       for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1511         {
1512           /* If the file exists, and the number of counts in it is the same,
1513              then merge them in.  */
1514              
1515           if ((da_file = fopen (ptr->filename, "r")) != 0)
1516             {
1517               long n_counts = 0;
1518               
1519               if (__read_long (&n_counts, da_file, 8) != 0)
1520                 {
1521                   fprintf (stderr, "arc profiling: Can't read output file %s.\n",
1522                            ptr->filename);
1523                   continue;
1524                 }
1525
1526               if (n_counts == ptr->ncounts)
1527                 {
1528                   int i;
1529
1530                   for (i = 0; i < n_counts; i++)
1531                     {
1532                       long v = 0;
1533
1534                       if (__read_long (&v, da_file, 8) != 0)
1535                         {
1536                           fprintf (stderr, "arc profiling: Can't read output file %s.\n",
1537                                    ptr->filename);
1538                           break;
1539                         }
1540                       ptr->counts[i] += v;
1541                     }
1542                 }
1543
1544               if (fclose (da_file) == EOF)
1545                 fprintf (stderr, "arc profiling: Error closing output file %s.\n",
1546                          ptr->filename);
1547             }
1548           if ((da_file = fopen (ptr->filename, "w")) == 0)
1549             {
1550               fprintf (stderr, "arc profiling: Can't open output file %s.\n",
1551                        ptr->filename);
1552               continue;
1553             }
1554
1555           /* ??? Should first write a header to the file.  Preferably, a 4 byte
1556              magic number, 4 bytes containing the time the program was
1557              compiled, 4 bytes containing the last modification time of the
1558              source file, and 4 bytes indicating the compiler options used.
1559
1560              That way we can easily verify that the proper source/executable/
1561              data file combination is being used from gcov.  */
1562
1563           if (__write_long (ptr->ncounts, da_file, 8) != 0)
1564             {
1565               
1566               fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1567                        ptr->filename);
1568             }
1569           else
1570             {
1571               int j;
1572               long *count_ptr = ptr->counts;
1573               int ret = 0;
1574               for (j = ptr->ncounts; j > 0; j--)
1575                 {
1576                   if (__write_long (*count_ptr, da_file, 8) != 0)
1577                     {
1578                       ret=1;
1579                       break;
1580                     }
1581                   count_ptr++;
1582                 }
1583               if (ret)
1584                 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1585                          ptr->filename);
1586             }
1587           
1588           if (fclose (da_file) == EOF)
1589             fprintf (stderr, "arc profiling: Error closing output file %s.\n",
1590                      ptr->filename);
1591         }
1592
1593       return;
1594     }
1595
1596   /* Must be basic block profiling.  Emit a human readable output file.  */
1597
1598   file = fopen ("bb.out", "a");
1599
1600   if (!file)
1601     perror ("bb.out");
1602
1603   else
1604     {
1605       struct bb *ptr;
1606
1607       /* This is somewhat type incorrect, but it avoids worrying about
1608          exactly where time.h is included from.  It should be ok unless
1609          a void * differs from other pointer formats, or if sizeof (long)
1610          is < sizeof (time_t).  It would be nice if we could assume the
1611          use of rationale standards here.  */
1612
1613       time ((void *) &time_value);
1614       fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value));
1615
1616       /* We check the length field explicitly in order to allow compatibility
1617          with older GCC's which did not provide it.  */
1618
1619       for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1620         {
1621           int i;
1622           int func_p    = (ptr->nwords >= sizeof (struct bb)
1623                            && ptr->nwords <= 1000
1624                            && ptr->functions);
1625           int line_p    = (func_p && ptr->line_nums);
1626           int file_p    = (func_p && ptr->filenames);
1627           int addr_p    = (ptr->addresses != 0);
1628           long ncounts  = ptr->ncounts;
1629           long cnt_max  = 0;
1630           long line_max = 0;
1631           long addr_max = 0;
1632           int file_len  = 0;
1633           int func_len  = 0;
1634           int blk_len   = num_digits (ncounts, 10);
1635           int cnt_len;
1636           int line_len;
1637           int addr_len;
1638
1639           fprintf (file, "File %s, %ld basic blocks \n\n",
1640                    ptr->filename, ncounts);
1641
1642           /* Get max values for each field.  */
1643           for (i = 0; i < ncounts; i++)
1644             {
1645               const char *p;
1646               int len;
1647
1648               if (cnt_max < ptr->counts[i])
1649                 cnt_max = ptr->counts[i];
1650
1651               if (addr_p && addr_max < ptr->addresses[i])
1652                 addr_max = ptr->addresses[i];
1653
1654               if (line_p && line_max < ptr->line_nums[i])
1655                 line_max = ptr->line_nums[i];
1656
1657               if (func_p)
1658                 {
1659                   p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>";
1660                   len = strlen (p);
1661                   if (func_len < len)
1662                     func_len = len;
1663                 }
1664
1665               if (file_p)
1666                 {
1667                   p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>";
1668                   len = strlen (p);
1669                   if (file_len < len)
1670                     file_len = len;
1671                 }
1672             }
1673
1674           addr_len = num_digits (addr_max, 16);
1675           cnt_len  = num_digits (cnt_max, 10);
1676           line_len = num_digits (line_max, 10);
1677
1678           /* Now print out the basic block information.  */
1679           for (i = 0; i < ncounts; i++)
1680             {
1681               fprintf (file,
1682                        "    Block #%*d: executed %*ld time(s)",
1683                        blk_len, i+1,
1684                        cnt_len, ptr->counts[i]);
1685
1686               if (addr_p)
1687                 fprintf (file, " address= 0x%.*lx", addr_len,
1688                          ptr->addresses[i]);
1689
1690               if (func_p)
1691                 fprintf (file, " function= %-*s", func_len,
1692                          (ptr->functions[i]) ? ptr->functions[i] : "<none>");
1693
1694               if (line_p)
1695                 fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]);
1696
1697               if (file_p)
1698                 fprintf (file, " file= %s",
1699                          (ptr->filenames[i]) ? ptr->filenames[i] : "<none>");
1700
1701               fprintf (file, "\n");
1702             }
1703
1704           fprintf (file, "\n");
1705           fflush (file);
1706         }
1707
1708       fprintf (file, "\n\n");
1709       fclose (file);
1710     }
1711 }
1712
1713 void
1714 __bb_init_func (struct bb *blocks)
1715 {
1716   /* User is supposed to check whether the first word is non-0,
1717      but just in case....  */
1718
1719   if (blocks->zero_word)
1720     return;
1721
1722   /* Initialize destructor.  */
1723   if (!bb_head)
1724     atexit (__bb_exit_func);
1725
1726   /* Set up linked list.  */
1727   blocks->zero_word = 1;
1728   blocks->next = bb_head;
1729   bb_head = blocks;
1730 }
1731
1732 #ifndef MACHINE_STATE_SAVE
1733 #define MACHINE_STATE_SAVE(ID)
1734 #endif
1735 #ifndef MACHINE_STATE_RESTORE
1736 #define MACHINE_STATE_RESTORE(ID)
1737 #endif
1738
1739 /* Number of buckets in hashtable of basic block addresses.  */
1740
1741 #define BB_BUCKETS 311
1742
1743 /* Maximum length of string in file bb.in.  */
1744
1745 #define BBINBUFSIZE 500
1746
1747 /* BBINBUFSIZE-1 with double quotes. We could use #BBINBUFSIZE or
1748    "BBINBUFSIZE" but want to avoid trouble with preprocessors.  */
1749
1750 #define BBINBUFSIZESTR "499"
1751
1752 struct bb_edge
1753 {
1754   struct bb_edge *next;
1755   unsigned long src_addr;
1756   unsigned long dst_addr;
1757   unsigned long count;
1758 };
1759
1760 enum bb_func_mode
1761 {
1762   TRACE_KEEP = 0, TRACE_ON = 1, TRACE_OFF = 2
1763 };
1764
1765 struct bb_func
1766 {
1767   struct bb_func *next;
1768   char *funcname;
1769   char *filename;
1770   enum bb_func_mode mode;
1771 };
1772
1773 /* This is the connection to the outside world.
1774    The BLOCK_PROFILER macro must set __bb.blocks
1775    and __bb.blockno.  */
1776
1777 struct {
1778   unsigned long blockno;
1779   struct bb *blocks;
1780 } __bb;
1781
1782 /* Vars to store addrs of source and destination basic blocks 
1783    of a jump.  */
1784
1785 static unsigned long bb_src = 0;
1786 static unsigned long bb_dst = 0;
1787
1788 static FILE *bb_tracefile = (FILE *) 0;
1789 static struct bb_edge **bb_hashbuckets = (struct bb_edge **) 0;
1790 static struct bb_func *bb_func_head = (struct bb_func *) 0;
1791 static unsigned long bb_callcount = 0;
1792 static int bb_mode = 0;
1793
1794 static unsigned long *bb_stack = (unsigned long *) 0;
1795 static size_t bb_stacksize = 0;
1796
1797 static int reported = 0;
1798
1799 /* Trace modes:
1800 Always             :   Print execution frequencies of basic blocks
1801                        to file bb.out.
1802 bb_mode & 1 != 0   :   Dump trace of basic blocks to file bbtrace[.gz]
1803 bb_mode & 2 != 0   :   Print jump frequencies to file bb.out.
1804 bb_mode & 4 != 0   :   Cut call instructions from basic block flow.
1805 bb_mode & 8 != 0   :   Insert return instructions in basic block flow.
1806 */
1807
1808 #ifdef HAVE_POPEN
1809
1810 /*#include <sys/types.h>*/
1811 #include <sys/stat.h>
1812 /*#include <malloc.h>*/
1813
1814 /* Commands executed by gopen.  */
1815
1816 #define GOPENDECOMPRESS "gzip -cd "
1817 #define GOPENCOMPRESS "gzip -c >"
1818
1819 /* Like fopen but pipes through gzip.  mode may only be "r" or "w".
1820    If it does not compile, simply replace gopen by fopen and delete
1821    '.gz' from any first parameter to gopen.  */
1822
1823 static FILE *
1824 gopen (char *fn, char *mode)
1825 {
1826   int use_gzip;
1827   char *p;
1828
1829   if (mode[1])
1830     return (FILE *) 0;
1831
1832   if (mode[0] != 'r' && mode[0] != 'w') 
1833     return (FILE *) 0;
1834
1835   p = fn + strlen (fn)-1;
1836   use_gzip = ((p[-1] == '.' && (p[0] == 'Z' || p[0] == 'z'))
1837               || (p[-2] == '.' && p[-1] == 'g' && p[0] == 'z'));
1838
1839   if (use_gzip)
1840     {
1841       if (mode[0]=='r')
1842         {
1843           FILE *f;
1844           char *s = (char *) malloc (sizeof (char) * strlen (fn)
1845                                      + sizeof (GOPENDECOMPRESS));
1846           strcpy (s, GOPENDECOMPRESS);
1847           strcpy (s + (sizeof (GOPENDECOMPRESS)-1), fn);
1848           f = popen (s, mode);
1849           free (s);
1850           return f;
1851         }
1852
1853       else
1854         {
1855           FILE *f;
1856           char *s = (char *) malloc (sizeof (char) * strlen (fn)
1857                                      + sizeof (GOPENCOMPRESS));
1858           strcpy (s, GOPENCOMPRESS);
1859           strcpy (s + (sizeof (GOPENCOMPRESS)-1), fn);
1860           if (!(f = popen (s, mode)))
1861             f = fopen (s, mode);
1862           free (s);
1863           return f;
1864         }
1865     }
1866
1867   else
1868     return fopen (fn, mode);
1869 }
1870
1871 static int
1872 gclose (FILE *f)
1873 {
1874   struct stat buf;
1875
1876   if (f != 0)
1877     {
1878       if (!fstat (fileno (f), &buf) && S_ISFIFO (buf.st_mode))
1879         return pclose (f);
1880
1881       return fclose (f);
1882     }
1883   return 0;
1884 }
1885
1886 #endif /* HAVE_POPEN */
1887
1888 /* Called once per program.  */
1889
1890 static void
1891 __bb_exit_trace_func ()
1892 {
1893   FILE *file = fopen ("bb.out", "a");
1894   struct bb_func *f;
1895   struct bb *b;
1896         
1897   if (!file)
1898     perror ("bb.out");
1899
1900   if (bb_mode & 1)
1901     {
1902       if (!bb_tracefile)
1903         perror ("bbtrace");
1904       else
1905 #ifdef HAVE_POPEN
1906         gclose (bb_tracefile);
1907 #else
1908         fclose (bb_tracefile);
1909 #endif /* HAVE_POPEN */
1910     }
1911
1912   /* Check functions in `bb.in'.  */
1913
1914   if (file)
1915     {
1916       long time_value;
1917       const struct bb_func *p;
1918       int printed_something = 0;
1919       struct bb *ptr;
1920       long blk;
1921
1922       /* This is somewhat type incorrect.  */
1923       time ((void *) &time_value);
1924
1925       for (p = bb_func_head; p != (struct bb_func *) 0; p = p->next)
1926         {
1927           for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1928             {
1929               if (!ptr->filename || (p->filename != (char *) 0 && strcmp (p->filename, ptr->filename)))
1930                 continue;
1931               for (blk = 0; blk < ptr->ncounts; blk++)
1932                 {
1933                   if (!strcmp (p->funcname, ptr->functions[blk]))
1934                     goto found;
1935                 }
1936             }
1937   
1938           if (!printed_something)
1939             {
1940               fprintf (file, "Functions in `bb.in' not executed during basic block profiling on %s\n", ctime ((void *) &time_value));
1941               printed_something = 1;
1942             }
1943
1944           fprintf (file, "\tFunction %s", p->funcname);
1945           if (p->filename)
1946               fprintf (file, " of file %s", p->filename);
1947           fprintf (file, "\n" );
1948   
1949 found:        ;
1950         }
1951
1952       if (printed_something)
1953        fprintf (file, "\n");
1954
1955     }
1956
1957   if (bb_mode & 2)
1958     {
1959       if (!bb_hashbuckets)
1960         {
1961           if (!reported)
1962             {
1963               fprintf (stderr, "Profiler: out of memory\n");
1964               reported = 1;
1965             }
1966           return;
1967         }
1968     
1969       else if (file)
1970         {
1971           long time_value;
1972           int i;
1973           unsigned long addr_max = 0;
1974           unsigned long cnt_max  = 0;
1975           int cnt_len;
1976           int addr_len;
1977     
1978           /* This is somewhat type incorrect, but it avoids worrying about
1979              exactly where time.h is included from.  It should be ok unless
1980              a void * differs from other pointer formats, or if sizeof (long)
1981              is < sizeof (time_t).  It would be nice if we could assume the
1982              use of rationale standards here.  */
1983     
1984           time ((void *) &time_value);
1985           fprintf (file, "Basic block jump tracing");
1986
1987           switch (bb_mode & 12)
1988             {
1989               case 0:
1990                 fprintf (file, " (with call)");
1991               break;
1992
1993               case 4:
1994                 /* Print nothing.  */
1995               break;
1996
1997               case 8:
1998                 fprintf (file, " (with call & ret)");
1999               break;
2000
2001               case 12:
2002                 fprintf (file, " (with ret)");
2003               break;
2004             }
2005
2006           fprintf (file, " finished on %s\n", ctime ((void *) &time_value));
2007     
2008           for (i = 0; i < BB_BUCKETS; i++)
2009             {
2010                struct bb_edge *bucket = bb_hashbuckets[i];
2011                for ( ; bucket; bucket = bucket->next )
2012                  {
2013                    if (addr_max < bucket->src_addr) 
2014                      addr_max = bucket->src_addr;
2015                    if (addr_max < bucket->dst_addr) 
2016                      addr_max = bucket->dst_addr;
2017                    if (cnt_max < bucket->count) 
2018                      cnt_max = bucket->count;
2019                  }
2020             }
2021           addr_len = num_digits (addr_max, 16);
2022           cnt_len  = num_digits (cnt_max, 10);
2023     
2024           for ( i = 0; i < BB_BUCKETS; i++)
2025             {
2026                struct bb_edge *bucket = bb_hashbuckets[i];
2027                for ( ; bucket; bucket = bucket->next )
2028                  {
2029                    fprintf (file, "Jump from block 0x%.*lx to "
2030                                   "block 0x%.*lx executed %*lu time(s)\n", 
2031                             addr_len, bucket->src_addr, 
2032                             addr_len, bucket->dst_addr, 
2033                             cnt_len, bucket->count);
2034                  }
2035             }
2036   
2037           fprintf (file, "\n");
2038
2039         }
2040     }
2041
2042    if (file)
2043      fclose (file);
2044
2045    /* Free allocated memory.  */
2046
2047    f = bb_func_head;
2048    while (f)
2049      {
2050        struct bb_func *old = f;
2051
2052        f = f->next;
2053        if (old->funcname) free (old->funcname);
2054        if (old->filename) free (old->filename);
2055        free (old);
2056      }
2057
2058    if (bb_stack)
2059      free (bb_stack);
2060
2061    if (bb_hashbuckets)
2062      {
2063        int i;
2064
2065        for (i = 0; i < BB_BUCKETS; i++)
2066          {
2067            struct bb_edge *old, *bucket = bb_hashbuckets[i];
2068
2069            while (bucket)
2070              {
2071                old = bucket;
2072                bucket = bucket->next;
2073                free (old);
2074              }
2075          }
2076        free (bb_hashbuckets);
2077      }
2078
2079    for (b = bb_head; b; b = b->next)
2080      if (b->flags) free (b->flags);
2081 }
2082
2083 /* Called once per program.  */
2084
2085 static void
2086 __bb_init_prg ()
2087 {
2088   FILE *file;
2089   char buf[BBINBUFSIZE];
2090   const char *p;
2091   const char *pos;
2092   enum bb_func_mode m;
2093   int i;
2094
2095   /* Initialize destructor.  */
2096   atexit (__bb_exit_func);
2097
2098   if (!(file = fopen ("bb.in", "r")))
2099     return;
2100
2101   while(fscanf (file, " %" BBINBUFSIZESTR "s ", buf) != EOF)
2102     {
2103       p = buf;
2104       if (*p == '-') 
2105         { 
2106           m = TRACE_OFF; 
2107           p++; 
2108         }
2109       else 
2110         { 
2111           m = TRACE_ON; 
2112         }
2113       if (!strcmp (p, "__bb_trace__"))
2114         bb_mode |= 1;
2115       else if (!strcmp (p, "__bb_jumps__"))
2116         bb_mode |= 2;
2117       else if (!strcmp (p, "__bb_hidecall__"))
2118         bb_mode |= 4;
2119       else if (!strcmp (p, "__bb_showret__"))
2120         bb_mode |= 8;
2121       else 
2122         {
2123           struct bb_func *f = (struct bb_func *) malloc (sizeof (struct bb_func));
2124           if (f)
2125             {
2126               unsigned long l;
2127               f->next = bb_func_head;
2128               if ((pos = strchr (p, ':')))
2129                 {
2130                   if (!(f->funcname = (char *) malloc (strlen (pos+1)+1)))
2131                     continue;
2132                   strcpy (f->funcname, pos+1);
2133                   l = pos-p;
2134                   if ((f->filename = (char *) malloc (l+1)))
2135                     {
2136                       strncpy (f->filename, p, l);
2137                       f->filename[l] = '\0';
2138                     }
2139                   else
2140                     f->filename = (char *) 0;
2141                 }
2142               else
2143                 {
2144                   if (!(f->funcname = (char *) malloc (strlen (p)+1)))
2145                     continue;
2146                   strcpy (f->funcname, p);
2147                   f->filename = (char *) 0;
2148                 }
2149               f->mode = m;
2150               bb_func_head = f;
2151             }
2152          }
2153     }
2154   fclose (file);
2155
2156 #ifdef HAVE_POPEN 
2157
2158   if (bb_mode & 1)
2159       bb_tracefile = gopen ("bbtrace.gz", "w");
2160
2161 #else
2162
2163   if (bb_mode & 1)
2164       bb_tracefile = fopen ("bbtrace", "w");
2165
2166 #endif /* HAVE_POPEN */
2167
2168   if (bb_mode & 2)
2169     {
2170       bb_hashbuckets = (struct bb_edge **) 
2171                    malloc (BB_BUCKETS * sizeof (struct bb_edge *));
2172       if (bb_hashbuckets)
2173         /* Use a loop here rather than calling bzero to avoid having to
2174            conditionalize its existance.  */
2175         for (i = 0; i < BB_BUCKETS; i++)
2176           bb_hashbuckets[i] = 0;
2177     }
2178
2179   if (bb_mode & 12)
2180     {
2181       bb_stacksize = 10;
2182       bb_stack = (unsigned long *) malloc (bb_stacksize * sizeof (*bb_stack));
2183     }
2184
2185   /* Initialize destructor.  */
2186   atexit (__bb_exit_trace_func);
2187 }
2188
2189 /* Called upon entering a basic block.  */
2190
2191 void
2192 __bb_trace_func ()
2193 {
2194   struct bb_edge *bucket;
2195
2196   MACHINE_STATE_SAVE("1")
2197
2198   if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2199     goto skip;
2200
2201   bb_dst = __bb.blocks->addresses[__bb.blockno];
2202   __bb.blocks->counts[__bb.blockno]++;
2203
2204   if (bb_tracefile)
2205     {
2206       fwrite (&bb_dst, sizeof (unsigned long), 1, bb_tracefile);
2207     }
2208
2209   if (bb_hashbuckets)
2210     {
2211       struct bb_edge **startbucket, **oldnext;
2212
2213       oldnext = startbucket
2214         = & bb_hashbuckets[ (((int) bb_src*8) ^ (int) bb_dst) % BB_BUCKETS ];
2215       bucket = *startbucket;
2216
2217       for (bucket = *startbucket; bucket; 
2218            oldnext = &(bucket->next), bucket = *oldnext)
2219         {
2220           if (bucket->src_addr == bb_src
2221               && bucket->dst_addr == bb_dst)
2222             {
2223               bucket->count++;
2224               *oldnext = bucket->next;
2225               bucket->next = *startbucket;
2226               *startbucket = bucket;
2227               goto ret;
2228             }
2229         }
2230
2231       bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2232
2233       if (!bucket)
2234         {
2235           if (!reported)
2236             {
2237               fprintf (stderr, "Profiler: out of memory\n");
2238               reported = 1;
2239             }
2240         }
2241
2242       else
2243         {
2244           bucket->src_addr = bb_src;
2245           bucket->dst_addr = bb_dst;
2246           bucket->next = *startbucket;
2247           *startbucket = bucket;
2248           bucket->count = 1;
2249         }
2250     }
2251
2252 ret:
2253   bb_src = bb_dst;
2254
2255 skip:
2256   ;
2257
2258   MACHINE_STATE_RESTORE("1")
2259
2260 }
2261
2262 /* Called when returning from a function and `__bb_showret__' is set.  */
2263
2264 static void
2265 __bb_trace_func_ret ()
2266 {
2267   struct bb_edge *bucket;
2268
2269   if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2270     goto skip;
2271
2272   if (bb_hashbuckets)
2273     {
2274       struct bb_edge **startbucket, **oldnext;
2275
2276       oldnext = startbucket
2277         = & bb_hashbuckets[ (((int) bb_dst * 8) ^ (int) bb_src) % BB_BUCKETS ];
2278       bucket = *startbucket;
2279
2280       for (bucket = *startbucket; bucket; 
2281            oldnext = &(bucket->next), bucket = *oldnext)
2282         {
2283           if (bucket->src_addr == bb_dst
2284                && bucket->dst_addr == bb_src)
2285             {
2286               bucket->count++;
2287               *oldnext = bucket->next;
2288               bucket->next = *startbucket;
2289               *startbucket = bucket;
2290               goto ret;
2291             }
2292         }
2293
2294       bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2295
2296       if (!bucket)
2297         {
2298           if (!reported)
2299             {
2300               fprintf (stderr, "Profiler: out of memory\n");
2301               reported = 1;
2302             }
2303         }
2304
2305       else
2306         {
2307           bucket->src_addr = bb_dst;
2308           bucket->dst_addr = bb_src;
2309           bucket->next = *startbucket;
2310           *startbucket = bucket;
2311           bucket->count = 1;
2312         }
2313     }
2314
2315 ret:
2316   bb_dst = bb_src;
2317
2318 skip:
2319   ;
2320
2321 }
2322
2323 /* Called upon entering the first function of a file.  */
2324
2325 static void
2326 __bb_init_file (struct bb *blocks)
2327 {
2328
2329   const struct bb_func *p;
2330   long blk, ncounts = blocks->ncounts;
2331   const char **functions = blocks->functions;
2332
2333   /* Set up linked list.  */
2334   blocks->zero_word = 1;
2335   blocks->next = bb_head;
2336   bb_head = blocks;
2337
2338   blocks->flags = 0;
2339   if (!bb_func_head
2340       || !(blocks->flags = (char *) malloc (sizeof (char) * blocks->ncounts)))
2341     return;
2342
2343   for (blk = 0; blk < ncounts; blk++)
2344     blocks->flags[blk] = 0;
2345
2346   for (blk = 0; blk < ncounts; blk++)
2347     {
2348       for (p = bb_func_head; p; p = p->next)
2349         {
2350           if (!strcmp (p->funcname, functions[blk])
2351               && (!p->filename || !strcmp (p->filename, blocks->filename)))
2352             {
2353               blocks->flags[blk] |= p->mode;
2354             }
2355         }
2356     }
2357
2358 }
2359
2360 /* Called when exiting from a function.  */
2361
2362 void
2363 __bb_trace_ret ()
2364 {
2365
2366   MACHINE_STATE_SAVE("2")
2367
2368   if (bb_callcount)
2369     {
2370       if ((bb_mode & 12) && bb_stacksize > bb_callcount)
2371         {
2372           bb_src = bb_stack[bb_callcount];
2373           if (bb_mode & 8)
2374             __bb_trace_func_ret ();
2375         }
2376
2377       bb_callcount -= 1;
2378     }
2379
2380   MACHINE_STATE_RESTORE("2")
2381
2382 }
2383
2384 /* Called when entering a function.  */
2385
2386 void
2387 __bb_init_trace_func (struct bb *blocks, unsigned long blockno)
2388 {
2389   static int trace_init = 0;
2390
2391   MACHINE_STATE_SAVE("3")
2392
2393   if (!blocks->zero_word)
2394     { 
2395       if (!trace_init)
2396         { 
2397           trace_init = 1;
2398           __bb_init_prg ();
2399         }
2400       __bb_init_file (blocks);
2401     }
2402
2403   if (bb_callcount)
2404     {
2405
2406       bb_callcount += 1;
2407
2408       if (bb_mode & 12)
2409         {
2410           if (bb_callcount >= bb_stacksize)
2411             {
2412               size_t newsize = bb_callcount + 100;
2413
2414               bb_stack = (unsigned long *) realloc (bb_stack, newsize);
2415               if (! bb_stack)
2416                 {
2417                   if (!reported)
2418                     {
2419                       fprintf (stderr, "Profiler: out of memory\n");
2420                       reported = 1;
2421                     }
2422                   bb_stacksize = 0;
2423                   goto stack_overflow;
2424                 }
2425               bb_stacksize = newsize;
2426             }
2427           bb_stack[bb_callcount] = bb_src;
2428
2429           if (bb_mode & 4)
2430             bb_src = 0;
2431
2432         }
2433
2434 stack_overflow:;
2435
2436     }
2437
2438   else if (blocks->flags && (blocks->flags[blockno] & TRACE_ON))
2439     {
2440       bb_callcount = 1;
2441       bb_src = 0;
2442
2443       if (bb_stack)
2444           bb_stack[bb_callcount] = bb_src;
2445     }
2446
2447   MACHINE_STATE_RESTORE("3")
2448 }
2449
2450 #endif /* not inhibit_libc */
2451 #endif /* not BLOCK_PROFILER_CODE */
2452 #endif /* L_bb */
2453 \f
2454 #ifdef L_shtab
2455 unsigned int __shtab[] = {
2456     0x00000001, 0x00000002, 0x00000004, 0x00000008,
2457     0x00000010, 0x00000020, 0x00000040, 0x00000080,
2458     0x00000100, 0x00000200, 0x00000400, 0x00000800,
2459     0x00001000, 0x00002000, 0x00004000, 0x00008000,
2460     0x00010000, 0x00020000, 0x00040000, 0x00080000,
2461     0x00100000, 0x00200000, 0x00400000, 0x00800000,
2462     0x01000000, 0x02000000, 0x04000000, 0x08000000,
2463     0x10000000, 0x20000000, 0x40000000, 0x80000000
2464   };
2465 #endif
2466 \f
2467 #ifdef L_clear_cache
2468 /* Clear part of an instruction cache.  */
2469
2470 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
2471
2472 void
2473 __clear_cache (char *beg, char *end)
2474 {
2475 #ifdef CLEAR_INSN_CACHE 
2476   CLEAR_INSN_CACHE (beg, end);
2477 #else
2478 #ifdef INSN_CACHE_SIZE
2479   static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
2480   static int initialized;
2481   int offset;
2482   void *start_addr
2483   void *end_addr;
2484   typedef (*function_ptr) ();
2485
2486 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
2487   /* It's cheaper to clear the whole cache.
2488      Put in a series of jump instructions so that calling the beginning
2489      of the cache will clear the whole thing.  */
2490
2491   if (! initialized)
2492     {
2493       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2494                  & -INSN_CACHE_LINE_WIDTH);
2495       int end_ptr = ptr + INSN_CACHE_SIZE;
2496
2497       while (ptr < end_ptr)
2498         {
2499           *(INSTRUCTION_TYPE *)ptr
2500             = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
2501           ptr += INSN_CACHE_LINE_WIDTH;
2502         }
2503       *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
2504
2505       initialized = 1;
2506     }
2507
2508   /* Call the beginning of the sequence.  */
2509   (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2510                     & -INSN_CACHE_LINE_WIDTH))
2511    ());
2512
2513 #else /* Cache is large.  */
2514
2515   if (! initialized)
2516     {
2517       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2518                  & -INSN_CACHE_LINE_WIDTH);
2519
2520       while (ptr < (int) array + sizeof array)
2521         {
2522           *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
2523           ptr += INSN_CACHE_LINE_WIDTH;
2524         }
2525
2526       initialized = 1;
2527     }
2528
2529   /* Find the location in array that occupies the same cache line as BEG.  */
2530
2531   offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
2532   start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
2533                  & -INSN_CACHE_PLANE_SIZE)
2534                 + offset);
2535
2536   /* Compute the cache alignment of the place to stop clearing.  */
2537 #if 0  /* This is not needed for gcc's purposes.  */
2538   /* If the block to clear is bigger than a cache plane,
2539      we clear the entire cache, and OFFSET is already correct.  */ 
2540   if (end < beg + INSN_CACHE_PLANE_SIZE)
2541 #endif
2542     offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
2543                & -INSN_CACHE_LINE_WIDTH)
2544               & (INSN_CACHE_PLANE_SIZE - 1));
2545
2546 #if INSN_CACHE_DEPTH > 1
2547   end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
2548   if (end_addr <= start_addr)
2549     end_addr += INSN_CACHE_PLANE_SIZE;
2550
2551   for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
2552     {
2553       int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
2554       int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
2555
2556       while (addr != stop)
2557         {
2558           /* Call the return instruction at ADDR.  */
2559           ((function_ptr) addr) ();
2560
2561           addr += INSN_CACHE_LINE_WIDTH;
2562         }
2563     }
2564 #else /* just one plane */
2565   do
2566     {
2567       /* Call the return instruction at START_ADDR.  */
2568       ((function_ptr) start_addr) ();
2569
2570       start_addr += INSN_CACHE_LINE_WIDTH;
2571     }
2572   while ((start_addr % INSN_CACHE_SIZE) != offset);
2573 #endif /* just one plane */
2574 #endif /* Cache is large */
2575 #endif /* Cache exists */
2576 #endif /* CLEAR_INSN_CACHE */
2577 }
2578
2579 #endif /* L_clear_cache */
2580 \f
2581 #ifdef L_trampoline
2582
2583 /* Jump to a trampoline, loading the static chain address.  */
2584
2585 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
2586
2587 long getpagesize()
2588 {
2589 #ifdef _ALPHA_
2590   return 8192;
2591 #else
2592   return 4096;
2593 #endif
2594 }
2595
2596 #ifdef i386
2597 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
2598 #endif
2599
2600 int
2601 mprotect (char *addr, int len, int prot)
2602 {
2603   int np, op;
2604
2605   if (prot == 7)
2606     np = 0x40;
2607   else if (prot == 5)
2608     np = 0x20;
2609   else if (prot == 4)
2610     np = 0x10;
2611   else if (prot == 3)
2612     np = 0x04;
2613   else if (prot == 1)
2614     np = 0x02;
2615   else if (prot == 0)
2616     np = 0x01;
2617
2618   if (VirtualProtect (addr, len, np, &op))
2619     return 0;
2620   else
2621     return -1;
2622 }
2623
2624 #endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
2625
2626 #ifdef TRANSFER_FROM_TRAMPOLINE 
2627 TRANSFER_FROM_TRAMPOLINE 
2628 #endif
2629
2630 #if defined (NeXT) && defined (__MACH__)
2631
2632 /* Make stack executable so we can call trampolines on stack.
2633    This is called from INITIALIZE_TRAMPOLINE in next.h.  */
2634 #ifdef NeXTStep21
2635  #include <mach.h>
2636 #else
2637  #include <mach/mach.h>
2638 #endif
2639
2640 void
2641 __enable_execute_stack (char *addr)
2642 {
2643   kern_return_t r;
2644   char *eaddr = addr + TRAMPOLINE_SIZE;
2645   vm_address_t a = (vm_address_t) addr;
2646
2647   /* turn on execute access on stack */
2648   r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
2649   if (r != KERN_SUCCESS)
2650     {
2651       mach_error("vm_protect VM_PROT_ALL", r);
2652       exit(1);
2653     }
2654
2655   /* We inline the i-cache invalidation for speed */
2656
2657 #ifdef CLEAR_INSN_CACHE
2658   CLEAR_INSN_CACHE (addr, eaddr);
2659 #else
2660   __clear_cache ((int) addr, (int) eaddr);
2661 #endif
2662
2663
2664 #endif /* defined (NeXT) && defined (__MACH__) */
2665
2666 #ifdef __convex__
2667
2668 /* Make stack executable so we can call trampolines on stack.
2669    This is called from INITIALIZE_TRAMPOLINE in convex.h.  */
2670
2671 #include <sys/mman.h>
2672 #include <sys/vmparam.h>
2673 #include <machine/machparam.h>
2674
2675 void
2676 __enable_execute_stack ()
2677 {
2678   int fp;
2679   static unsigned lowest = USRSTACK;
2680   unsigned current = (unsigned) &fp & -NBPG;
2681
2682   if (lowest > current)
2683     {
2684       unsigned len = lowest - current;
2685       mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
2686       lowest = current;
2687     }
2688
2689   /* Clear instruction cache in case an old trampoline is in it.  */
2690   asm ("pich");
2691 }
2692 #endif /* __convex__ */
2693
2694 #ifdef __sysV88__
2695
2696 /* Modified from the convex -code above.  */
2697
2698 #include <sys/param.h>
2699 #include <errno.h>
2700 #include <sys/m88kbcs.h>
2701
2702 void
2703 __enable_execute_stack ()
2704 {
2705   int save_errno;
2706   static unsigned long lowest = USRSTACK;
2707   unsigned long current = (unsigned long) &save_errno & -NBPC;
2708   
2709   /* Ignore errno being set. memctl sets errno to EINVAL whenever the
2710      address is seen as 'negative'. That is the case with the stack.   */
2711
2712   save_errno=errno;
2713   if (lowest > current)
2714     {
2715       unsigned len=lowest-current;
2716       memctl(current,len,MCT_TEXT);
2717       lowest = current;
2718     }
2719   else
2720     memctl(current,NBPC,MCT_TEXT);
2721   errno=save_errno;
2722 }
2723
2724 #endif /* __sysV88__ */
2725
2726 #ifdef __sysV68__
2727
2728 #include <sys/signal.h>
2729 #include <errno.h>
2730
2731 /* Motorola forgot to put memctl.o in the libp version of libc881.a,
2732    so define it here, because we need it in __clear_insn_cache below */
2733 /* On older versions of this OS, no memctl or MCT_TEXT are defined;
2734    hence we enable this stuff only if MCT_TEXT is #define'd.  */
2735
2736 #ifdef MCT_TEXT
2737 asm("\n\
2738         global memctl\n\
2739 memctl:\n\
2740         movq &75,%d0\n\
2741         trap &0\n\
2742         bcc.b noerror\n\
2743         jmp cerror%\n\
2744 noerror:\n\
2745         movq &0,%d0\n\
2746         rts");
2747 #endif
2748
2749 /* Clear instruction cache so we can call trampolines on stack.
2750    This is called from FINALIZE_TRAMPOLINE in mot3300.h.  */
2751
2752 void
2753 __clear_insn_cache ()
2754 {
2755 #ifdef MCT_TEXT
2756   int save_errno;
2757
2758   /* Preserve errno, because users would be surprised to have
2759   errno changing without explicitly calling any system-call. */
2760   save_errno = errno;
2761
2762   /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache. 
2763      No need to use an address derived from _start or %sp, as 0 works also. */
2764   memctl(0, 4096, MCT_TEXT);
2765   errno = save_errno;
2766 #endif
2767 }
2768
2769 #endif /* __sysV68__ */
2770
2771 #ifdef __pyr__
2772
2773 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
2774 #include <stdio.h>
2775 #include <sys/mman.h>
2776 #include <sys/types.h>
2777 #include <sys/param.h>
2778 #include <sys/vmmac.h>
2779
2780 /* Modified from the convex -code above.
2781    mremap promises to clear the i-cache.  */
2782
2783 void
2784 __enable_execute_stack ()
2785 {
2786   int fp;
2787   if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
2788                 PROT_READ|PROT_WRITE|PROT_EXEC))
2789     {
2790       perror ("mprotect in __enable_execute_stack");
2791       fflush (stderr);
2792       abort ();
2793     }
2794 }
2795 #endif /* __pyr__ */
2796
2797 #if defined (sony_news) && defined (SYSTYPE_BSD)
2798
2799 #include <stdio.h>
2800 #include <sys/types.h>
2801 #include <sys/param.h>
2802 #include <syscall.h>
2803 #include <machine/sysnews.h>
2804
2805 /* cacheflush function for NEWS-OS 4.2.
2806    This function is called from trampoline-initialize code
2807    defined in config/mips/mips.h.  */
2808
2809 void
2810 cacheflush (char *beg, int size, int flag)
2811 {
2812   if (syscall (SYS_sysnews, NEWS_CACHEFLUSH, beg, size, FLUSH_BCACHE))
2813     {
2814       perror ("cache_flush");
2815       fflush (stderr);
2816       abort ();
2817     }
2818 }
2819
2820 #endif /* sony_news */
2821 #endif /* L_trampoline */
2822 \f
2823 #ifndef __CYGWIN__
2824 #ifdef L__main
2825
2826 #include "gbl-ctors.h"
2827 /* Some systems use __main in a way incompatible with its use in gcc, in these
2828    cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2829    give the same symbol without quotes for an alternative entry point.  You
2830    must define both, or neither.  */
2831 #ifndef NAME__MAIN
2832 #define NAME__MAIN "__main"
2833 #define SYMBOL__MAIN __main
2834 #endif
2835
2836 #ifdef INIT_SECTION_ASM_OP
2837 #undef HAS_INIT_SECTION
2838 #define HAS_INIT_SECTION
2839 #endif
2840
2841 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
2842
2843 /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
2844    code to run constructors.  In that case, we need to handle EH here, too.  */
2845
2846 #ifdef EH_FRAME_SECTION
2847 #include "frame.h"
2848 extern unsigned char __EH_FRAME_BEGIN__[];
2849 #endif
2850
2851 /* Run all the global destructors on exit from the program.  */
2852
2853 void
2854 __do_global_dtors ()
2855 {
2856 #ifdef DO_GLOBAL_DTORS_BODY
2857   DO_GLOBAL_DTORS_BODY;
2858 #else
2859   static func_ptr *p = __DTOR_LIST__ + 1;
2860   while (*p)
2861     {
2862       p++;
2863       (*(p-1)) ();
2864     }
2865 #endif
2866 #ifdef EH_FRAME_SECTION
2867   __deregister_frame_info (__EH_FRAME_BEGIN__);
2868 #endif
2869 }
2870 #endif
2871
2872 #ifndef HAS_INIT_SECTION
2873 /* Run all the global constructors on entry to the program.  */
2874
2875 void
2876 __do_global_ctors ()
2877 {
2878 #ifdef EH_FRAME_SECTION
2879   {
2880     static struct object object;
2881     __register_frame_info (__EH_FRAME_BEGIN__, &object);
2882   }
2883 #endif
2884   DO_GLOBAL_CTORS_BODY;
2885   atexit (__do_global_dtors);
2886 }
2887 #endif /* no HAS_INIT_SECTION */
2888
2889 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
2890 /* Subroutine called automatically by `main'.
2891    Compiling a global function named `main'
2892    produces an automatic call to this function at the beginning.
2893
2894    For many systems, this routine calls __do_global_ctors.
2895    For systems which support a .init section we use the .init section
2896    to run __do_global_ctors, so we need not do anything here.  */
2897
2898 void
2899 SYMBOL__MAIN ()
2900 {
2901   /* Support recursive calls to `main': run initializers just once.  */
2902   static int initialized;
2903   if (! initialized)
2904     {
2905       initialized = 1;
2906       __do_global_ctors ();
2907     }
2908 }
2909 #endif /* no HAS_INIT_SECTION or INVOKE__main */
2910
2911 #endif /* L__main */
2912 #endif /* __CYGWIN__ */
2913 \f
2914 #ifdef L_ctors
2915
2916 #include "gbl-ctors.h"
2917
2918 /* Provide default definitions for the lists of constructors and
2919    destructors, so that we don't get linker errors.  These symbols are
2920    intentionally bss symbols, so that gld and/or collect will provide
2921    the right values.  */
2922
2923 /* We declare the lists here with two elements each,
2924    so that they are valid empty lists if no other definition is loaded.
2925
2926    If we are using the old "set" extensions to have the gnu linker
2927    collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
2928    must be in the bss/common section.
2929
2930    Long term no port should use those extensions.  But many still do.  */
2931 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
2932 #if defined (ASM_OUTPUT_CONSTRUCTOR) || defined (USE_COLLECT2)
2933 func_ptr __CTOR_LIST__[2] = {0, 0};
2934 func_ptr __DTOR_LIST__[2] = {0, 0};
2935 #else
2936 func_ptr __CTOR_LIST__[2];
2937 func_ptr __DTOR_LIST__[2];
2938 #endif
2939 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
2940 #endif /* L_ctors */
2941 \f
2942 #ifdef L_exit
2943
2944 #include "gbl-ctors.h"
2945
2946 #ifdef NEED_ATEXIT
2947
2948 #ifndef ON_EXIT
2949
2950 # include <errno.h>
2951
2952 static func_ptr *atexit_chain = 0;
2953 static long atexit_chain_length = 0;
2954 static volatile long last_atexit_chain_slot = -1;
2955
2956 int
2957 atexit (func_ptr func)
2958 {
2959   if (++last_atexit_chain_slot == atexit_chain_length)
2960     {
2961       atexit_chain_length += 32;
2962       if (atexit_chain)
2963         atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
2964                                              * sizeof (func_ptr));
2965       else
2966         atexit_chain = (func_ptr *) malloc (atexit_chain_length
2967                                             * sizeof (func_ptr));
2968       if (! atexit_chain)
2969         {
2970           atexit_chain_length = 0;
2971           last_atexit_chain_slot = -1;
2972           errno = ENOMEM;
2973           return (-1);
2974         }
2975     }
2976   atexit_chain[last_atexit_chain_slot] = func;
2977   return (0);
2978 }
2979
2980 extern void _cleanup ();
2981 extern void _exit () __attribute__ ((noreturn));
2982
2983 void 
2984 exit (int status)
2985 {
2986   if (atexit_chain)
2987     {
2988       for ( ; last_atexit_chain_slot-- >= 0; )
2989         {
2990           (*atexit_chain[last_atexit_chain_slot + 1]) ();
2991           atexit_chain[last_atexit_chain_slot + 1] = 0;
2992         }
2993       free (atexit_chain);
2994       atexit_chain = 0;
2995     }
2996 #ifdef EXIT_BODY
2997   EXIT_BODY;
2998 #else
2999   _cleanup ();
3000 #endif
3001   _exit (status);
3002 }
3003
3004 #else /* ON_EXIT */
3005
3006 /* Simple; we just need a wrapper for ON_EXIT.  */
3007 int
3008 atexit (func_ptr func)
3009 {
3010   return ON_EXIT (func);
3011 }
3012
3013 #endif /* ON_EXIT */
3014 #endif /* NEED_ATEXIT */
3015
3016 #endif /* L_exit */
3017 \f
3018 #ifdef L_eh
3019
3020 #include "gthr.h"
3021
3022 /* Shared exception handling support routines.  */
3023
3024 extern void __default_terminate (void) __attribute__ ((__noreturn__));
3025
3026 void
3027 __default_terminate ()
3028 {
3029   abort ();
3030 }
3031
3032 void (*__terminate_func)() = __default_terminate;
3033
3034 void
3035 __terminate ()
3036 {
3037   (*__terminate_func)();
3038 }
3039
3040 void *
3041 __throw_type_match (void *catch_type, void *throw_type, void *obj)
3042 {
3043 #if 0
3044  printf ("__throw_type_match (): catch_type = %s, throw_type = %s\n",
3045          catch_type, throw_type);
3046 #endif
3047  if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)
3048    return obj;
3049  return 0;
3050 }
3051
3052 void
3053 __empty ()
3054 {
3055 }
3056 \f
3057
3058 /* Include definitions of EH context and table layout */
3059
3060 #include "eh-common.h"
3061 #ifndef inhibit_libc
3062 #include <stdio.h>
3063 #endif
3064
3065 /* Allocate and return a new EH context structure. */
3066
3067 extern void __throw ();
3068
3069 static void *
3070 new_eh_context ()
3071 {
3072   struct eh_full_context {
3073     struct eh_context c;
3074     void *top_elt[2];
3075   } *ehfc = (struct eh_full_context *) malloc (sizeof *ehfc);
3076
3077   if (! ehfc)
3078     __terminate ();
3079
3080   memset (ehfc, 0, sizeof *ehfc);
3081
3082   ehfc->c.dynamic_handler_chain = (void **) ehfc->top_elt;
3083
3084   /* This should optimize out entirely.  This should always be true,
3085      but just in case it ever isn't, don't allow bogus code to be
3086      generated.  */
3087
3088   if ((void*)(&ehfc->c) != (void*)ehfc)
3089     __terminate ();
3090
3091   return &ehfc->c;
3092 }
3093
3094 #if __GTHREADS
3095 static __gthread_key_t eh_context_key;
3096
3097 /* Destructor for struct eh_context. */
3098 static void
3099 eh_context_free (void *ptr)
3100 {
3101   __gthread_key_dtor (eh_context_key, ptr);
3102   if (ptr)
3103     free (ptr);
3104 }
3105 #endif
3106
3107 /* Pointer to function to return EH context. */
3108
3109 static struct eh_context *eh_context_initialize ();
3110 static struct eh_context *eh_context_static ();
3111 #if __GTHREADS
3112 static struct eh_context *eh_context_specific ();
3113 #endif
3114
3115 static struct eh_context *(*get_eh_context) () = &eh_context_initialize;
3116
3117 /* Routine to get EH context.
3118    This one will simply call the function pointer. */
3119
3120 void *
3121 __get_eh_context ()
3122 {
3123   return (void *) (*get_eh_context) ();
3124 }
3125
3126 /* Get and set the language specific info pointer. */
3127
3128 void **
3129 __get_eh_info ()
3130 {
3131   struct eh_context *eh = (*get_eh_context) ();
3132   return &eh->info;
3133 }
3134 \f
3135 #ifdef DWARF2_UNWIND_INFO
3136 static int dwarf_reg_size_table_initialized = 0;
3137 static char dwarf_reg_size_table[FIRST_PSEUDO_REGISTER];
3138
3139 static void
3140 init_reg_size_table ()
3141 {
3142   __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
3143   dwarf_reg_size_table_initialized = 1;
3144 }
3145 #endif
3146
3147 #if __GTHREADS
3148 static void
3149 eh_threads_initialize ()
3150 {
3151   /* Try to create the key.  If it fails, revert to static method,
3152      otherwise start using thread specific EH contexts. */
3153   if (__gthread_key_create (&eh_context_key, &eh_context_free) == 0)
3154     get_eh_context = &eh_context_specific;
3155   else
3156     get_eh_context = &eh_context_static;
3157 }
3158 #endif /* no __GTHREADS */
3159
3160 /* Initialize EH context.
3161    This will be called only once, since we change GET_EH_CONTEXT
3162    pointer to another routine. */
3163
3164 static struct eh_context *
3165 eh_context_initialize ()
3166 {
3167 #if __GTHREADS
3168
3169   static __gthread_once_t once = __GTHREAD_ONCE_INIT;
3170   /* Make sure that get_eh_context does not point to us anymore.
3171      Some systems have dummy thread routines in their libc that
3172      return a success (Solaris 2.6 for example). */
3173   if (__gthread_once (&once, eh_threads_initialize) != 0
3174       || get_eh_context == &eh_context_initialize)
3175     {
3176       /* Use static version of EH context. */
3177       get_eh_context = &eh_context_static;
3178     }
3179 #ifdef DWARF2_UNWIND_INFO
3180   {
3181     static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
3182     if (__gthread_once (&once_regsizes, init_reg_size_table) != 0
3183         || ! dwarf_reg_size_table_initialized)
3184       init_reg_size_table ();
3185   }
3186 #endif
3187
3188 #else /* no __GTHREADS */
3189
3190   /* Use static version of EH context. */
3191   get_eh_context = &eh_context_static;
3192
3193 #ifdef DWARF2_UNWIND_INFO
3194   init_reg_size_table ();
3195 #endif
3196
3197 #endif /* no __GTHREADS */
3198
3199   return (*get_eh_context) ();
3200 }
3201
3202 /* Return a static EH context. */
3203
3204 static struct eh_context *
3205 eh_context_static ()
3206 {
3207   static struct eh_context eh;
3208   static int initialized;
3209   static void *top_elt[2];
3210
3211   if (! initialized)
3212     {
3213       initialized = 1;
3214       memset (&eh, 0, sizeof eh);
3215       eh.dynamic_handler_chain = top_elt;
3216     }
3217   return &eh;
3218 }
3219
3220 #if __GTHREADS
3221 /* Return a thread specific EH context. */
3222
3223 static struct eh_context *
3224 eh_context_specific ()
3225 {
3226   struct eh_context *eh;
3227   eh = (struct eh_context *) __gthread_getspecific (eh_context_key);
3228   if (! eh)
3229     {
3230       eh = new_eh_context ();
3231       if (__gthread_setspecific (eh_context_key, (void *) eh) != 0)
3232         __terminate ();
3233     }
3234
3235   return eh;
3236 }
3237 #endif __GTHREADS
3238 \f
3239 /* Support routines for setjmp/longjmp exception handling.  */
3240
3241 /* Calls to __sjthrow are generated by the compiler when an exception
3242    is raised when using the setjmp/longjmp exception handling codegen
3243    method.  */
3244
3245 #ifdef DONT_USE_BUILTIN_SETJMP
3246 extern void longjmp (void *, int);
3247 #endif
3248
3249 /* Routine to get the head of the current thread's dynamic handler chain
3250    use for exception handling. */
3251
3252 void ***
3253 __get_dynamic_handler_chain ()
3254 {
3255   struct eh_context *eh = (*get_eh_context) ();
3256   return &eh->dynamic_handler_chain;
3257 }
3258
3259 /* This is used to throw an exception when the setjmp/longjmp codegen
3260    method is used for exception handling.
3261
3262    We call __terminate if there are no handlers left.  Otherwise we run the
3263    cleanup actions off the dynamic cleanup stack, and pop the top of the
3264    dynamic handler chain, and use longjmp to transfer back to the associated
3265    handler.  */
3266
3267 extern void __sjthrow (void) __attribute__ ((__noreturn__));
3268
3269 void
3270 __sjthrow ()
3271 {
3272   struct eh_context *eh = (*get_eh_context) ();
3273   void ***dhc = &eh->dynamic_handler_chain;
3274   void *jmpbuf;
3275   void (*func)(void *, int);
3276   void *arg;
3277   void ***cleanup;
3278
3279   /* The cleanup chain is one word into the buffer.  Get the cleanup
3280      chain.  */
3281   cleanup = (void***)&(*dhc)[1];
3282
3283   /* If there are any cleanups in the chain, run them now.  */
3284   if (cleanup[0])
3285     {
3286       double store[200];
3287       void **buf = (void**)store;
3288       buf[1] = 0;
3289       buf[0] = (*dhc);
3290
3291       /* try { */
3292 #ifdef DONT_USE_BUILTIN_SETJMP
3293       if (! setjmp (&buf[2]))
3294 #else
3295       if (! __builtin_setjmp (&buf[2]))
3296 #endif
3297         {
3298           *dhc = buf;
3299           while (cleanup[0])
3300             {
3301               func = (void(*)(void*, int))cleanup[0][1];
3302               arg = (void*)cleanup[0][2];
3303
3304               /* Update this before running the cleanup.  */
3305               cleanup[0] = (void **)cleanup[0][0];
3306
3307               (*func)(arg, 2);
3308             }
3309           *dhc = buf[0];
3310         }
3311       /* catch (...) */
3312       else
3313         {
3314           __terminate ();
3315         }
3316     }
3317   
3318   /* We must call terminate if we try and rethrow an exception, when
3319      there is no exception currently active and when there are no
3320      handlers left.  */
3321   if (! eh->info || (*dhc)[0] == 0)
3322     __terminate ();
3323     
3324   /* Find the jmpbuf associated with the top element of the dynamic
3325      handler chain.  The jumpbuf starts two words into the buffer.  */
3326   jmpbuf = &(*dhc)[2];
3327
3328   /* Then we pop the top element off the dynamic handler chain.  */
3329   *dhc = (void**)(*dhc)[0];
3330
3331   /* And then we jump to the handler.  */
3332
3333 #ifdef DONT_USE_BUILTIN_SETJMP
3334   longjmp (jmpbuf, 1);
3335 #else
3336   __builtin_longjmp (jmpbuf, 1);
3337 #endif
3338 }
3339
3340 /* Run cleanups on the dynamic cleanup stack for the current dynamic
3341    handler, then pop the handler off the dynamic handler stack, and
3342    then throw.  This is used to skip the first handler, and transfer
3343    control to the next handler in the dynamic handler stack.  */
3344
3345 extern void __sjpopnthrow (void) __attribute__ ((__noreturn__));
3346
3347 void
3348 __sjpopnthrow ()
3349 {
3350   struct eh_context *eh = (*get_eh_context) ();
3351   void ***dhc = &eh->dynamic_handler_chain;
3352   void (*func)(void *, int);
3353   void *arg;
3354   void ***cleanup;
3355
3356   /* The cleanup chain is one word into the buffer.  Get the cleanup
3357      chain.  */
3358   cleanup = (void***)&(*dhc)[1];
3359
3360   /* If there are any cleanups in the chain, run them now.  */
3361   if (cleanup[0])
3362     {
3363       double store[200];
3364       void **buf = (void**)store;
3365       buf[1] = 0;
3366       buf[0] = (*dhc);
3367
3368       /* try { */
3369 #ifdef DONT_USE_BUILTIN_SETJMP
3370       if (! setjmp (&buf[2]))
3371 #else
3372       if (! __builtin_setjmp (&buf[2]))
3373 #endif
3374         {
3375           *dhc = buf;
3376           while (cleanup[0])
3377             {
3378               func = (void(*)(void*, int))cleanup[0][1];
3379               arg = (void*)cleanup[0][2];
3380
3381               /* Update this before running the cleanup.  */
3382               cleanup[0] = (void **)cleanup[0][0];
3383
3384               (*func)(arg, 2);
3385             }
3386           *dhc = buf[0];
3387         }
3388       /* catch (...) */
3389       else
3390         {
3391           __terminate ();
3392         }
3393     }
3394
3395   /* Then we pop the top element off the dynamic handler chain.  */
3396   *dhc = (void**)(*dhc)[0];
3397
3398   __sjthrow ();
3399 }
3400 \f
3401 /* Support code for all exception region-based exception handling.  */
3402
3403 int
3404 __eh_rtime_match (void *rtime)
3405 {
3406   void *info;
3407   __eh_matcher matcher;
3408   void *ret;
3409
3410   info = *(__get_eh_info ());
3411   matcher = ((__eh_info *)info)->match_function;
3412   if (! matcher)
3413     {
3414 #ifndef inhibit_libc
3415       fprintf (stderr, "Internal Compiler Bug: No runtime type matcher.");
3416 #endif
3417       return 0;
3418     }
3419   ret = (*matcher) (info, rtime, (void *)0);
3420   return (ret != NULL);
3421 }
3422
3423 /* This value identifies the place from which an exception is being
3424    thrown.  */
3425
3426 #ifdef EH_TABLE_LOOKUP
3427
3428 EH_TABLE_LOOKUP
3429
3430 #else
3431
3432 #ifdef DWARF2_UNWIND_INFO
3433
3434 /* Return the table version of an exception descriptor */
3435
3436 short 
3437 __get_eh_table_version (exception_descriptor *table) 
3438 {
3439   return table->lang.version;
3440 }
3441
3442 /* Return the originating table language of an exception descriptor */
3443
3444 short 
3445 __get_eh_table_language (exception_descriptor *table)
3446 {
3447   return table->lang.language;
3448 }
3449
3450 /* This routine takes a PC and a pointer to the exception region TABLE for
3451    its translation unit, and returns the address of the exception handler
3452    associated with the closest exception table handler entry associated
3453    with that PC, or 0 if there are no table entries the PC fits in.
3454
3455    In the advent of a tie, we have to give the last entry, as it represents
3456    an inner block.  */
3457
3458 static void *
3459 old_find_exception_handler (void *pc, old_exception_table *table)
3460 {
3461   if (table)
3462     {
3463       int pos;
3464       int best = -1;
3465
3466       /* We can't do a binary search because the table isn't guaranteed
3467          to be sorted from function to function.  */
3468       for (pos = 0; table[pos].start_region != (void *) -1; ++pos)
3469         {
3470           if (table[pos].start_region <= pc && table[pos].end_region > pc)
3471             {
3472               /* This can apply.  Make sure it is at least as small as
3473                  the previous best.  */
3474               if (best == -1 || (table[pos].end_region <= table[best].end_region
3475                         && table[pos].start_region >= table[best].start_region))
3476                 best = pos;
3477             }
3478           /* But it is sorted by starting PC within a function.  */
3479           else if (best >= 0 && table[pos].start_region > pc)
3480             break;
3481         }
3482       if (best != -1)
3483         return table[best].exception_handler;
3484     }
3485
3486   return (void *) 0;
3487 }
3488
3489 /* find_exception_handler finds the correct handler, if there is one, to
3490    handle an exception.
3491    returns a pointer to the handler which controlled should be transferred
3492    to, or NULL if there is nothing left.
3493    Parameters:
3494    PC - pc where the exception originates. If this is a rethrow, 
3495         then this starts out as a pointer to the exception table
3496         entry we wish to rethrow out of.
3497    TABLE - exception table for the current module.
3498    EH_INFO - eh info pointer for this exception.
3499    RETHROW - 1 if this is a rethrow. (see incoming value of PC).
3500    CLEANUP - returned flag indicating whether this is a cleanup handler.
3501 */
3502 static void *
3503 find_exception_handler (void *pc, exception_descriptor *table, 
3504                         __eh_info *eh_info, int rethrow, int *cleanup)
3505 {
3506
3507   void *retval = NULL;
3508   *cleanup = 1;
3509   if (table)
3510     {
3511       int pos = 0;
3512       /* The new model assumed the table is sorted inner-most out so the
3513          first region we find which matches is the correct one */
3514
3515       exception_table *tab = &(table->table[0]);
3516
3517       /* Subtract 1 from the PC to avoid hitting the next region */
3518       if (rethrow) 
3519         {
3520           /* pc is actually the region table entry to rethrow out of */
3521           pos = ((exception_table *) pc) - tab;
3522           pc = ((exception_table *) pc)->end_region - 1;
3523
3524           /* The label is always on the LAST handler entry for a region, 
3525              so we know the next entry is a different region, even if the
3526              addresses are the same. Make sure its not end of table tho. */
3527           if (tab[pos].start_region != (void *) -1)
3528             pos++;
3529         }
3530       else
3531         pc--;
3532       
3533       /* We can't do a binary search because the table is in inner-most
3534          to outermost address ranges within functions */
3535       for ( ; tab[pos].start_region != (void *) -1; pos++)
3536         { 
3537           if (tab[pos].start_region <= pc && tab[pos].end_region > pc)
3538             {
3539               if (tab[pos].match_info)
3540                 {
3541                   __eh_matcher matcher = eh_info->match_function;
3542                   /* match info but no matcher is NOT a match */
3543                   if (matcher) 
3544                     {
3545                       void *ret = (*matcher)((void *) eh_info, 
3546                                              tab[pos].match_info, table);
3547                       if (ret) 
3548                         {
3549                           if (retval == NULL)
3550                             retval = tab[pos].exception_handler;
3551                           *cleanup = 0;
3552                           break;
3553                         }
3554                     }
3555                 }
3556               else
3557                 {
3558                   if (retval == NULL)
3559                     retval = tab[pos].exception_handler;
3560                 }
3561             }
3562         }
3563     }
3564   return retval;
3565 }
3566 #endif /* DWARF2_UNWIND_INFO */
3567 #endif /* EH_TABLE_LOOKUP */
3568 \f
3569 #ifdef DWARF2_UNWIND_INFO
3570 /* Support code for exception handling using static unwind information.  */
3571
3572 #include "frame.h"
3573
3574 /* This type is used in get_reg and put_reg to deal with ABIs where a void*
3575    is smaller than a word, such as the Irix 6 n32 ABI.  We cast twice to
3576    avoid a warning about casting between int and pointer of different
3577    sizes.  */
3578
3579 typedef int ptr_type __attribute__ ((mode (pointer)));
3580
3581 #ifdef INCOMING_REGNO
3582 /* Is the saved value for register REG in frame UDATA stored in a register
3583    window in the previous frame?  */
3584
3585 /* ??? The Sparc INCOMING_REGNO references TARGET_FLAT.  This allows us
3586    to use the macro here.  One wonders, though, that perhaps TARGET_FLAT
3587    compiled functions won't work with the frame-unwind stuff here.  
3588    Perhaps the entireity of in_reg_window should be conditional on having
3589    seen a DW_CFA_GNU_window_save?  */
3590 #define target_flags 0
3591
3592 static int
3593 in_reg_window (int reg, frame_state *udata)
3594 {
3595   if (udata->saved[reg] == REG_SAVED_REG)
3596     return INCOMING_REGNO (reg) == reg;
3597   if (udata->saved[reg] != REG_SAVED_OFFSET)
3598     return 0;
3599
3600 #ifdef STACK_GROWS_DOWNWARD
3601   return udata->reg_or_offset[reg] > 0;
3602 #else
3603   return udata->reg_or_offset[reg] < 0;
3604 #endif
3605 }
3606 #else
3607 static inline int in_reg_window (int reg, frame_state *udata) { return 0; }
3608 #endif /* INCOMING_REGNO */
3609
3610 /* Get the address of register REG as saved in UDATA, where SUB_UDATA is a
3611    frame called by UDATA or 0.  */
3612
3613 static word_type *
3614 get_reg_addr (unsigned reg, frame_state *udata, frame_state *sub_udata)
3615 {
3616   while (udata->saved[reg] == REG_SAVED_REG)
3617     {
3618       reg = udata->reg_or_offset[reg];
3619       if (in_reg_window (reg, udata))
3620         {
3621           udata = sub_udata;
3622           sub_udata = NULL;
3623         }
3624     }
3625   if (udata->saved[reg] == REG_SAVED_OFFSET)
3626     return (word_type *)(udata->cfa + udata->reg_or_offset[reg]);
3627   else
3628     abort ();
3629 }
3630
3631 /* Get the value of register REG as saved in UDATA, where SUB_UDATA is a
3632    frame called by UDATA or 0.  */
3633
3634 static inline void *
3635 get_reg (unsigned reg, frame_state *udata, frame_state *sub_udata)
3636 {
3637   return (void *)(ptr_type) *get_reg_addr (reg, udata, sub_udata);
3638 }
3639
3640 /* Overwrite the saved value for register REG in frame UDATA with VAL.  */
3641
3642 static inline void
3643 put_reg (unsigned reg, void *val, frame_state *udata)
3644 {
3645   *get_reg_addr (reg, udata, NULL) = (word_type)(ptr_type) val;
3646 }
3647
3648 /* Copy the saved value for register REG from frame UDATA to frame
3649    TARGET_UDATA.  Unlike the previous two functions, this can handle
3650    registers that are not one word large.  */
3651
3652 static void
3653 copy_reg (unsigned reg, frame_state *udata, frame_state *target_udata)
3654 {
3655   word_type *preg = get_reg_addr (reg, udata, NULL);
3656   word_type *ptreg = get_reg_addr (reg, target_udata, NULL);
3657
3658   memcpy (ptreg, preg, dwarf_reg_size_table [reg]);
3659 }
3660
3661 /* Retrieve the return address for frame UDATA.  */
3662
3663 static inline void *
3664 get_return_addr (frame_state *udata, frame_state *sub_udata)
3665 {
3666   return __builtin_extract_return_addr
3667     (get_reg (udata->retaddr_column, udata, sub_udata));
3668 }
3669
3670 /* Overwrite the return address for frame UDATA with VAL.  */
3671
3672 static inline void
3673 put_return_addr (void *val, frame_state *udata)
3674 {
3675   val = __builtin_frob_return_addr (val);
3676   put_reg (udata->retaddr_column, val, udata);
3677 }
3678
3679 /* Given the current frame UDATA and its return address PC, return the
3680    information about the calling frame in CALLER_UDATA.  */
3681
3682 static void *
3683 next_stack_level (void *pc, frame_state *udata, frame_state *caller_udata)
3684 {
3685   caller_udata = __frame_state_for (pc, caller_udata);
3686   if (! caller_udata)
3687     return 0;
3688
3689   /* Now go back to our caller's stack frame.  If our caller's CFA register
3690      was saved in our stack frame, restore it; otherwise, assume the CFA
3691      register is SP and restore it to our CFA value.  */
3692   if (udata->saved[caller_udata->cfa_reg])
3693     caller_udata->cfa = get_reg (caller_udata->cfa_reg, udata, 0);
3694   else
3695     caller_udata->cfa = udata->cfa;
3696   caller_udata->cfa += caller_udata->cfa_offset;
3697
3698   return caller_udata;
3699 }
3700
3701 /* Hook to call before __terminate if only cleanup handlers remain. */
3702 void 
3703 __unwinding_cleanup ()
3704 {
3705 }
3706
3707 /* throw_helper performs some of the common grunt work for a throw. This
3708    routine is called by throw and rethrows. This is pretty much split 
3709    out from the old __throw routine. An addition has been added which allows
3710    for a dummy call to a routine __unwinding_cleanup() when there are nothing
3711    but cleanups remaining. This allows a debugger to examine the state
3712    at which the throw was executed, before any cleanups, rather than
3713    at the terminate point after the stack has been unwound.
3714
3715    EH is the current eh_context structure.
3716    PC is the address of the call to __throw.
3717    MY_UDATA is the unwind information for __throw.
3718    OFFSET_P is where we return the SP adjustment offset.  */
3719
3720 static void *
3721 throw_helper (eh, pc, my_udata, offset_p)
3722      struct eh_context *eh;
3723      void *pc;
3724      frame_state *my_udata;
3725      long *offset_p;
3726 {
3727   frame_state ustruct2, *udata = &ustruct2;
3728   frame_state ustruct;
3729   frame_state *sub_udata = &ustruct;
3730   void *saved_pc = pc;
3731   void *handler;
3732   void *handler_p;
3733   void *pc_p;
3734   frame_state saved_ustruct;
3735   int new_eh_model;
3736   int cleanup = 0;
3737   int only_cleanup = 0;
3738   int rethrow = 0;
3739   int saved_state = 0;
3740   long args_size;
3741   __eh_info *eh_info = (__eh_info *)eh->info;
3742
3743   /* Do we find a handler based on a re-throw PC? */
3744   if (eh->table_index != (void *) 0)
3745     rethrow = 1;
3746
3747   memcpy (udata, my_udata, sizeof (*udata));
3748
3749   handler = (void *) 0;
3750   for (;;)
3751     { 
3752       frame_state *p = udata;
3753       udata = next_stack_level (pc, udata, sub_udata);
3754       sub_udata = p;
3755
3756       /* If we couldn't find the next frame, we lose.  */
3757       if (! udata)
3758         break;
3759
3760       if (udata->eh_ptr == NULL)
3761         new_eh_model = 0;
3762       else
3763         new_eh_model = (((exception_descriptor *)(udata->eh_ptr))->
3764                                           runtime_id_field == NEW_EH_RUNTIME);
3765
3766       if (rethrow) 
3767         {
3768           rethrow = 0;
3769           handler = find_exception_handler (eh->table_index, udata->eh_ptr, 
3770                                           eh_info, 1, &cleanup);
3771           eh->table_index = (void *)0;
3772         }
3773       else
3774         if (new_eh_model)
3775           handler = find_exception_handler (pc, udata->eh_ptr, eh_info, 
3776                                             0, &cleanup);
3777         else
3778           handler = old_find_exception_handler (pc, udata->eh_ptr);
3779
3780       /* If we found one, we can stop searching, if its not a cleanup. 
3781          for cleanups, we save the state, and keep looking. This allows
3782          us to call a debug hook if there are nothing but cleanups left. */
3783       if (handler)
3784         {
3785           if (cleanup)
3786             {
3787               if (!saved_state)
3788                 {
3789                   saved_ustruct = *udata;
3790                   handler_p = handler;
3791                   pc_p = pc;
3792                   saved_state = 1;
3793                   only_cleanup = 1;
3794                 }
3795             }
3796           else
3797             {
3798               only_cleanup = 0;
3799               break;
3800             }
3801         }
3802
3803       /* Otherwise, we continue searching.  We subtract 1 from PC to avoid
3804          hitting the beginning of the next region.  */
3805       pc = get_return_addr (udata, sub_udata) - 1;
3806     }
3807
3808   if (saved_state) 
3809     {
3810       udata = &saved_ustruct;
3811       handler = handler_p;
3812       pc = pc_p;
3813       if (only_cleanup)
3814         __unwinding_cleanup ();
3815     }
3816
3817   /* If we haven't found a handler by now, this is an unhandled
3818      exception.  */
3819   if (! handler) 
3820     __terminate();
3821
3822   eh->handler_label = handler;
3823
3824   args_size = udata->args_size;
3825
3826   if (pc == saved_pc)
3827     /* We found a handler in the throw context, no need to unwind.  */
3828     udata = my_udata;
3829   else
3830     {
3831       int i;
3832
3833       /* Unwind all the frames between this one and the handler by copying
3834          their saved register values into our register save slots.  */
3835
3836       /* Remember the PC where we found the handler.  */
3837       void *handler_pc = pc;
3838
3839       /* Start from the throw context again.  */
3840       pc = saved_pc;
3841       memcpy (udata, my_udata, sizeof (*udata));
3842
3843       while (pc != handler_pc)
3844         {
3845           frame_state *p = udata;
3846           udata = next_stack_level (pc, udata, sub_udata);
3847           sub_udata = p;
3848
3849           for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
3850             if (i != udata->retaddr_column && udata->saved[i])
3851               {
3852                 /* If you modify the saved value of the return address
3853                    register on the SPARC, you modify the return address for
3854                    your caller's frame.  Don't do that here, as it will
3855                    confuse get_return_addr.  */
3856                 if (in_reg_window (i, udata)
3857                     && udata->saved[udata->retaddr_column] == REG_SAVED_REG
3858                     && udata->reg_or_offset[udata->retaddr_column] == i)
3859                   continue;
3860                 copy_reg (i, udata, my_udata);
3861               }
3862
3863           pc = get_return_addr (udata, sub_udata) - 1;
3864         }
3865
3866       /* But we do need to update the saved return address register from
3867          the last frame we unwind, or the handler frame will have the wrong
3868          return address.  */
3869       if (udata->saved[udata->retaddr_column] == REG_SAVED_REG)
3870         {
3871           i = udata->reg_or_offset[udata->retaddr_column];
3872           if (in_reg_window (i, udata))
3873             copy_reg (i, udata, my_udata);
3874         }
3875     }
3876   /* udata now refers to the frame called by the handler frame.  */
3877
3878   /* We adjust SP by the difference between __throw's CFA and the CFA for
3879      the frame called by the handler frame, because those CFAs correspond
3880      to the SP values at the two call sites.  We need to further adjust by
3881      the args_size of the handler frame itself to get the handler frame's
3882      SP from before the args were pushed for that call.  */
3883 #ifdef STACK_GROWS_DOWNWARD
3884   *offset_p = udata->cfa - my_udata->cfa + args_size;
3885 #else
3886   *offset_p = my_udata->cfa - udata->cfa - args_size;
3887 #endif
3888                        
3889   return handler;
3890 }
3891
3892
3893 /* We first search for an exception handler, and if we don't find
3894    it, we call __terminate on the current stack frame so that we may
3895    use the debugger to walk the stack and understand why no handler
3896    was found.
3897
3898    If we find one, then we unwind the frames down to the one that
3899    has the handler and transfer control into the handler.  */
3900
3901 /*extern void __throw(void) __attribute__ ((__noreturn__));*/
3902
3903 void
3904 __throw ()
3905 {
3906   struct eh_context *eh = (*get_eh_context) ();
3907   void *pc, *handler;
3908   long offset;
3909
3910   /* XXX maybe make my_ustruct static so we don't have to look it up for
3911      each throw.  */
3912   frame_state my_ustruct, *my_udata = &my_ustruct;
3913
3914   /* This is required for C++ semantics.  We must call terminate if we
3915      try and rethrow an exception, when there is no exception currently
3916      active.  */
3917   if (! eh->info)
3918     __terminate ();
3919     
3920   /* Start at our stack frame.  */
3921 label:
3922   my_udata = __frame_state_for (&&label, my_udata);
3923   if (! my_udata)
3924     __terminate ();
3925
3926   /* We need to get the value from the CFA register. */
3927   my_udata->cfa = __builtin_dwarf_cfa ();
3928
3929   /* Do any necessary initialization to access arbitrary stack frames.
3930      On the SPARC, this means flushing the register windows.  */
3931   __builtin_unwind_init ();
3932
3933   /* Now reset pc to the right throw point.  */
3934   pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
3935
3936   handler = throw_helper (eh, pc, my_udata, &offset);
3937
3938   /* Now go!  */
3939
3940   __builtin_eh_return ((void *)eh, offset, handler);
3941
3942   /* Epilogue:  restore the handler frame's register values and return
3943      to the stub.  */
3944 }
3945
3946 /*extern void __rethrow(void *) __attribute__ ((__noreturn__));*/
3947
3948 void
3949 __rethrow (index)
3950      void *index;
3951 {
3952   struct eh_context *eh = (*get_eh_context) ();
3953   void *pc, *handler;
3954   long offset;
3955
3956   /* XXX maybe make my_ustruct static so we don't have to look it up for
3957      each throw.  */
3958   frame_state my_ustruct, *my_udata = &my_ustruct;
3959
3960   /* This is required for C++ semantics.  We must call terminate if we
3961      try and rethrow an exception, when there is no exception currently
3962      active.  */
3963   if (! eh->info)
3964     __terminate ();
3965
3966   /* This is the table index we want to rethrow from. The value of
3967      the END_REGION label is used for the PC of the throw, and the
3968      search begins with the next table entry. */
3969   eh->table_index = index;
3970     
3971   /* Start at our stack frame.  */
3972 label:
3973   my_udata = __frame_state_for (&&label, my_udata);
3974   if (! my_udata)
3975     __terminate ();
3976
3977   /* We need to get the value from the CFA register. */
3978   my_udata->cfa = __builtin_dwarf_cfa ();
3979
3980   /* Do any necessary initialization to access arbitrary stack frames.
3981      On the SPARC, this means flushing the register windows.  */
3982   __builtin_unwind_init ();
3983
3984   /* Now reset pc to the right throw point.  */
3985   pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
3986
3987   handler = throw_helper (eh, pc, my_udata, &offset);
3988
3989   /* Now go!  */
3990
3991   __builtin_eh_return ((void *)eh, offset, handler);
3992
3993   /* Epilogue:  restore the handler frame's register values and return
3994      to the stub.  */
3995 }
3996 #endif /* DWARF2_UNWIND_INFO */
3997
3998 #endif /* L_eh */
3999 \f
4000 #ifdef L_pure
4001 #ifndef inhibit_libc
4002 /* This gets us __GNU_LIBRARY__.  */
4003 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
4004 #include <stdio.h>
4005
4006 #ifdef __GNU_LIBRARY__
4007   /* Avoid forcing the library's meaning of `write' on the user program
4008      by using the "internal" name (for use within the library)  */
4009 #define write(fd, buf, n)       __write((fd), (buf), (n))
4010 #endif
4011 #endif /* inhibit_libc */
4012
4013 #define MESSAGE "pure virtual method called\n"
4014
4015 extern void __terminate (void) __attribute__ ((__noreturn__));
4016
4017 void
4018 __pure_virtual ()
4019 {
4020 #ifndef inhibit_libc
4021   write (2, MESSAGE, sizeof (MESSAGE) - 1);
4022 #endif
4023   __terminate ();
4024 }
4025 #endif