OSDN Git Service

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