OSDN Git Service

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