OSDN Git Service

Mark args as unused.
[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 __attribute__((__unused__)),
2474                char *end __attribute__((__unused__)))
2475 {
2476 #ifdef CLEAR_INSN_CACHE 
2477   CLEAR_INSN_CACHE (beg, end);
2478 #else
2479 #ifdef INSN_CACHE_SIZE
2480   static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
2481   static int initialized;
2482   int offset;
2483   void *start_addr
2484   void *end_addr;
2485   typedef (*function_ptr) ();
2486
2487 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
2488   /* It's cheaper to clear the whole cache.
2489      Put in a series of jump instructions so that calling the beginning
2490      of the cache will clear the whole thing.  */
2491
2492   if (! initialized)
2493     {
2494       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2495                  & -INSN_CACHE_LINE_WIDTH);
2496       int end_ptr = ptr + INSN_CACHE_SIZE;
2497
2498       while (ptr < end_ptr)
2499         {
2500           *(INSTRUCTION_TYPE *)ptr
2501             = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
2502           ptr += INSN_CACHE_LINE_WIDTH;
2503         }
2504       *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
2505
2506       initialized = 1;
2507     }
2508
2509   /* Call the beginning of the sequence.  */
2510   (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2511                     & -INSN_CACHE_LINE_WIDTH))
2512    ());
2513
2514 #else /* Cache is large.  */
2515
2516   if (! initialized)
2517     {
2518       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2519                  & -INSN_CACHE_LINE_WIDTH);
2520
2521       while (ptr < (int) array + sizeof array)
2522         {
2523           *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
2524           ptr += INSN_CACHE_LINE_WIDTH;
2525         }
2526
2527       initialized = 1;
2528     }
2529
2530   /* Find the location in array that occupies the same cache line as BEG.  */
2531
2532   offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
2533   start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
2534                  & -INSN_CACHE_PLANE_SIZE)
2535                 + offset);
2536
2537   /* Compute the cache alignment of the place to stop clearing.  */
2538 #if 0  /* This is not needed for gcc's purposes.  */
2539   /* If the block to clear is bigger than a cache plane,
2540      we clear the entire cache, and OFFSET is already correct.  */ 
2541   if (end < beg + INSN_CACHE_PLANE_SIZE)
2542 #endif
2543     offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
2544                & -INSN_CACHE_LINE_WIDTH)
2545               & (INSN_CACHE_PLANE_SIZE - 1));
2546
2547 #if INSN_CACHE_DEPTH > 1
2548   end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
2549   if (end_addr <= start_addr)
2550     end_addr += INSN_CACHE_PLANE_SIZE;
2551
2552   for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
2553     {
2554       int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
2555       int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
2556
2557       while (addr != stop)
2558         {
2559           /* Call the return instruction at ADDR.  */
2560           ((function_ptr) addr) ();
2561
2562           addr += INSN_CACHE_LINE_WIDTH;
2563         }
2564     }
2565 #else /* just one plane */
2566   do
2567     {
2568       /* Call the return instruction at START_ADDR.  */
2569       ((function_ptr) start_addr) ();
2570
2571       start_addr += INSN_CACHE_LINE_WIDTH;
2572     }
2573   while ((start_addr % INSN_CACHE_SIZE) != offset);
2574 #endif /* just one plane */
2575 #endif /* Cache is large */
2576 #endif /* Cache exists */
2577 #endif /* CLEAR_INSN_CACHE */
2578 }
2579
2580 #endif /* L_clear_cache */
2581 \f
2582 #ifdef L_trampoline
2583
2584 /* Jump to a trampoline, loading the static chain address.  */
2585
2586 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
2587
2588 long getpagesize()
2589 {
2590 #ifdef _ALPHA_
2591   return 8192;
2592 #else
2593   return 4096;
2594 #endif
2595 }
2596
2597 #ifdef i386
2598 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
2599 #endif
2600
2601 int
2602 mprotect (char *addr, int len, int prot)
2603 {
2604   int np, op;
2605
2606   if (prot == 7)
2607     np = 0x40;
2608   else if (prot == 5)
2609     np = 0x20;
2610   else if (prot == 4)
2611     np = 0x10;
2612   else if (prot == 3)
2613     np = 0x04;
2614   else if (prot == 1)
2615     np = 0x02;
2616   else if (prot == 0)
2617     np = 0x01;
2618
2619   if (VirtualProtect (addr, len, np, &op))
2620     return 0;
2621   else
2622     return -1;
2623 }
2624
2625 #endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
2626
2627 #ifdef TRANSFER_FROM_TRAMPOLINE 
2628 TRANSFER_FROM_TRAMPOLINE 
2629 #endif
2630
2631 #if defined (NeXT) && defined (__MACH__)
2632
2633 /* Make stack executable so we can call trampolines on stack.
2634    This is called from INITIALIZE_TRAMPOLINE in next.h.  */
2635 #ifdef NeXTStep21
2636  #include <mach.h>
2637 #else
2638  #include <mach/mach.h>
2639 #endif
2640
2641 void
2642 __enable_execute_stack (char *addr)
2643 {
2644   kern_return_t r;
2645   char *eaddr = addr + TRAMPOLINE_SIZE;
2646   vm_address_t a = (vm_address_t) addr;
2647
2648   /* turn on execute access on stack */
2649   r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
2650   if (r != KERN_SUCCESS)
2651     {
2652       mach_error("vm_protect VM_PROT_ALL", r);
2653       exit(1);
2654     }
2655
2656   /* We inline the i-cache invalidation for speed */
2657
2658 #ifdef CLEAR_INSN_CACHE
2659   CLEAR_INSN_CACHE (addr, eaddr);
2660 #else
2661   __clear_cache ((int) addr, (int) eaddr);
2662 #endif
2663
2664
2665 #endif /* defined (NeXT) && defined (__MACH__) */
2666
2667 #ifdef __convex__
2668
2669 /* Make stack executable so we can call trampolines on stack.
2670    This is called from INITIALIZE_TRAMPOLINE in convex.h.  */
2671
2672 #include <sys/mman.h>
2673 #include <sys/vmparam.h>
2674 #include <machine/machparam.h>
2675
2676 void
2677 __enable_execute_stack ()
2678 {
2679   int fp;
2680   static unsigned lowest = USRSTACK;
2681   unsigned current = (unsigned) &fp & -NBPG;
2682
2683   if (lowest > current)
2684     {
2685       unsigned len = lowest - current;
2686       mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
2687       lowest = current;
2688     }
2689
2690   /* Clear instruction cache in case an old trampoline is in it.  */
2691   asm ("pich");
2692 }
2693 #endif /* __convex__ */
2694
2695 #ifdef __sysV88__
2696
2697 /* Modified from the convex -code above.  */
2698
2699 #include <sys/param.h>
2700 #include <errno.h>
2701 #include <sys/m88kbcs.h>
2702
2703 void
2704 __enable_execute_stack ()
2705 {
2706   int save_errno;
2707   static unsigned long lowest = USRSTACK;
2708   unsigned long current = (unsigned long) &save_errno & -NBPC;
2709   
2710   /* Ignore errno being set. memctl sets errno to EINVAL whenever the
2711      address is seen as 'negative'. That is the case with the stack.   */
2712
2713   save_errno=errno;
2714   if (lowest > current)
2715     {
2716       unsigned len=lowest-current;
2717       memctl(current,len,MCT_TEXT);
2718       lowest = current;
2719     }
2720   else
2721     memctl(current,NBPC,MCT_TEXT);
2722   errno=save_errno;
2723 }
2724
2725 #endif /* __sysV88__ */
2726
2727 #ifdef __sysV68__
2728
2729 #include <sys/signal.h>
2730 #include <errno.h>
2731
2732 /* Motorola forgot to put memctl.o in the libp version of libc881.a,
2733    so define it here, because we need it in __clear_insn_cache below */
2734 /* On older versions of this OS, no memctl or MCT_TEXT are defined;
2735    hence we enable this stuff only if MCT_TEXT is #define'd.  */
2736
2737 #ifdef MCT_TEXT
2738 asm("\n\
2739         global memctl\n\
2740 memctl:\n\
2741         movq &75,%d0\n\
2742         trap &0\n\
2743         bcc.b noerror\n\
2744         jmp cerror%\n\
2745 noerror:\n\
2746         movq &0,%d0\n\
2747         rts");
2748 #endif
2749
2750 /* Clear instruction cache so we can call trampolines on stack.
2751    This is called from FINALIZE_TRAMPOLINE in mot3300.h.  */
2752
2753 void
2754 __clear_insn_cache ()
2755 {
2756 #ifdef MCT_TEXT
2757   int save_errno;
2758
2759   /* Preserve errno, because users would be surprised to have
2760   errno changing without explicitly calling any system-call. */
2761   save_errno = errno;
2762
2763   /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache. 
2764      No need to use an address derived from _start or %sp, as 0 works also. */
2765   memctl(0, 4096, MCT_TEXT);
2766   errno = save_errno;
2767 #endif
2768 }
2769
2770 #endif /* __sysV68__ */
2771
2772 #ifdef __pyr__
2773
2774 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
2775 #include <stdio.h>
2776 #include <sys/mman.h>
2777 #include <sys/types.h>
2778 #include <sys/param.h>
2779 #include <sys/vmmac.h>
2780
2781 /* Modified from the convex -code above.
2782    mremap promises to clear the i-cache.  */
2783
2784 void
2785 __enable_execute_stack ()
2786 {
2787   int fp;
2788   if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
2789                 PROT_READ|PROT_WRITE|PROT_EXEC))
2790     {
2791       perror ("mprotect in __enable_execute_stack");
2792       fflush (stderr);
2793       abort ();
2794     }
2795 }
2796 #endif /* __pyr__ */
2797
2798 #if defined (sony_news) && defined (SYSTYPE_BSD)
2799
2800 #include <stdio.h>
2801 #include <sys/types.h>
2802 #include <sys/param.h>
2803 #include <syscall.h>
2804 #include <machine/sysnews.h>
2805
2806 /* cacheflush function for NEWS-OS 4.2.
2807    This function is called from trampoline-initialize code
2808    defined in config/mips/mips.h.  */
2809
2810 void
2811 cacheflush (char *beg, int size, int flag)
2812 {
2813   if (syscall (SYS_sysnews, NEWS_CACHEFLUSH, beg, size, FLUSH_BCACHE))
2814     {
2815       perror ("cache_flush");
2816       fflush (stderr);
2817       abort ();
2818     }
2819 }
2820
2821 #endif /* sony_news */
2822 #endif /* L_trampoline */
2823 \f
2824 #ifndef __CYGWIN__
2825 #ifdef L__main
2826
2827 #include "gbl-ctors.h"
2828 /* Some systems use __main in a way incompatible with its use in gcc, in these
2829    cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2830    give the same symbol without quotes for an alternative entry point.  You
2831    must define both, or neither.  */
2832 #ifndef NAME__MAIN
2833 #define NAME__MAIN "__main"
2834 #define SYMBOL__MAIN __main
2835 #endif
2836
2837 #ifdef INIT_SECTION_ASM_OP
2838 #undef HAS_INIT_SECTION
2839 #define HAS_INIT_SECTION
2840 #endif
2841
2842 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
2843
2844 /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
2845    code to run constructors.  In that case, we need to handle EH here, too.  */
2846
2847 #ifdef EH_FRAME_SECTION
2848 #include "frame.h"
2849 extern unsigned char __EH_FRAME_BEGIN__[];
2850 #endif
2851
2852 /* Run all the global destructors on exit from the program.  */
2853
2854 void
2855 __do_global_dtors ()
2856 {
2857 #ifdef DO_GLOBAL_DTORS_BODY
2858   DO_GLOBAL_DTORS_BODY;
2859 #else
2860   static func_ptr *p = __DTOR_LIST__ + 1;
2861   while (*p)
2862     {
2863       p++;
2864       (*(p-1)) ();
2865     }
2866 #endif
2867 #ifdef EH_FRAME_SECTION
2868   __deregister_frame_info (__EH_FRAME_BEGIN__);
2869 #endif
2870 }
2871 #endif
2872
2873 #ifndef HAS_INIT_SECTION
2874 /* Run all the global constructors on entry to the program.  */
2875
2876 void
2877 __do_global_ctors ()
2878 {
2879 #ifdef EH_FRAME_SECTION
2880   {
2881     static struct object object;
2882     __register_frame_info (__EH_FRAME_BEGIN__, &object);
2883   }
2884 #endif
2885   DO_GLOBAL_CTORS_BODY;
2886   atexit (__do_global_dtors);
2887 }
2888 #endif /* no HAS_INIT_SECTION */
2889
2890 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
2891 /* Subroutine called automatically by `main'.
2892    Compiling a global function named `main'
2893    produces an automatic call to this function at the beginning.
2894
2895    For many systems, this routine calls __do_global_ctors.
2896    For systems which support a .init section we use the .init section
2897    to run __do_global_ctors, so we need not do anything here.  */
2898
2899 void
2900 SYMBOL__MAIN ()
2901 {
2902   /* Support recursive calls to `main': run initializers just once.  */
2903   static int initialized;
2904   if (! initialized)
2905     {
2906       initialized = 1;
2907       __do_global_ctors ();
2908     }
2909 }
2910 #endif /* no HAS_INIT_SECTION or INVOKE__main */
2911
2912 #endif /* L__main */
2913 #endif /* __CYGWIN__ */
2914 \f
2915 #ifdef L_ctors
2916
2917 #include "gbl-ctors.h"
2918
2919 /* Provide default definitions for the lists of constructors and
2920    destructors, so that we don't get linker errors.  These symbols are
2921    intentionally bss symbols, so that gld and/or collect will provide
2922    the right values.  */
2923
2924 /* We declare the lists here with two elements each,
2925    so that they are valid empty lists if no other definition is loaded.
2926
2927    If we are using the old "set" extensions to have the gnu linker
2928    collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
2929    must be in the bss/common section.
2930
2931    Long term no port should use those extensions.  But many still do.  */
2932 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
2933 #if defined (ASM_OUTPUT_CONSTRUCTOR) || defined (USE_COLLECT2)
2934 func_ptr __CTOR_LIST__[2] = {0, 0};
2935 func_ptr __DTOR_LIST__[2] = {0, 0};
2936 #else
2937 func_ptr __CTOR_LIST__[2];
2938 func_ptr __DTOR_LIST__[2];
2939 #endif
2940 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
2941 #endif /* L_ctors */
2942 \f
2943 #ifdef L_exit
2944
2945 #include "gbl-ctors.h"
2946
2947 #ifdef NEED_ATEXIT
2948
2949 #ifndef ON_EXIT
2950
2951 # include <errno.h>
2952
2953 static func_ptr *atexit_chain = 0;
2954 static long atexit_chain_length = 0;
2955 static volatile long last_atexit_chain_slot = -1;
2956
2957 int
2958 atexit (func_ptr func)
2959 {
2960   if (++last_atexit_chain_slot == atexit_chain_length)
2961     {
2962       atexit_chain_length += 32;
2963       if (atexit_chain)
2964         atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
2965                                              * sizeof (func_ptr));
2966       else
2967         atexit_chain = (func_ptr *) malloc (atexit_chain_length
2968                                             * sizeof (func_ptr));
2969       if (! atexit_chain)
2970         {
2971           atexit_chain_length = 0;
2972           last_atexit_chain_slot = -1;
2973           errno = ENOMEM;
2974           return (-1);
2975         }
2976     }
2977   atexit_chain[last_atexit_chain_slot] = func;
2978   return (0);
2979 }
2980
2981 extern void _cleanup ();
2982 extern void _exit () __attribute__ ((noreturn));
2983
2984 void 
2985 exit (int status)
2986 {
2987   if (atexit_chain)
2988     {
2989       for ( ; last_atexit_chain_slot-- >= 0; )
2990         {
2991           (*atexit_chain[last_atexit_chain_slot + 1]) ();
2992           atexit_chain[last_atexit_chain_slot + 1] = 0;
2993         }
2994       free (atexit_chain);
2995       atexit_chain = 0;
2996     }
2997 #ifdef EXIT_BODY
2998   EXIT_BODY;
2999 #else
3000   _cleanup ();
3001 #endif
3002   _exit (status);
3003 }
3004
3005 #else /* ON_EXIT */
3006
3007 /* Simple; we just need a wrapper for ON_EXIT.  */
3008 int
3009 atexit (func_ptr func)
3010 {
3011   return ON_EXIT (func);
3012 }
3013
3014 #endif /* ON_EXIT */
3015 #endif /* NEED_ATEXIT */
3016
3017 #endif /* L_exit */
3018 \f
3019 #ifdef L_eh
3020
3021 #include "gthr.h"
3022
3023 /* Shared exception handling support routines.  */
3024
3025 extern void __default_terminate (void) __attribute__ ((__noreturn__));
3026
3027 void
3028 __default_terminate ()
3029 {
3030   abort ();
3031 }
3032
3033 void (*__terminate_func)() = __default_terminate;
3034
3035 void
3036 __terminate ()
3037 {
3038   (*__terminate_func)();
3039 }
3040
3041 void *
3042 __throw_type_match (void *catch_type, void *throw_type, void *obj)
3043 {
3044 #if 0
3045  printf ("__throw_type_match (): catch_type = %s, throw_type = %s\n",
3046          catch_type, throw_type);
3047 #endif
3048  if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)
3049    return obj;
3050  return 0;
3051 }
3052
3053 void
3054 __empty ()
3055 {
3056 }
3057 \f
3058
3059 /* Include definitions of EH context and table layout */
3060
3061 #include "eh-common.h"
3062 #ifndef inhibit_libc
3063 #include <stdio.h>
3064 #endif
3065
3066 /* Allocate and return a new EH context structure. */
3067
3068 extern void __throw ();
3069
3070 static void *
3071 new_eh_context ()
3072 {
3073   struct eh_full_context {
3074     struct eh_context c;
3075     void *top_elt[2];
3076   } *ehfc = (struct eh_full_context *) malloc (sizeof *ehfc);
3077
3078   if (! ehfc)
3079     __terminate ();
3080
3081   memset (ehfc, 0, sizeof *ehfc);
3082
3083   ehfc->c.dynamic_handler_chain = (void **) ehfc->top_elt;
3084
3085   /* This should optimize out entirely.  This should always be true,
3086      but just in case it ever isn't, don't allow bogus code to be
3087      generated.  */
3088
3089   if ((void*)(&ehfc->c) != (void*)ehfc)
3090     __terminate ();
3091
3092   return &ehfc->c;
3093 }
3094
3095 #if __GTHREADS
3096 static __gthread_key_t eh_context_key;
3097
3098 /* Destructor for struct eh_context. */
3099 static void
3100 eh_context_free (void *ptr)
3101 {
3102   __gthread_key_dtor (eh_context_key, ptr);
3103   if (ptr)
3104     free (ptr);
3105 }
3106 #endif
3107
3108 /* Pointer to function to return EH context. */
3109
3110 static struct eh_context *eh_context_initialize ();
3111 static struct eh_context *eh_context_static ();
3112 #if __GTHREADS
3113 static struct eh_context *eh_context_specific ();
3114 #endif
3115
3116 static struct eh_context *(*get_eh_context) () = &eh_context_initialize;
3117
3118 /* Routine to get EH context.
3119    This one will simply call the function pointer. */
3120
3121 void *
3122 __get_eh_context ()
3123 {
3124   return (void *) (*get_eh_context) ();
3125 }
3126
3127 /* Get and set the language specific info pointer. */
3128
3129 void **
3130 __get_eh_info ()
3131 {
3132   struct eh_context *eh = (*get_eh_context) ();
3133   return &eh->info;
3134 }
3135 \f
3136 #ifdef DWARF2_UNWIND_INFO
3137 static int dwarf_reg_size_table_initialized = 0;
3138 static char dwarf_reg_size_table[FIRST_PSEUDO_REGISTER];
3139
3140 static void
3141 init_reg_size_table ()
3142 {
3143   __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
3144   dwarf_reg_size_table_initialized = 1;
3145 }
3146 #endif
3147
3148 #if __GTHREADS
3149 static void
3150 eh_threads_initialize ()
3151 {
3152   /* Try to create the key.  If it fails, revert to static method,
3153      otherwise start using thread specific EH contexts. */
3154   if (__gthread_key_create (&eh_context_key, &eh_context_free) == 0)
3155     get_eh_context = &eh_context_specific;
3156   else
3157     get_eh_context = &eh_context_static;
3158 }
3159 #endif /* no __GTHREADS */
3160
3161 /* Initialize EH context.
3162    This will be called only once, since we change GET_EH_CONTEXT
3163    pointer to another routine. */
3164
3165 static struct eh_context *
3166 eh_context_initialize ()
3167 {
3168 #if __GTHREADS
3169
3170   static __gthread_once_t once = __GTHREAD_ONCE_INIT;
3171   /* Make sure that get_eh_context does not point to us anymore.
3172      Some systems have dummy thread routines in their libc that
3173      return a success (Solaris 2.6 for example). */
3174   if (__gthread_once (&once, eh_threads_initialize) != 0
3175       || get_eh_context == &eh_context_initialize)
3176     {
3177       /* Use static version of EH context. */
3178       get_eh_context = &eh_context_static;
3179     }
3180 #ifdef DWARF2_UNWIND_INFO
3181   {
3182     static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
3183     if (__gthread_once (&once_regsizes, init_reg_size_table) != 0
3184         || ! dwarf_reg_size_table_initialized)
3185       init_reg_size_table ();
3186   }
3187 #endif
3188
3189 #else /* no __GTHREADS */
3190
3191   /* Use static version of EH context. */
3192   get_eh_context = &eh_context_static;
3193
3194 #ifdef DWARF2_UNWIND_INFO
3195   init_reg_size_table ();
3196 #endif
3197
3198 #endif /* no __GTHREADS */
3199
3200   return (*get_eh_context) ();
3201 }
3202
3203 /* Return a static EH context. */
3204
3205 static struct eh_context *
3206 eh_context_static ()
3207 {
3208   static struct eh_context eh;
3209   static int initialized;
3210   static void *top_elt[2];
3211
3212   if (! initialized)
3213     {
3214       initialized = 1;
3215       memset (&eh, 0, sizeof eh);
3216       eh.dynamic_handler_chain = top_elt;
3217     }
3218   return &eh;
3219 }
3220
3221 #if __GTHREADS
3222 /* Return a thread specific EH context. */
3223
3224 static struct eh_context *
3225 eh_context_specific ()
3226 {
3227   struct eh_context *eh;
3228   eh = (struct eh_context *) __gthread_getspecific (eh_context_key);
3229   if (! eh)
3230     {
3231       eh = new_eh_context ();
3232       if (__gthread_setspecific (eh_context_key, (void *) eh) != 0)
3233         __terminate ();
3234     }
3235
3236   return eh;
3237 }
3238 #endif __GTHREADS
3239 \f
3240 /* Support routines for setjmp/longjmp exception handling.  */
3241
3242 /* Calls to __sjthrow are generated by the compiler when an exception
3243    is raised when using the setjmp/longjmp exception handling codegen
3244    method.  */
3245
3246 #ifdef DONT_USE_BUILTIN_SETJMP
3247 extern void longjmp (void *, int);
3248 #endif
3249
3250 /* Routine to get the head of the current thread's dynamic handler chain
3251    use for exception handling. */
3252
3253 void ***
3254 __get_dynamic_handler_chain ()
3255 {
3256   struct eh_context *eh = (*get_eh_context) ();
3257   return &eh->dynamic_handler_chain;
3258 }
3259
3260 /* This is used to throw an exception when the setjmp/longjmp codegen
3261    method is used for exception handling.
3262
3263    We call __terminate if there are no handlers left.  Otherwise we run the
3264    cleanup actions off the dynamic cleanup stack, and pop the top of the
3265    dynamic handler chain, and use longjmp to transfer back to the associated
3266    handler.  */
3267
3268 extern void __sjthrow (void) __attribute__ ((__noreturn__));
3269
3270 void
3271 __sjthrow ()
3272 {
3273   struct eh_context *eh = (*get_eh_context) ();
3274   void ***dhc = &eh->dynamic_handler_chain;
3275   void *jmpbuf;
3276   void (*func)(void *, int);
3277   void *arg;
3278   void ***cleanup;
3279
3280   /* The cleanup chain is one word into the buffer.  Get the cleanup
3281      chain.  */
3282   cleanup = (void***)&(*dhc)[1];
3283
3284   /* If there are any cleanups in the chain, run them now.  */
3285   if (cleanup[0])
3286     {
3287       double store[200];
3288       void **buf = (void**)store;
3289       buf[1] = 0;
3290       buf[0] = (*dhc);
3291
3292       /* try { */
3293 #ifdef DONT_USE_BUILTIN_SETJMP
3294       if (! setjmp (&buf[2]))
3295 #else
3296       if (! __builtin_setjmp (&buf[2]))
3297 #endif
3298         {
3299           *dhc = buf;
3300           while (cleanup[0])
3301             {
3302               func = (void(*)(void*, int))cleanup[0][1];
3303               arg = (void*)cleanup[0][2];
3304
3305               /* Update this before running the cleanup.  */
3306               cleanup[0] = (void **)cleanup[0][0];
3307
3308               (*func)(arg, 2);
3309             }
3310           *dhc = buf[0];
3311         }
3312       /* catch (...) */
3313       else
3314         {
3315           __terminate ();
3316         }
3317     }
3318   
3319   /* We must call terminate if we try and rethrow an exception, when
3320      there is no exception currently active and when there are no
3321      handlers left.  */
3322   if (! eh->info || (*dhc)[0] == 0)
3323     __terminate ();
3324     
3325   /* Find the jmpbuf associated with the top element of the dynamic
3326      handler chain.  The jumpbuf starts two words into the buffer.  */
3327   jmpbuf = &(*dhc)[2];
3328
3329   /* Then we pop the top element off the dynamic handler chain.  */
3330   *dhc = (void**)(*dhc)[0];
3331
3332   /* And then we jump to the handler.  */
3333
3334 #ifdef DONT_USE_BUILTIN_SETJMP
3335   longjmp (jmpbuf, 1);
3336 #else
3337   __builtin_longjmp (jmpbuf, 1);
3338 #endif
3339 }
3340
3341 /* Run cleanups on the dynamic cleanup stack for the current dynamic
3342    handler, then pop the handler off the dynamic handler stack, and
3343    then throw.  This is used to skip the first handler, and transfer
3344    control to the next handler in the dynamic handler stack.  */
3345
3346 extern void __sjpopnthrow (void) __attribute__ ((__noreturn__));
3347
3348 void
3349 __sjpopnthrow ()
3350 {
3351   struct eh_context *eh = (*get_eh_context) ();
3352   void ***dhc = &eh->dynamic_handler_chain;
3353   void (*func)(void *, int);
3354   void *arg;
3355   void ***cleanup;
3356
3357   /* The cleanup chain is one word into the buffer.  Get the cleanup
3358      chain.  */
3359   cleanup = (void***)&(*dhc)[1];
3360
3361   /* If there are any cleanups in the chain, run them now.  */
3362   if (cleanup[0])
3363     {
3364       double store[200];
3365       void **buf = (void**)store;
3366       buf[1] = 0;
3367       buf[0] = (*dhc);
3368
3369       /* try { */
3370 #ifdef DONT_USE_BUILTIN_SETJMP
3371       if (! setjmp (&buf[2]))
3372 #else
3373       if (! __builtin_setjmp (&buf[2]))
3374 #endif
3375         {
3376           *dhc = buf;
3377           while (cleanup[0])
3378             {
3379               func = (void(*)(void*, int))cleanup[0][1];
3380               arg = (void*)cleanup[0][2];
3381
3382               /* Update this before running the cleanup.  */
3383               cleanup[0] = (void **)cleanup[0][0];
3384
3385               (*func)(arg, 2);
3386             }
3387           *dhc = buf[0];
3388         }
3389       /* catch (...) */
3390       else
3391         {
3392           __terminate ();
3393         }
3394     }
3395
3396   /* Then we pop the top element off the dynamic handler chain.  */
3397   *dhc = (void**)(*dhc)[0];
3398
3399   __sjthrow ();
3400 }
3401 \f
3402 /* Support code for all exception region-based exception handling.  */
3403
3404 int
3405 __eh_rtime_match (void *rtime)
3406 {
3407   void *info;
3408   __eh_matcher matcher;
3409   void *ret;
3410
3411   info = *(__get_eh_info ());
3412   matcher = ((__eh_info *)info)->match_function;
3413   if (! matcher)
3414     {
3415 #ifndef inhibit_libc
3416       fprintf (stderr, "Internal Compiler Bug: No runtime type matcher.");
3417 #endif
3418       return 0;
3419     }
3420   ret = (*matcher) (info, rtime, (void *)0);
3421   return (ret != NULL);
3422 }
3423
3424 /* This value identifies the place from which an exception is being
3425    thrown.  */
3426
3427 #ifdef EH_TABLE_LOOKUP
3428
3429 EH_TABLE_LOOKUP
3430
3431 #else
3432
3433 #ifdef DWARF2_UNWIND_INFO
3434
3435 /* Return the table version of an exception descriptor */
3436
3437 short 
3438 __get_eh_table_version (exception_descriptor *table) 
3439 {
3440   return table->lang.version;
3441 }
3442
3443 /* Return the originating table language of an exception descriptor */
3444
3445 short 
3446 __get_eh_table_language (exception_descriptor *table)
3447 {
3448   return table->lang.language;
3449 }
3450
3451 /* This routine takes a PC and a pointer to the exception region TABLE for
3452    its translation unit, and returns the address of the exception handler
3453    associated with the closest exception table handler entry associated
3454    with that PC, or 0 if there are no table entries the PC fits in.
3455
3456    In the advent of a tie, we have to give the last entry, as it represents
3457    an inner block.  */
3458
3459 static void *
3460 old_find_exception_handler (void *pc, old_exception_table *table)
3461 {
3462   if (table)
3463     {
3464       int pos;
3465       int best = -1;
3466
3467       /* We can't do a binary search because the table isn't guaranteed
3468          to be sorted from function to function.  */
3469       for (pos = 0; table[pos].start_region != (void *) -1; ++pos)
3470         {
3471           if (table[pos].start_region <= pc && table[pos].end_region > pc)
3472             {
3473               /* This can apply.  Make sure it is at least as small as
3474                  the previous best.  */
3475               if (best == -1 || (table[pos].end_region <= table[best].end_region
3476                         && table[pos].start_region >= table[best].start_region))
3477                 best = pos;
3478             }
3479           /* But it is sorted by starting PC within a function.  */
3480           else if (best >= 0 && table[pos].start_region > pc)
3481             break;
3482         }
3483       if (best != -1)
3484         return table[best].exception_handler;
3485     }
3486
3487   return (void *) 0;
3488 }
3489
3490 /* find_exception_handler finds the correct handler, if there is one, to
3491    handle an exception.
3492    returns a pointer to the handler which controlled should be transferred
3493    to, or NULL if there is nothing left.
3494    Parameters:
3495    PC - pc where the exception originates. If this is a rethrow, 
3496         then this starts out as a pointer to the exception table
3497         entry we wish to rethrow out of.
3498    TABLE - exception table for the current module.
3499    EH_INFO - eh info pointer for this exception.
3500    RETHROW - 1 if this is a rethrow. (see incoming value of PC).
3501    CLEANUP - returned flag indicating whether this is a cleanup handler.
3502 */
3503 static void *
3504 find_exception_handler (void *pc, exception_descriptor *table, 
3505                         __eh_info *eh_info, int rethrow, int *cleanup)
3506 {
3507
3508   void *retval = NULL;
3509   *cleanup = 1;
3510   if (table)
3511     {
3512       int pos = 0;
3513       /* The new model assumed the table is sorted inner-most out so the
3514          first region we find which matches is the correct one */
3515
3516       exception_table *tab = &(table->table[0]);
3517
3518       /* Subtract 1 from the PC to avoid hitting the next region */
3519       if (rethrow) 
3520         {
3521           /* pc is actually the region table entry to rethrow out of */
3522           pos = ((exception_table *) pc) - tab;
3523           pc = ((exception_table *) pc)->end_region - 1;
3524
3525           /* The label is always on the LAST handler entry for a region, 
3526              so we know the next entry is a different region, even if the
3527              addresses are the same. Make sure its not end of table tho. */
3528           if (tab[pos].start_region != (void *) -1)
3529             pos++;
3530         }
3531       else
3532         pc--;
3533       
3534       /* We can't do a binary search because the table is in inner-most
3535          to outermost address ranges within functions */
3536       for ( ; tab[pos].start_region != (void *) -1; pos++)
3537         { 
3538           if (tab[pos].start_region <= pc && tab[pos].end_region > pc)
3539             {
3540               if (tab[pos].match_info)
3541                 {
3542                   __eh_matcher matcher = eh_info->match_function;
3543                   /* match info but no matcher is NOT a match */
3544                   if (matcher) 
3545                     {
3546                       void *ret = (*matcher)((void *) eh_info, 
3547                                              tab[pos].match_info, table);
3548                       if (ret) 
3549                         {
3550                           if (retval == NULL)
3551                             retval = tab[pos].exception_handler;
3552                           *cleanup = 0;
3553                           break;
3554                         }
3555                     }
3556                 }
3557               else
3558                 {
3559                   if (retval == NULL)
3560                     retval = tab[pos].exception_handler;
3561                 }
3562             }
3563         }
3564     }
3565   return retval;
3566 }
3567 #endif /* DWARF2_UNWIND_INFO */
3568 #endif /* EH_TABLE_LOOKUP */
3569 \f
3570 #ifdef DWARF2_UNWIND_INFO
3571 /* Support code for exception handling using static unwind information.  */
3572
3573 #include "frame.h"
3574
3575 /* This type is used in get_reg and put_reg to deal with ABIs where a void*
3576    is smaller than a word, such as the Irix 6 n32 ABI.  We cast twice to
3577    avoid a warning about casting between int and pointer of different
3578    sizes.  */
3579
3580 typedef int ptr_type __attribute__ ((mode (pointer)));
3581
3582 #ifdef INCOMING_REGNO
3583 /* Is the saved value for register REG in frame UDATA stored in a register
3584    window in the previous frame?  */
3585
3586 /* ??? The Sparc INCOMING_REGNO references TARGET_FLAT.  This allows us
3587    to use the macro here.  One wonders, though, that perhaps TARGET_FLAT
3588    compiled functions won't work with the frame-unwind stuff here.  
3589    Perhaps the entireity of in_reg_window should be conditional on having
3590    seen a DW_CFA_GNU_window_save?  */
3591 #define target_flags 0
3592
3593 static int
3594 in_reg_window (int reg, frame_state *udata)
3595 {
3596   if (udata->saved[reg] == REG_SAVED_REG)
3597     return INCOMING_REGNO (reg) == reg;
3598   if (udata->saved[reg] != REG_SAVED_OFFSET)
3599     return 0;
3600
3601 #ifdef STACK_GROWS_DOWNWARD
3602   return udata->reg_or_offset[reg] > 0;
3603 #else
3604   return udata->reg_or_offset[reg] < 0;
3605 #endif
3606 }
3607 #else
3608 static inline int in_reg_window (int reg, frame_state *udata) { return 0; }
3609 #endif /* INCOMING_REGNO */
3610
3611 /* Get the address of register REG as saved in UDATA, where SUB_UDATA is a
3612    frame called by UDATA or 0.  */
3613
3614 static word_type *
3615 get_reg_addr (unsigned reg, frame_state *udata, frame_state *sub_udata)
3616 {
3617   while (udata->saved[reg] == REG_SAVED_REG)
3618     {
3619       reg = udata->reg_or_offset[reg];
3620       if (in_reg_window (reg, udata))
3621         {
3622           udata = sub_udata;
3623           sub_udata = NULL;
3624         }
3625     }
3626   if (udata->saved[reg] == REG_SAVED_OFFSET)
3627     return (word_type *)(udata->cfa + udata->reg_or_offset[reg]);
3628   else
3629     abort ();
3630 }
3631
3632 /* Get the value of register REG as saved in UDATA, where SUB_UDATA is a
3633    frame called by UDATA or 0.  */
3634
3635 static inline void *
3636 get_reg (unsigned reg, frame_state *udata, frame_state *sub_udata)
3637 {
3638   return (void *)(ptr_type) *get_reg_addr (reg, udata, sub_udata);
3639 }
3640
3641 /* Overwrite the saved value for register REG in frame UDATA with VAL.  */
3642
3643 static inline void
3644 put_reg (unsigned reg, void *val, frame_state *udata)
3645 {
3646   *get_reg_addr (reg, udata, NULL) = (word_type)(ptr_type) val;
3647 }
3648
3649 /* Copy the saved value for register REG from frame UDATA to frame
3650    TARGET_UDATA.  Unlike the previous two functions, this can handle
3651    registers that are not one word large.  */
3652
3653 static void
3654 copy_reg (unsigned reg, frame_state *udata, frame_state *target_udata)
3655 {
3656   word_type *preg = get_reg_addr (reg, udata, NULL);
3657   word_type *ptreg = get_reg_addr (reg, target_udata, NULL);
3658
3659   memcpy (ptreg, preg, dwarf_reg_size_table [reg]);
3660 }
3661
3662 /* Retrieve the return address for frame UDATA.  */
3663
3664 static inline void *
3665 get_return_addr (frame_state *udata, frame_state *sub_udata)
3666 {
3667   return __builtin_extract_return_addr
3668     (get_reg (udata->retaddr_column, udata, sub_udata));
3669 }
3670
3671 /* Overwrite the return address for frame UDATA with VAL.  */
3672
3673 static inline void
3674 put_return_addr (void *val, frame_state *udata)
3675 {
3676   val = __builtin_frob_return_addr (val);
3677   put_reg (udata->retaddr_column, val, udata);
3678 }
3679
3680 /* Given the current frame UDATA and its return address PC, return the
3681    information about the calling frame in CALLER_UDATA.  */
3682
3683 static void *
3684 next_stack_level (void *pc, frame_state *udata, frame_state *caller_udata)
3685 {
3686   caller_udata = __frame_state_for (pc, caller_udata);
3687   if (! caller_udata)
3688     return 0;
3689
3690   /* Now go back to our caller's stack frame.  If our caller's CFA register
3691      was saved in our stack frame, restore it; otherwise, assume the CFA
3692      register is SP and restore it to our CFA value.  */
3693   if (udata->saved[caller_udata->cfa_reg])
3694     caller_udata->cfa = get_reg (caller_udata->cfa_reg, udata, 0);
3695   else
3696     caller_udata->cfa = udata->cfa;
3697   caller_udata->cfa += caller_udata->cfa_offset;
3698
3699   return caller_udata;
3700 }
3701
3702 /* Hook to call before __terminate if only cleanup handlers remain. */
3703 void 
3704 __unwinding_cleanup ()
3705 {
3706 }
3707
3708 /* throw_helper performs some of the common grunt work for a throw. This
3709    routine is called by throw and rethrows. This is pretty much split 
3710    out from the old __throw routine. An addition has been added which allows
3711    for a dummy call to a routine __unwinding_cleanup() when there are nothing
3712    but cleanups remaining. This allows a debugger to examine the state
3713    at which the throw was executed, before any cleanups, rather than
3714    at the terminate point after the stack has been unwound.
3715
3716    EH is the current eh_context structure.
3717    PC is the address of the call to __throw.
3718    MY_UDATA is the unwind information for __throw.
3719    OFFSET_P is where we return the SP adjustment offset.  */
3720
3721 static void *
3722 throw_helper (eh, pc, my_udata, offset_p)
3723      struct eh_context *eh;
3724      void *pc;
3725      frame_state *my_udata;
3726      long *offset_p;
3727 {
3728   frame_state ustruct2, *udata = &ustruct2;
3729   frame_state ustruct;
3730   frame_state *sub_udata = &ustruct;
3731   void *saved_pc = pc;
3732   void *handler;
3733   void *handler_p;
3734   void *pc_p;
3735   frame_state saved_ustruct;
3736   int new_eh_model;
3737   int cleanup = 0;
3738   int only_cleanup = 0;
3739   int rethrow = 0;
3740   int saved_state = 0;
3741   long args_size;
3742   __eh_info *eh_info = (__eh_info *)eh->info;
3743
3744   /* Do we find a handler based on a re-throw PC? */
3745   if (eh->table_index != (void *) 0)
3746     rethrow = 1;
3747
3748   memcpy (udata, my_udata, sizeof (*udata));
3749
3750   handler = (void *) 0;
3751   for (;;)
3752     { 
3753       frame_state *p = udata;
3754       udata = next_stack_level (pc, udata, sub_udata);
3755       sub_udata = p;
3756
3757       /* If we couldn't find the next frame, we lose.  */
3758       if (! udata)
3759         break;
3760
3761       if (udata->eh_ptr == NULL)
3762         new_eh_model = 0;
3763       else
3764         new_eh_model = (((exception_descriptor *)(udata->eh_ptr))->
3765                                           runtime_id_field == NEW_EH_RUNTIME);
3766
3767       if (rethrow) 
3768         {
3769           rethrow = 0;
3770           handler = find_exception_handler (eh->table_index, udata->eh_ptr, 
3771                                           eh_info, 1, &cleanup);
3772           eh->table_index = (void *)0;
3773         }
3774       else
3775         if (new_eh_model)
3776           handler = find_exception_handler (pc, udata->eh_ptr, eh_info, 
3777                                             0, &cleanup);
3778         else
3779           handler = old_find_exception_handler (pc, udata->eh_ptr);
3780
3781       /* If we found one, we can stop searching, if its not a cleanup. 
3782          for cleanups, we save the state, and keep looking. This allows
3783          us to call a debug hook if there are nothing but cleanups left. */
3784       if (handler)
3785         {
3786           if (cleanup)
3787             {
3788               if (!saved_state)
3789                 {
3790                   saved_ustruct = *udata;
3791                   handler_p = handler;
3792                   pc_p = pc;
3793                   saved_state = 1;
3794                   only_cleanup = 1;
3795                 }
3796             }
3797           else
3798             {
3799               only_cleanup = 0;
3800               break;
3801             }
3802         }
3803
3804       /* Otherwise, we continue searching.  We subtract 1 from PC to avoid
3805          hitting the beginning of the next region.  */
3806       pc = get_return_addr (udata, sub_udata) - 1;
3807     }
3808
3809   if (saved_state) 
3810     {
3811       udata = &saved_ustruct;
3812       handler = handler_p;
3813       pc = pc_p;
3814       if (only_cleanup)
3815         __unwinding_cleanup ();
3816     }
3817
3818   /* If we haven't found a handler by now, this is an unhandled
3819      exception.  */
3820   if (! handler) 
3821     __terminate();
3822
3823   eh->handler_label = handler;
3824
3825   args_size = udata->args_size;
3826
3827   if (pc == saved_pc)
3828     /* We found a handler in the throw context, no need to unwind.  */
3829     udata = my_udata;
3830   else
3831     {
3832       int i;
3833
3834       /* Unwind all the frames between this one and the handler by copying
3835          their saved register values into our register save slots.  */
3836
3837       /* Remember the PC where we found the handler.  */
3838       void *handler_pc = pc;
3839
3840       /* Start from the throw context again.  */
3841       pc = saved_pc;
3842       memcpy (udata, my_udata, sizeof (*udata));
3843
3844       while (pc != handler_pc)
3845         {
3846           frame_state *p = udata;
3847           udata = next_stack_level (pc, udata, sub_udata);
3848           sub_udata = p;
3849
3850           for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
3851             if (i != udata->retaddr_column && udata->saved[i])
3852               {
3853                 /* If you modify the saved value of the return address
3854                    register on the SPARC, you modify the return address for
3855                    your caller's frame.  Don't do that here, as it will
3856                    confuse get_return_addr.  */
3857                 if (in_reg_window (i, udata)
3858                     && udata->saved[udata->retaddr_column] == REG_SAVED_REG
3859                     && udata->reg_or_offset[udata->retaddr_column] == i)
3860                   continue;
3861                 copy_reg (i, udata, my_udata);
3862               }
3863
3864           pc = get_return_addr (udata, sub_udata) - 1;
3865         }
3866
3867       /* But we do need to update the saved return address register from
3868          the last frame we unwind, or the handler frame will have the wrong
3869          return address.  */
3870       if (udata->saved[udata->retaddr_column] == REG_SAVED_REG)
3871         {
3872           i = udata->reg_or_offset[udata->retaddr_column];
3873           if (in_reg_window (i, udata))
3874             copy_reg (i, udata, my_udata);
3875         }
3876     }
3877   /* udata now refers to the frame called by the handler frame.  */
3878
3879   /* We adjust SP by the difference between __throw's CFA and the CFA for
3880      the frame called by the handler frame, because those CFAs correspond
3881      to the SP values at the two call sites.  We need to further adjust by
3882      the args_size of the handler frame itself to get the handler frame's
3883      SP from before the args were pushed for that call.  */
3884 #ifdef STACK_GROWS_DOWNWARD
3885   *offset_p = udata->cfa - my_udata->cfa + args_size;
3886 #else
3887   *offset_p = my_udata->cfa - udata->cfa - args_size;
3888 #endif
3889                        
3890   return handler;
3891 }
3892
3893
3894 /* We first search for an exception handler, and if we don't find
3895    it, we call __terminate on the current stack frame so that we may
3896    use the debugger to walk the stack and understand why no handler
3897    was found.
3898
3899    If we find one, then we unwind the frames down to the one that
3900    has the handler and transfer control into the handler.  */
3901
3902 /*extern void __throw(void) __attribute__ ((__noreturn__));*/
3903
3904 void
3905 __throw ()
3906 {
3907   struct eh_context *eh = (*get_eh_context) ();
3908   void *pc, *handler;
3909   long offset;
3910
3911   /* XXX maybe make my_ustruct static so we don't have to look it up for
3912      each throw.  */
3913   frame_state my_ustruct, *my_udata = &my_ustruct;
3914
3915   /* This is required for C++ semantics.  We must call terminate if we
3916      try and rethrow an exception, when there is no exception currently
3917      active.  */
3918   if (! eh->info)
3919     __terminate ();
3920     
3921   /* Start at our stack frame.  */
3922 label:
3923   my_udata = __frame_state_for (&&label, my_udata);
3924   if (! my_udata)
3925     __terminate ();
3926
3927   /* We need to get the value from the CFA register. */
3928   my_udata->cfa = __builtin_dwarf_cfa ();
3929
3930   /* Do any necessary initialization to access arbitrary stack frames.
3931      On the SPARC, this means flushing the register windows.  */
3932   __builtin_unwind_init ();
3933
3934   /* Now reset pc to the right throw point.  */
3935   pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
3936
3937   handler = throw_helper (eh, pc, my_udata, &offset);
3938
3939   /* Now go!  */
3940
3941   __builtin_eh_return ((void *)eh, offset, handler);
3942
3943   /* Epilogue:  restore the handler frame's register values and return
3944      to the stub.  */
3945 }
3946
3947 /*extern void __rethrow(void *) __attribute__ ((__noreturn__));*/
3948
3949 void
3950 __rethrow (index)
3951      void *index;
3952 {
3953   struct eh_context *eh = (*get_eh_context) ();
3954   void *pc, *handler;
3955   long offset;
3956
3957   /* XXX maybe make my_ustruct static so we don't have to look it up for
3958      each throw.  */
3959   frame_state my_ustruct, *my_udata = &my_ustruct;
3960
3961   /* This is required for C++ semantics.  We must call terminate if we
3962      try and rethrow an exception, when there is no exception currently
3963      active.  */
3964   if (! eh->info)
3965     __terminate ();
3966
3967   /* This is the table index we want to rethrow from. The value of
3968      the END_REGION label is used for the PC of the throw, and the
3969      search begins with the next table entry. */
3970   eh->table_index = index;
3971     
3972   /* Start at our stack frame.  */
3973 label:
3974   my_udata = __frame_state_for (&&label, my_udata);
3975   if (! my_udata)
3976     __terminate ();
3977
3978   /* We need to get the value from the CFA register. */
3979   my_udata->cfa = __builtin_dwarf_cfa ();
3980
3981   /* Do any necessary initialization to access arbitrary stack frames.
3982      On the SPARC, this means flushing the register windows.  */
3983   __builtin_unwind_init ();
3984
3985   /* Now reset pc to the right throw point.  */
3986   pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
3987
3988   handler = throw_helper (eh, pc, my_udata, &offset);
3989
3990   /* Now go!  */
3991
3992   __builtin_eh_return ((void *)eh, offset, handler);
3993
3994   /* Epilogue:  restore the handler frame's register values and return
3995      to the stub.  */
3996 }
3997 #endif /* DWARF2_UNWIND_INFO */
3998
3999 #endif /* L_eh */
4000 \f
4001 #ifdef L_pure
4002 #ifndef inhibit_libc
4003 /* This gets us __GNU_LIBRARY__.  */
4004 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
4005 #include <stdio.h>
4006
4007 #ifdef __GNU_LIBRARY__
4008   /* Avoid forcing the library's meaning of `write' on the user program
4009      by using the "internal" name (for use within the library)  */
4010 #define write(fd, buf, n)       __write((fd), (buf), (n))
4011 #endif
4012 #endif /* inhibit_libc */
4013
4014 #define MESSAGE "pure virtual method called\n"
4015
4016 extern void __terminate (void) __attribute__ ((__noreturn__));
4017
4018 void
4019 __pure_virtual ()
4020 {
4021 #ifndef inhibit_libc
4022   write (2, MESSAGE, sizeof (MESSAGE) - 1);
4023 #endif
4024   __terminate ();
4025 }
4026 #endif