OSDN Git Service

* gbl-ctors.h: Lose HAVE_ATEXIT. Don't define ON_EXIT.
[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 /* Return the number of digits needed to print a value */
1461 /* __inline__ */ static int num_digits (long value, int base)
1462 {
1463   int minus = (value < 0 && base != 16);
1464   unsigned long v = (minus) ? -value : value;
1465   int ret = minus;
1466
1467   do
1468     {
1469       v /= base;
1470       ret++;
1471     }
1472   while (v);
1473
1474   return ret;
1475 }
1476
1477 void
1478 __bb_exit_func (void)
1479 {
1480   FILE *da_file, *file;
1481   long time_value;
1482   int i;
1483
1484   if (bb_head == 0)
1485     return;
1486
1487   i = strlen (bb_head->filename) - 3;
1488
1489   if (!strcmp (bb_head->filename+i, ".da"))
1490     {
1491       /* Must be -fprofile-arcs not -a.
1492          Dump data in a form that gcov expects.  */
1493
1494       struct bb *ptr;
1495
1496       for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1497         {
1498           /* If the file exists, and the number of counts in it is the same,
1499              then merge them in.  */
1500              
1501           if ((da_file = fopen (ptr->filename, "r")) != 0)
1502             {
1503               long n_counts = 0;
1504               
1505               if (__read_long (&n_counts, da_file, 8) != 0)
1506                 {
1507                   fprintf (stderr, "arc profiling: Can't read output file %s.\n",
1508                            ptr->filename);
1509                   continue;
1510                 }
1511
1512               if (n_counts == ptr->ncounts)
1513                 {
1514                   int i;
1515
1516                   for (i = 0; i < n_counts; i++)
1517                     {
1518                       long v = 0;
1519
1520                       if (__read_long (&v, da_file, 8) != 0)
1521                         {
1522                           fprintf (stderr, "arc profiling: Can't read output file %s.\n",
1523                                    ptr->filename);
1524                           break;
1525                         }
1526                       ptr->counts[i] += v;
1527                     }
1528                 }
1529
1530               if (fclose (da_file) == EOF)
1531                 fprintf (stderr, "arc profiling: Error closing output file %s.\n",
1532                          ptr->filename);
1533             }
1534           if ((da_file = fopen (ptr->filename, "w")) == 0)
1535             {
1536               fprintf (stderr, "arc profiling: Can't open output file %s.\n",
1537                        ptr->filename);
1538               continue;
1539             }
1540
1541           /* ??? Should first write a header to the file.  Preferably, a 4 byte
1542              magic number, 4 bytes containing the time the program was
1543              compiled, 4 bytes containing the last modification time of the
1544              source file, and 4 bytes indicating the compiler options used.
1545
1546              That way we can easily verify that the proper source/executable/
1547              data file combination is being used from gcov.  */
1548
1549           if (__write_long (ptr->ncounts, da_file, 8) != 0)
1550             {
1551               
1552               fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1553                        ptr->filename);
1554             }
1555           else
1556             {
1557               int j;
1558               long *count_ptr = ptr->counts;
1559               int ret = 0;
1560               for (j = ptr->ncounts; j > 0; j--)
1561                 {
1562                   if (__write_long (*count_ptr, da_file, 8) != 0)
1563                     {
1564                       ret=1;
1565                       break;
1566                     }
1567                   count_ptr++;
1568                 }
1569               if (ret)
1570                 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1571                          ptr->filename);
1572             }
1573           
1574           if (fclose (da_file) == EOF)
1575             fprintf (stderr, "arc profiling: Error closing output file %s.\n",
1576                      ptr->filename);
1577         }
1578
1579       return;
1580     }
1581
1582   /* Must be basic block profiling.  Emit a human readable output file.  */
1583
1584   file = fopen ("bb.out", "a");
1585
1586   if (!file)
1587     perror ("bb.out");
1588
1589   else
1590     {
1591       struct bb *ptr;
1592
1593       /* This is somewhat type incorrect, but it avoids worrying about
1594          exactly where time.h is included from.  It should be ok unless
1595          a void * differs from other pointer formats, or if sizeof (long)
1596          is < sizeof (time_t).  It would be nice if we could assume the
1597          use of rationale standards here.  */
1598
1599       time ((void *) &time_value);
1600       fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value));
1601
1602       /* We check the length field explicitly in order to allow compatibility
1603          with older GCC's which did not provide it.  */
1604
1605       for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1606         {
1607           int i;
1608           int func_p    = (ptr->nwords >= sizeof (struct bb)
1609                            && ptr->nwords <= 1000
1610                            && ptr->functions);
1611           int line_p    = (func_p && ptr->line_nums);
1612           int file_p    = (func_p && ptr->filenames);
1613           int addr_p    = (ptr->addresses != 0);
1614           long ncounts  = ptr->ncounts;
1615           long cnt_max  = 0;
1616           long line_max = 0;
1617           long addr_max = 0;
1618           int file_len  = 0;
1619           int func_len  = 0;
1620           int blk_len   = num_digits (ncounts, 10);
1621           int cnt_len;
1622           int line_len;
1623           int addr_len;
1624
1625           fprintf (file, "File %s, %ld basic blocks \n\n",
1626                    ptr->filename, ncounts);
1627
1628           /* Get max values for each field.  */
1629           for (i = 0; i < ncounts; i++)
1630             {
1631               const char *p;
1632               int len;
1633
1634               if (cnt_max < ptr->counts[i])
1635                 cnt_max = ptr->counts[i];
1636
1637               if (addr_p && addr_max < ptr->addresses[i])
1638                 addr_max = ptr->addresses[i];
1639
1640               if (line_p && line_max < ptr->line_nums[i])
1641                 line_max = ptr->line_nums[i];
1642
1643               if (func_p)
1644                 {
1645                   p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>";
1646                   len = strlen (p);
1647                   if (func_len < len)
1648                     func_len = len;
1649                 }
1650
1651               if (file_p)
1652                 {
1653                   p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>";
1654                   len = strlen (p);
1655                   if (file_len < len)
1656                     file_len = len;
1657                 }
1658             }
1659
1660           addr_len = num_digits (addr_max, 16);
1661           cnt_len  = num_digits (cnt_max, 10);
1662           line_len = num_digits (line_max, 10);
1663
1664           /* Now print out the basic block information.  */
1665           for (i = 0; i < ncounts; i++)
1666             {
1667               fprintf (file,
1668                        "    Block #%*d: executed %*ld time(s)",
1669                        blk_len, i+1,
1670                        cnt_len, ptr->counts[i]);
1671
1672               if (addr_p)
1673                 fprintf (file, " address= 0x%.*lx", addr_len,
1674                          ptr->addresses[i]);
1675
1676               if (func_p)
1677                 fprintf (file, " function= %-*s", func_len,
1678                          (ptr->functions[i]) ? ptr->functions[i] : "<none>");
1679
1680               if (line_p)
1681                 fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]);
1682
1683               if (file_p)
1684                 fprintf (file, " file= %s",
1685                          (ptr->filenames[i]) ? ptr->filenames[i] : "<none>");
1686
1687               fprintf (file, "\n");
1688             }
1689
1690           fprintf (file, "\n");
1691           fflush (file);
1692         }
1693
1694       fprintf (file, "\n\n");
1695       fclose (file);
1696     }
1697 }
1698
1699 void
1700 __bb_init_func (struct bb *blocks)
1701 {
1702   /* User is supposed to check whether the first word is non-0,
1703      but just in case....  */
1704
1705   if (blocks->zero_word)
1706     return;
1707
1708   /* Initialize destructor.  */
1709   if (!bb_head)
1710     atexit (__bb_exit_func);
1711
1712   /* Set up linked list.  */
1713   blocks->zero_word = 1;
1714   blocks->next = bb_head;
1715   bb_head = blocks;
1716 }
1717
1718 #ifndef MACHINE_STATE_SAVE
1719 #define MACHINE_STATE_SAVE(ID)
1720 #endif
1721 #ifndef MACHINE_STATE_RESTORE
1722 #define MACHINE_STATE_RESTORE(ID)
1723 #endif
1724
1725 /* Number of buckets in hashtable of basic block addresses.  */
1726
1727 #define BB_BUCKETS 311
1728
1729 /* Maximum length of string in file bb.in.  */
1730
1731 #define BBINBUFSIZE 500
1732
1733 /* BBINBUFSIZE-1 with double quotes. We could use #BBINBUFSIZE or
1734    "BBINBUFSIZE" but want to avoid trouble with preprocessors.  */
1735
1736 #define BBINBUFSIZESTR "499"
1737
1738 struct bb_edge
1739 {
1740   struct bb_edge *next;
1741   unsigned long src_addr;
1742   unsigned long dst_addr;
1743   unsigned long count;
1744 };
1745
1746 enum bb_func_mode
1747 {
1748   TRACE_KEEP = 0, TRACE_ON = 1, TRACE_OFF = 2
1749 };
1750
1751 struct bb_func
1752 {
1753   struct bb_func *next;
1754   char *funcname;
1755   char *filename;
1756   enum bb_func_mode mode;
1757 };
1758
1759 /* This is the connection to the outside world.
1760    The BLOCK_PROFILER macro must set __bb.blocks
1761    and __bb.blockno.  */
1762
1763 struct {
1764   unsigned long blockno;
1765   struct bb *blocks;
1766 } __bb;
1767
1768 /* Vars to store addrs of source and destination basic blocks 
1769    of a jump.  */
1770
1771 static unsigned long bb_src = 0;
1772 static unsigned long bb_dst = 0;
1773
1774 static FILE *bb_tracefile = (FILE *) 0;
1775 static struct bb_edge **bb_hashbuckets = (struct bb_edge **) 0;
1776 static struct bb_func *bb_func_head = (struct bb_func *) 0;
1777 static unsigned long bb_callcount = 0;
1778 static int bb_mode = 0;
1779
1780 static unsigned long *bb_stack = (unsigned long *) 0;
1781 static size_t bb_stacksize = 0;
1782
1783 static int reported = 0;
1784
1785 /* Trace modes:
1786 Always             :   Print execution frequencies of basic blocks
1787                        to file bb.out.
1788 bb_mode & 1 != 0   :   Dump trace of basic blocks to file bbtrace[.gz]
1789 bb_mode & 2 != 0   :   Print jump frequencies to file bb.out.
1790 bb_mode & 4 != 0   :   Cut call instructions from basic block flow.
1791 bb_mode & 8 != 0   :   Insert return instructions in basic block flow.
1792 */
1793
1794 #ifdef HAVE_POPEN
1795
1796 /*#include <sys/types.h>*/
1797 #include <sys/stat.h>
1798 /*#include <malloc.h>*/
1799
1800 /* Commands executed by gopen.  */
1801
1802 #define GOPENDECOMPRESS "gzip -cd "
1803 #define GOPENCOMPRESS "gzip -c >"
1804
1805 /* Like fopen but pipes through gzip.  mode may only be "r" or "w".
1806    If it does not compile, simply replace gopen by fopen and delete
1807    '.gz' from any first parameter to gopen.  */
1808
1809 static FILE *
1810 gopen (char *fn, char *mode)
1811 {
1812   int use_gzip;
1813   char *p;
1814
1815   if (mode[1])
1816     return (FILE *) 0;
1817
1818   if (mode[0] != 'r' && mode[0] != 'w') 
1819     return (FILE *) 0;
1820
1821   p = fn + strlen (fn)-1;
1822   use_gzip = ((p[-1] == '.' && (p[0] == 'Z' || p[0] == 'z'))
1823               || (p[-2] == '.' && p[-1] == 'g' && p[0] == 'z'));
1824
1825   if (use_gzip)
1826     {
1827       if (mode[0]=='r')
1828         {
1829           FILE *f;
1830           char *s = (char *) malloc (sizeof (char) * strlen (fn)
1831                                      + sizeof (GOPENDECOMPRESS));
1832           strcpy (s, GOPENDECOMPRESS);
1833           strcpy (s + (sizeof (GOPENDECOMPRESS)-1), fn);
1834           f = popen (s, mode);
1835           free (s);
1836           return f;
1837         }
1838
1839       else
1840         {
1841           FILE *f;
1842           char *s = (char *) malloc (sizeof (char) * strlen (fn)
1843                                      + sizeof (GOPENCOMPRESS));
1844           strcpy (s, GOPENCOMPRESS);
1845           strcpy (s + (sizeof (GOPENCOMPRESS)-1), fn);
1846           if (!(f = popen (s, mode)))
1847             f = fopen (s, mode);
1848           free (s);
1849           return f;
1850         }
1851     }
1852
1853   else
1854     return fopen (fn, mode);
1855 }
1856
1857 static int
1858 gclose (FILE *f)
1859 {
1860   struct stat buf;
1861
1862   if (f != 0)
1863     {
1864       if (!fstat (fileno (f), &buf) && S_ISFIFO (buf.st_mode))
1865         return pclose (f);
1866
1867       return fclose (f);
1868     }
1869   return 0;
1870 }
1871
1872 #endif /* HAVE_POPEN */
1873
1874 /* Called once per program.  */
1875
1876 static void
1877 __bb_exit_trace_func ()
1878 {
1879   FILE *file = fopen ("bb.out", "a");
1880   struct bb_func *f;
1881   struct bb *b;
1882         
1883   if (!file)
1884     perror ("bb.out");
1885
1886   if (bb_mode & 1)
1887     {
1888       if (!bb_tracefile)
1889         perror ("bbtrace");
1890       else
1891 #ifdef HAVE_POPEN
1892         gclose (bb_tracefile);
1893 #else
1894         fclose (bb_tracefile);
1895 #endif /* HAVE_POPEN */
1896     }
1897
1898   /* Check functions in `bb.in'.  */
1899
1900   if (file)
1901     {
1902       long time_value;
1903       const struct bb_func *p;
1904       int printed_something = 0;
1905       struct bb *ptr;
1906       long blk;
1907
1908       /* This is somewhat type incorrect.  */
1909       time ((void *) &time_value);
1910
1911       for (p = bb_func_head; p != (struct bb_func *) 0; p = p->next)
1912         {
1913           for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1914             {
1915               if (!ptr->filename || (p->filename != (char *) 0 && strcmp (p->filename, ptr->filename)))
1916                 continue;
1917               for (blk = 0; blk < ptr->ncounts; blk++)
1918                 {
1919                   if (!strcmp (p->funcname, ptr->functions[blk]))
1920                     goto found;
1921                 }
1922             }
1923   
1924           if (!printed_something)
1925             {
1926               fprintf (file, "Functions in `bb.in' not executed during basic block profiling on %s\n", ctime ((void *) &time_value));
1927               printed_something = 1;
1928             }
1929
1930           fprintf (file, "\tFunction %s", p->funcname);
1931           if (p->filename)
1932               fprintf (file, " of file %s", p->filename);
1933           fprintf (file, "\n" );
1934   
1935 found:        ;
1936         }
1937
1938       if (printed_something)
1939        fprintf (file, "\n");
1940
1941     }
1942
1943   if (bb_mode & 2)
1944     {
1945       if (!bb_hashbuckets)
1946         {
1947           if (!reported)
1948             {
1949               fprintf (stderr, "Profiler: out of memory\n");
1950               reported = 1;
1951             }
1952           return;
1953         }
1954     
1955       else if (file)
1956         {
1957           long time_value;
1958           int i;
1959           unsigned long addr_max = 0;
1960           unsigned long cnt_max  = 0;
1961           int cnt_len;
1962           int addr_len;
1963     
1964           /* This is somewhat type incorrect, but it avoids worrying about
1965              exactly where time.h is included from.  It should be ok unless
1966              a void * differs from other pointer formats, or if sizeof (long)
1967              is < sizeof (time_t).  It would be nice if we could assume the
1968              use of rationale standards here.  */
1969     
1970           time ((void *) &time_value);
1971           fprintf (file, "Basic block jump tracing");
1972
1973           switch (bb_mode & 12)
1974             {
1975               case 0:
1976                 fprintf (file, " (with call)");
1977               break;
1978
1979               case 4:
1980                 /* Print nothing.  */
1981               break;
1982
1983               case 8:
1984                 fprintf (file, " (with call & ret)");
1985               break;
1986
1987               case 12:
1988                 fprintf (file, " (with ret)");
1989               break;
1990             }
1991
1992           fprintf (file, " finished on %s\n", ctime ((void *) &time_value));
1993     
1994           for (i = 0; i < BB_BUCKETS; i++)
1995             {
1996                struct bb_edge *bucket = bb_hashbuckets[i];
1997                for ( ; bucket; bucket = bucket->next )
1998                  {
1999                    if (addr_max < bucket->src_addr) 
2000                      addr_max = bucket->src_addr;
2001                    if (addr_max < bucket->dst_addr) 
2002                      addr_max = bucket->dst_addr;
2003                    if (cnt_max < bucket->count) 
2004                      cnt_max = bucket->count;
2005                  }
2006             }
2007           addr_len = num_digits (addr_max, 16);
2008           cnt_len  = num_digits (cnt_max, 10);
2009     
2010           for ( i = 0; i < BB_BUCKETS; i++)
2011             {
2012                struct bb_edge *bucket = bb_hashbuckets[i];
2013                for ( ; bucket; bucket = bucket->next )
2014                  {
2015                    fprintf (file, "Jump from block 0x%.*lx to "
2016                                   "block 0x%.*lx executed %*lu time(s)\n", 
2017                             addr_len, bucket->src_addr, 
2018                             addr_len, bucket->dst_addr, 
2019                             cnt_len, bucket->count);
2020                  }
2021             }
2022   
2023           fprintf (file, "\n");
2024
2025         }
2026     }
2027
2028    if (file)
2029      fclose (file);
2030
2031    /* Free allocated memory.  */
2032
2033    f = bb_func_head;
2034    while (f)
2035      {
2036        struct bb_func *old = f;
2037
2038        f = f->next;
2039        if (old->funcname) free (old->funcname);
2040        if (old->filename) free (old->filename);
2041        free (old);
2042      }
2043
2044    if (bb_stack)
2045      free (bb_stack);
2046
2047    if (bb_hashbuckets)
2048      {
2049        int i;
2050
2051        for (i = 0; i < BB_BUCKETS; i++)
2052          {
2053            struct bb_edge *old, *bucket = bb_hashbuckets[i];
2054
2055            while (bucket)
2056              {
2057                old = bucket;
2058                bucket = bucket->next;
2059                free (old);
2060              }
2061          }
2062        free (bb_hashbuckets);
2063      }
2064
2065    for (b = bb_head; b; b = b->next)
2066      if (b->flags) free (b->flags);
2067 }
2068
2069 /* Called once per program.  */
2070
2071 static void
2072 __bb_init_prg ()
2073 {
2074   FILE *file;
2075   char buf[BBINBUFSIZE];
2076   const char *p;
2077   const char *pos;
2078   enum bb_func_mode m;
2079   int i;
2080
2081   /* Initialize destructor.  */
2082   atexit (__bb_exit_func);
2083
2084   if (!(file = fopen ("bb.in", "r")))
2085     return;
2086
2087   while(fscanf (file, " %" BBINBUFSIZESTR "s ", buf) != EOF)
2088     {
2089       p = buf;
2090       if (*p == '-') 
2091         { 
2092           m = TRACE_OFF; 
2093           p++; 
2094         }
2095       else 
2096         { 
2097           m = TRACE_ON; 
2098         }
2099       if (!strcmp (p, "__bb_trace__"))
2100         bb_mode |= 1;
2101       else if (!strcmp (p, "__bb_jumps__"))
2102         bb_mode |= 2;
2103       else if (!strcmp (p, "__bb_hidecall__"))
2104         bb_mode |= 4;
2105       else if (!strcmp (p, "__bb_showret__"))
2106         bb_mode |= 8;
2107       else 
2108         {
2109           struct bb_func *f = (struct bb_func *) malloc (sizeof (struct bb_func));
2110           if (f)
2111             {
2112               unsigned long l;
2113               f->next = bb_func_head;
2114               if ((pos = strchr (p, ':')))
2115                 {
2116                   if (!(f->funcname = (char *) malloc (strlen (pos+1)+1)))
2117                     continue;
2118                   strcpy (f->funcname, pos+1);
2119                   l = pos-p;
2120                   if ((f->filename = (char *) malloc (l+1)))
2121                     {
2122                       strncpy (f->filename, p, l);
2123                       f->filename[l] = '\0';
2124                     }
2125                   else
2126                     f->filename = (char *) 0;
2127                 }
2128               else
2129                 {
2130                   if (!(f->funcname = (char *) malloc (strlen (p)+1)))
2131                     continue;
2132                   strcpy (f->funcname, p);
2133                   f->filename = (char *) 0;
2134                 }
2135               f->mode = m;
2136               bb_func_head = f;
2137             }
2138          }
2139     }
2140   fclose (file);
2141
2142 #ifdef HAVE_POPEN 
2143
2144   if (bb_mode & 1)
2145       bb_tracefile = gopen ("bbtrace.gz", "w");
2146
2147 #else
2148
2149   if (bb_mode & 1)
2150       bb_tracefile = fopen ("bbtrace", "w");
2151
2152 #endif /* HAVE_POPEN */
2153
2154   if (bb_mode & 2)
2155     {
2156       bb_hashbuckets = (struct bb_edge **) 
2157                    malloc (BB_BUCKETS * sizeof (struct bb_edge *));
2158       if (bb_hashbuckets)
2159         /* Use a loop here rather than calling bzero to avoid having to
2160            conditionalize its existance.  */
2161         for (i = 0; i < BB_BUCKETS; i++)
2162           bb_hashbuckets[i] = 0;
2163     }
2164
2165   if (bb_mode & 12)
2166     {
2167       bb_stacksize = 10;
2168       bb_stack = (unsigned long *) malloc (bb_stacksize * sizeof (*bb_stack));
2169     }
2170
2171   /* Initialize destructor.  */
2172   atexit (__bb_exit_trace_func);
2173 }
2174
2175 /* Called upon entering a basic block.  */
2176
2177 void
2178 __bb_trace_func ()
2179 {
2180   struct bb_edge *bucket;
2181
2182   MACHINE_STATE_SAVE("1")
2183
2184   if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2185     goto skip;
2186
2187   bb_dst = __bb.blocks->addresses[__bb.blockno];
2188   __bb.blocks->counts[__bb.blockno]++;
2189
2190   if (bb_tracefile)
2191     {
2192       fwrite (&bb_dst, sizeof (unsigned long), 1, bb_tracefile);
2193     }
2194
2195   if (bb_hashbuckets)
2196     {
2197       struct bb_edge **startbucket, **oldnext;
2198
2199       oldnext = startbucket
2200         = & bb_hashbuckets[ (((int) bb_src*8) ^ (int) bb_dst) % BB_BUCKETS ];
2201       bucket = *startbucket;
2202
2203       for (bucket = *startbucket; bucket; 
2204            oldnext = &(bucket->next), bucket = *oldnext)
2205         {
2206           if (bucket->src_addr == bb_src
2207               && bucket->dst_addr == bb_dst)
2208             {
2209               bucket->count++;
2210               *oldnext = bucket->next;
2211               bucket->next = *startbucket;
2212               *startbucket = bucket;
2213               goto ret;
2214             }
2215         }
2216
2217       bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2218
2219       if (!bucket)
2220         {
2221           if (!reported)
2222             {
2223               fprintf (stderr, "Profiler: out of memory\n");
2224               reported = 1;
2225             }
2226         }
2227
2228       else
2229         {
2230           bucket->src_addr = bb_src;
2231           bucket->dst_addr = bb_dst;
2232           bucket->next = *startbucket;
2233           *startbucket = bucket;
2234           bucket->count = 1;
2235         }
2236     }
2237
2238 ret:
2239   bb_src = bb_dst;
2240
2241 skip:
2242   ;
2243
2244   MACHINE_STATE_RESTORE("1")
2245
2246 }
2247
2248 /* Called when returning from a function and `__bb_showret__' is set.  */
2249
2250 static void
2251 __bb_trace_func_ret ()
2252 {
2253   struct bb_edge *bucket;
2254
2255   if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2256     goto skip;
2257
2258   if (bb_hashbuckets)
2259     {
2260       struct bb_edge **startbucket, **oldnext;
2261
2262       oldnext = startbucket
2263         = & bb_hashbuckets[ (((int) bb_dst * 8) ^ (int) bb_src) % BB_BUCKETS ];
2264       bucket = *startbucket;
2265
2266       for (bucket = *startbucket; bucket; 
2267            oldnext = &(bucket->next), bucket = *oldnext)
2268         {
2269           if (bucket->src_addr == bb_dst
2270                && bucket->dst_addr == bb_src)
2271             {
2272               bucket->count++;
2273               *oldnext = bucket->next;
2274               bucket->next = *startbucket;
2275               *startbucket = bucket;
2276               goto ret;
2277             }
2278         }
2279
2280       bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2281
2282       if (!bucket)
2283         {
2284           if (!reported)
2285             {
2286               fprintf (stderr, "Profiler: out of memory\n");
2287               reported = 1;
2288             }
2289         }
2290
2291       else
2292         {
2293           bucket->src_addr = bb_dst;
2294           bucket->dst_addr = bb_src;
2295           bucket->next = *startbucket;
2296           *startbucket = bucket;
2297           bucket->count = 1;
2298         }
2299     }
2300
2301 ret:
2302   bb_dst = bb_src;
2303
2304 skip:
2305   ;
2306
2307 }
2308
2309 /* Called upon entering the first function of a file.  */
2310
2311 static void
2312 __bb_init_file (struct bb *blocks)
2313 {
2314
2315   const struct bb_func *p;
2316   long blk, ncounts = blocks->ncounts;
2317   const char **functions = blocks->functions;
2318
2319   /* Set up linked list.  */
2320   blocks->zero_word = 1;
2321   blocks->next = bb_head;
2322   bb_head = blocks;
2323
2324   blocks->flags = 0;
2325   if (!bb_func_head
2326       || !(blocks->flags = (char *) malloc (sizeof (char) * blocks->ncounts)))
2327     return;
2328
2329   for (blk = 0; blk < ncounts; blk++)
2330     blocks->flags[blk] = 0;
2331
2332   for (blk = 0; blk < ncounts; blk++)
2333     {
2334       for (p = bb_func_head; p; p = p->next)
2335         {
2336           if (!strcmp (p->funcname, functions[blk])
2337               && (!p->filename || !strcmp (p->filename, blocks->filename)))
2338             {
2339               blocks->flags[blk] |= p->mode;
2340             }
2341         }
2342     }
2343
2344 }
2345
2346 /* Called when exiting from a function.  */
2347
2348 void
2349 __bb_trace_ret ()
2350 {
2351
2352   MACHINE_STATE_SAVE("2")
2353
2354   if (bb_callcount)
2355     {
2356       if ((bb_mode & 12) && bb_stacksize > bb_callcount)
2357         {
2358           bb_src = bb_stack[bb_callcount];
2359           if (bb_mode & 8)
2360             __bb_trace_func_ret ();
2361         }
2362
2363       bb_callcount -= 1;
2364     }
2365
2366   MACHINE_STATE_RESTORE("2")
2367
2368 }
2369
2370 /* Called when entering a function.  */
2371
2372 void
2373 __bb_init_trace_func (struct bb *blocks, unsigned long blockno)
2374 {
2375   static int trace_init = 0;
2376
2377   MACHINE_STATE_SAVE("3")
2378
2379   if (!blocks->zero_word)
2380     { 
2381       if (!trace_init)
2382         { 
2383           trace_init = 1;
2384           __bb_init_prg ();
2385         }
2386       __bb_init_file (blocks);
2387     }
2388
2389   if (bb_callcount)
2390     {
2391
2392       bb_callcount += 1;
2393
2394       if (bb_mode & 12)
2395         {
2396           if (bb_callcount >= bb_stacksize)
2397             {
2398               size_t newsize = bb_callcount + 100;
2399
2400               bb_stack = (unsigned long *) realloc (bb_stack, newsize);
2401               if (! bb_stack)
2402                 {
2403                   if (!reported)
2404                     {
2405                       fprintf (stderr, "Profiler: out of memory\n");
2406                       reported = 1;
2407                     }
2408                   bb_stacksize = 0;
2409                   goto stack_overflow;
2410                 }
2411               bb_stacksize = newsize;
2412             }
2413           bb_stack[bb_callcount] = bb_src;
2414
2415           if (bb_mode & 4)
2416             bb_src = 0;
2417
2418         }
2419
2420 stack_overflow:;
2421
2422     }
2423
2424   else if (blocks->flags && (blocks->flags[blockno] & TRACE_ON))
2425     {
2426       bb_callcount = 1;
2427       bb_src = 0;
2428
2429       if (bb_stack)
2430           bb_stack[bb_callcount] = bb_src;
2431     }
2432
2433   MACHINE_STATE_RESTORE("3")
2434 }
2435
2436 #endif /* not inhibit_libc */
2437 #endif /* not BLOCK_PROFILER_CODE */
2438 #endif /* L_bb */
2439 \f
2440 #ifdef L_shtab
2441 unsigned int __shtab[] = {
2442     0x00000001, 0x00000002, 0x00000004, 0x00000008,
2443     0x00000010, 0x00000020, 0x00000040, 0x00000080,
2444     0x00000100, 0x00000200, 0x00000400, 0x00000800,
2445     0x00001000, 0x00002000, 0x00004000, 0x00008000,
2446     0x00010000, 0x00020000, 0x00040000, 0x00080000,
2447     0x00100000, 0x00200000, 0x00400000, 0x00800000,
2448     0x01000000, 0x02000000, 0x04000000, 0x08000000,
2449     0x10000000, 0x20000000, 0x40000000, 0x80000000
2450   };
2451 #endif
2452 \f
2453 #ifdef L_clear_cache
2454 /* Clear part of an instruction cache.  */
2455
2456 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
2457
2458 void
2459 __clear_cache (char *beg, char *end)
2460 {
2461 #ifdef CLEAR_INSN_CACHE 
2462   CLEAR_INSN_CACHE (beg, end);
2463 #else
2464 #ifdef INSN_CACHE_SIZE
2465   static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
2466   static int initialized;
2467   int offset;
2468   void *start_addr
2469   void *end_addr;
2470   typedef (*function_ptr) ();
2471
2472 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
2473   /* It's cheaper to clear the whole cache.
2474      Put in a series of jump instructions so that calling the beginning
2475      of the cache will clear the whole thing.  */
2476
2477   if (! initialized)
2478     {
2479       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2480                  & -INSN_CACHE_LINE_WIDTH);
2481       int end_ptr = ptr + INSN_CACHE_SIZE;
2482
2483       while (ptr < end_ptr)
2484         {
2485           *(INSTRUCTION_TYPE *)ptr
2486             = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
2487           ptr += INSN_CACHE_LINE_WIDTH;
2488         }
2489       *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
2490
2491       initialized = 1;
2492     }
2493
2494   /* Call the beginning of the sequence.  */
2495   (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2496                     & -INSN_CACHE_LINE_WIDTH))
2497    ());
2498
2499 #else /* Cache is large.  */
2500
2501   if (! initialized)
2502     {
2503       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2504                  & -INSN_CACHE_LINE_WIDTH);
2505
2506       while (ptr < (int) array + sizeof array)
2507         {
2508           *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
2509           ptr += INSN_CACHE_LINE_WIDTH;
2510         }
2511
2512       initialized = 1;
2513     }
2514
2515   /* Find the location in array that occupies the same cache line as BEG.  */
2516
2517   offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
2518   start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
2519                  & -INSN_CACHE_PLANE_SIZE)
2520                 + offset);
2521
2522   /* Compute the cache alignment of the place to stop clearing.  */
2523 #if 0  /* This is not needed for gcc's purposes.  */
2524   /* If the block to clear is bigger than a cache plane,
2525      we clear the entire cache, and OFFSET is already correct.  */ 
2526   if (end < beg + INSN_CACHE_PLANE_SIZE)
2527 #endif
2528     offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
2529                & -INSN_CACHE_LINE_WIDTH)
2530               & (INSN_CACHE_PLANE_SIZE - 1));
2531
2532 #if INSN_CACHE_DEPTH > 1
2533   end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
2534   if (end_addr <= start_addr)
2535     end_addr += INSN_CACHE_PLANE_SIZE;
2536
2537   for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
2538     {
2539       int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
2540       int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
2541
2542       while (addr != stop)
2543         {
2544           /* Call the return instruction at ADDR.  */
2545           ((function_ptr) addr) ();
2546
2547           addr += INSN_CACHE_LINE_WIDTH;
2548         }
2549     }
2550 #else /* just one plane */
2551   do
2552     {
2553       /* Call the return instruction at START_ADDR.  */
2554       ((function_ptr) start_addr) ();
2555
2556       start_addr += INSN_CACHE_LINE_WIDTH;
2557     }
2558   while ((start_addr % INSN_CACHE_SIZE) != offset);
2559 #endif /* just one plane */
2560 #endif /* Cache is large */
2561 #endif /* Cache exists */
2562 #endif /* CLEAR_INSN_CACHE */
2563 }
2564
2565 #endif /* L_clear_cache */
2566 \f
2567 #ifdef L_trampoline
2568
2569 /* Jump to a trampoline, loading the static chain address.  */
2570
2571 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
2572
2573 long getpagesize()
2574 {
2575 #ifdef _ALPHA_
2576   return 8192;
2577 #else
2578   return 4096;
2579 #endif
2580 }
2581
2582 #ifdef i386
2583 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
2584 #endif
2585
2586 int
2587 mprotect (char *addr, int len, int prot)
2588 {
2589   int np, op;
2590
2591   if (prot == 7)
2592     np = 0x40;
2593   else if (prot == 5)
2594     np = 0x20;
2595   else if (prot == 4)
2596     np = 0x10;
2597   else if (prot == 3)
2598     np = 0x04;
2599   else if (prot == 1)
2600     np = 0x02;
2601   else if (prot == 0)
2602     np = 0x01;
2603
2604   if (VirtualProtect (addr, len, np, &op))
2605     return 0;
2606   else
2607     return -1;
2608 }
2609
2610 #endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
2611
2612 #ifdef TRANSFER_FROM_TRAMPOLINE 
2613 TRANSFER_FROM_TRAMPOLINE 
2614 #endif
2615
2616 #if defined (NeXT) && defined (__MACH__)
2617
2618 /* Make stack executable so we can call trampolines on stack.
2619    This is called from INITIALIZE_TRAMPOLINE in next.h.  */
2620 #ifdef NeXTStep21
2621  #include <mach.h>
2622 #else
2623  #include <mach/mach.h>
2624 #endif
2625
2626 void
2627 __enable_execute_stack (char *addr)
2628 {
2629   kern_return_t r;
2630   char *eaddr = addr + TRAMPOLINE_SIZE;
2631   vm_address_t a = (vm_address_t) addr;
2632
2633   /* turn on execute access on stack */
2634   r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
2635   if (r != KERN_SUCCESS)
2636     {
2637       mach_error("vm_protect VM_PROT_ALL", r);
2638       exit(1);
2639     }
2640
2641   /* We inline the i-cache invalidation for speed */
2642
2643 #ifdef CLEAR_INSN_CACHE
2644   CLEAR_INSN_CACHE (addr, eaddr);
2645 #else
2646   __clear_cache ((int) addr, (int) eaddr);
2647 #endif
2648
2649
2650 #endif /* defined (NeXT) && defined (__MACH__) */
2651
2652 #ifdef __convex__
2653
2654 /* Make stack executable so we can call trampolines on stack.
2655    This is called from INITIALIZE_TRAMPOLINE in convex.h.  */
2656
2657 #include <sys/mman.h>
2658 #include <sys/vmparam.h>
2659 #include <machine/machparam.h>
2660
2661 void
2662 __enable_execute_stack ()
2663 {
2664   int fp;
2665   static unsigned lowest = USRSTACK;
2666   unsigned current = (unsigned) &fp & -NBPG;
2667
2668   if (lowest > current)
2669     {
2670       unsigned len = lowest - current;
2671       mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
2672       lowest = current;
2673     }
2674
2675   /* Clear instruction cache in case an old trampoline is in it.  */
2676   asm ("pich");
2677 }
2678 #endif /* __convex__ */
2679
2680 #ifdef __sysV88__
2681
2682 /* Modified from the convex -code above.  */
2683
2684 #include <sys/param.h>
2685 #include <errno.h>
2686 #include <sys/m88kbcs.h>
2687
2688 void
2689 __enable_execute_stack ()
2690 {
2691   int save_errno;
2692   static unsigned long lowest = USRSTACK;
2693   unsigned long current = (unsigned long) &save_errno & -NBPC;
2694   
2695   /* Ignore errno being set. memctl sets errno to EINVAL whenever the
2696      address is seen as 'negative'. That is the case with the stack.   */
2697
2698   save_errno=errno;
2699   if (lowest > current)
2700     {
2701       unsigned len=lowest-current;
2702       memctl(current,len,MCT_TEXT);
2703       lowest = current;
2704     }
2705   else
2706     memctl(current,NBPC,MCT_TEXT);
2707   errno=save_errno;
2708 }
2709
2710 #endif /* __sysV88__ */
2711
2712 #ifdef __sysV68__
2713
2714 #include <sys/signal.h>
2715 #include <errno.h>
2716
2717 /* Motorola forgot to put memctl.o in the libp version of libc881.a,
2718    so define it here, because we need it in __clear_insn_cache below */
2719 /* On older versions of this OS, no memctl or MCT_TEXT are defined;
2720    hence we enable this stuff only if MCT_TEXT is #define'd.  */
2721
2722 #ifdef MCT_TEXT
2723 asm("\n\
2724         global memctl\n\
2725 memctl:\n\
2726         movq &75,%d0\n\
2727         trap &0\n\
2728         bcc.b noerror\n\
2729         jmp cerror%\n\
2730 noerror:\n\
2731         movq &0,%d0\n\
2732         rts");
2733 #endif
2734
2735 /* Clear instruction cache so we can call trampolines on stack.
2736    This is called from FINALIZE_TRAMPOLINE in mot3300.h.  */
2737
2738 void
2739 __clear_insn_cache ()
2740 {
2741 #ifdef MCT_TEXT
2742   int save_errno;
2743
2744   /* Preserve errno, because users would be surprised to have
2745   errno changing without explicitly calling any system-call. */
2746   save_errno = errno;
2747
2748   /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache. 
2749      No need to use an address derived from _start or %sp, as 0 works also. */
2750   memctl(0, 4096, MCT_TEXT);
2751   errno = save_errno;
2752 #endif
2753 }
2754
2755 #endif /* __sysV68__ */
2756
2757 #ifdef __pyr__
2758
2759 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
2760 #include <stdio.h>
2761 #include <sys/mman.h>
2762 #include <sys/types.h>
2763 #include <sys/param.h>
2764 #include <sys/vmmac.h>
2765
2766 /* Modified from the convex -code above.
2767    mremap promises to clear the i-cache.  */
2768
2769 void
2770 __enable_execute_stack ()
2771 {
2772   int fp;
2773   if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
2774                 PROT_READ|PROT_WRITE|PROT_EXEC))
2775     {
2776       perror ("mprotect in __enable_execute_stack");
2777       fflush (stderr);
2778       abort ();
2779     }
2780 }
2781 #endif /* __pyr__ */
2782
2783 #if defined (sony_news) && defined (SYSTYPE_BSD)
2784
2785 #include <stdio.h>
2786 #include <sys/types.h>
2787 #include <sys/param.h>
2788 #include <syscall.h>
2789 #include <machine/sysnews.h>
2790
2791 /* cacheflush function for NEWS-OS 4.2.
2792    This function is called from trampoline-initialize code
2793    defined in config/mips/mips.h.  */
2794
2795 void
2796 cacheflush (char *beg, int size, int flag)
2797 {
2798   if (syscall (SYS_sysnews, NEWS_CACHEFLUSH, beg, size, FLUSH_BCACHE))
2799     {
2800       perror ("cache_flush");
2801       fflush (stderr);
2802       abort ();
2803     }
2804 }
2805
2806 #endif /* sony_news */
2807 #endif /* L_trampoline */
2808 \f
2809 #ifndef __CYGWIN__
2810 #ifdef L__main
2811
2812 #include "gbl-ctors.h"
2813 /* Some systems use __main in a way incompatible with its use in gcc, in these
2814    cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2815    give the same symbol without quotes for an alternative entry point.  You
2816    must define both, or neither.  */
2817 #ifndef NAME__MAIN
2818 #define NAME__MAIN "__main"
2819 #define SYMBOL__MAIN __main
2820 #endif
2821
2822 #ifdef INIT_SECTION_ASM_OP
2823 #undef HAS_INIT_SECTION
2824 #define HAS_INIT_SECTION
2825 #endif
2826
2827 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
2828
2829 /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
2830    code to run constructors.  In that case, we need to handle EH here, too.  */
2831
2832 #ifdef EH_FRAME_SECTION
2833 #include "frame.h"
2834 extern unsigned char __EH_FRAME_BEGIN__[];
2835 #endif
2836
2837 /* Run all the global destructors on exit from the program.  */
2838
2839 void
2840 __do_global_dtors ()
2841 {
2842 #ifdef DO_GLOBAL_DTORS_BODY
2843   DO_GLOBAL_DTORS_BODY;
2844 #else
2845   static func_ptr *p = __DTOR_LIST__ + 1;
2846   while (*p)
2847     {
2848       p++;
2849       (*(p-1)) ();
2850     }
2851 #endif
2852 #ifdef EH_FRAME_SECTION
2853   __deregister_frame_info (__EH_FRAME_BEGIN__);
2854 #endif
2855 }
2856 #endif
2857
2858 #ifndef HAS_INIT_SECTION
2859 /* Run all the global constructors on entry to the program.  */
2860
2861 void
2862 __do_global_ctors ()
2863 {
2864 #ifdef EH_FRAME_SECTION
2865   {
2866     static struct object object;
2867     __register_frame_info (__EH_FRAME_BEGIN__, &object);
2868   }
2869 #endif
2870   DO_GLOBAL_CTORS_BODY;
2871   atexit (__do_global_dtors, 0);
2872 }
2873 #endif /* no HAS_INIT_SECTION */
2874
2875 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
2876 /* Subroutine called automatically by `main'.
2877    Compiling a global function named `main'
2878    produces an automatic call to this function at the beginning.
2879
2880    For many systems, this routine calls __do_global_ctors.
2881    For systems which support a .init section we use the .init section
2882    to run __do_global_ctors, so we need not do anything here.  */
2883
2884 void
2885 SYMBOL__MAIN ()
2886 {
2887   /* Support recursive calls to `main': run initializers just once.  */
2888   static int initialized;
2889   if (! initialized)
2890     {
2891       initialized = 1;
2892       __do_global_ctors ();
2893     }
2894 }
2895 #endif /* no HAS_INIT_SECTION or INVOKE__main */
2896
2897 #endif /* L__main */
2898 #endif /* __CYGWIN__ */
2899 \f
2900 #ifdef L_ctors
2901
2902 #include "gbl-ctors.h"
2903
2904 /* Provide default definitions for the lists of constructors and
2905    destructors, so that we don't get linker errors.  These symbols are
2906    intentionally bss symbols, so that gld and/or collect will provide
2907    the right values.  */
2908
2909 /* We declare the lists here with two elements each,
2910    so that they are valid empty lists if no other definition is loaded.
2911
2912    If we are using the old "set" extensions to have the gnu linker
2913    collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
2914    must be in the bss/common section.
2915
2916    Long term no port should use those extensions.  But many still do.  */
2917 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
2918 #if defined (ASM_OUTPUT_CONSTRUCTOR) || defined (USE_COLLECT2)
2919 func_ptr __CTOR_LIST__[2] = {0, 0};
2920 func_ptr __DTOR_LIST__[2] = {0, 0};
2921 #else
2922 func_ptr __CTOR_LIST__[2];
2923 func_ptr __DTOR_LIST__[2];
2924 #endif
2925 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
2926 #endif /* L_ctors */
2927 \f
2928 #ifdef L_exit
2929
2930 #include "gbl-ctors.h"
2931
2932 #ifdef NEED_ATEXIT
2933
2934 #ifndef HAVE_ON_EXIT
2935
2936 # include <errno.h>
2937
2938 static func_ptr *atexit_chain = 0;
2939 static long atexit_chain_length = 0;
2940 static volatile long last_atexit_chain_slot = -1;
2941
2942 int
2943 atexit (func_ptr func)
2944 {
2945   if (++last_atexit_chain_slot == atexit_chain_length)
2946     {
2947       atexit_chain_length += 32;
2948       if (atexit_chain)
2949         atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
2950                                              * sizeof (func_ptr));
2951       else
2952         atexit_chain = (func_ptr *) malloc (atexit_chain_length
2953                                             * sizeof (func_ptr));
2954       if (! atexit_chain)
2955         {
2956           atexit_chain_length = 0;
2957           last_atexit_chain_slot = -1;
2958           errno = ENOMEM;
2959           return (-1);
2960         }
2961     }
2962   atexit_chain[last_atexit_chain_slot] = func;
2963   return (0);
2964 }
2965
2966 extern void _cleanup ();
2967 extern void _exit () __attribute__ ((noreturn));
2968
2969 void 
2970 exit (int status)
2971 {
2972   if (atexit_chain)
2973     {
2974       for ( ; last_atexit_chain_slot-- >= 0; )
2975         {
2976           (*atexit_chain[last_atexit_chain_slot + 1]) ();
2977           atexit_chain[last_atexit_chain_slot + 1] = 0;
2978         }
2979       free (atexit_chain);
2980       atexit_chain = 0;
2981     }
2982 #ifdef EXIT_BODY
2983   EXIT_BODY;
2984 #else
2985   _cleanup ();
2986 #endif
2987   _exit (status);
2988 }
2989
2990 #else /* HAVE_ON_EXIT */
2991
2992 /* Simple; we just need a wrapper for ON_EXIT.  */
2993 int
2994 atexit (func_ptr func)
2995 {
2996   return ON_EXIT (func);
2997 }
2998
2999 #endif /* HAVE_ON_EXIT */
3000 #endif /* NEED_ATEXIT */
3001
3002 #endif /* L_exit */
3003 \f
3004 #ifdef L_eh
3005
3006 #include "gthr.h"
3007
3008 /* Shared exception handling support routines.  */
3009
3010 extern void __default_terminate (void) __attribute__ ((__noreturn__));
3011
3012 void
3013 __default_terminate ()
3014 {
3015   abort ();
3016 }
3017
3018 void (*__terminate_func)() = __default_terminate;
3019
3020 void
3021 __terminate ()
3022 {
3023   (*__terminate_func)();
3024 }
3025
3026 void *
3027 __throw_type_match (void *catch_type, void *throw_type, void *obj)
3028 {
3029 #if 0
3030  printf ("__throw_type_match (): catch_type = %s, throw_type = %s\n",
3031          catch_type, throw_type);
3032 #endif
3033  if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)
3034    return obj;
3035  return 0;
3036 }
3037
3038 void
3039 __empty ()
3040 {
3041 }
3042 \f
3043
3044 /* Include definitions of EH context and table layout */
3045
3046 #include "eh-common.h"
3047 #ifndef inhibit_libc
3048 #include <stdio.h>
3049 #endif
3050
3051 /* Allocate and return a new EH context structure. */
3052
3053 extern void __throw ();
3054
3055 static void *
3056 new_eh_context ()
3057 {
3058   struct eh_full_context {
3059     struct eh_context c;
3060     void *top_elt[2];
3061   } *ehfc = (struct eh_full_context *) malloc (sizeof *ehfc);
3062
3063   if (! ehfc)
3064     __terminate ();
3065
3066   memset (ehfc, 0, sizeof *ehfc);
3067
3068   ehfc->c.dynamic_handler_chain = (void **) ehfc->top_elt;
3069
3070   /* This should optimize out entirely.  This should always be true,
3071      but just in case it ever isn't, don't allow bogus code to be
3072      generated.  */
3073
3074   if ((void*)(&ehfc->c) != (void*)ehfc)
3075     __terminate ();
3076
3077   return &ehfc->c;
3078 }
3079
3080 #if __GTHREADS
3081 static __gthread_key_t eh_context_key;
3082
3083 /* Destructor for struct eh_context. */
3084 static void
3085 eh_context_free (void *ptr)
3086 {
3087   __gthread_key_dtor (eh_context_key, ptr);
3088   if (ptr)
3089     free (ptr);
3090 }
3091 #endif
3092
3093 /* Pointer to function to return EH context. */
3094
3095 static struct eh_context *eh_context_initialize ();
3096 static struct eh_context *eh_context_static ();
3097 #if __GTHREADS
3098 static struct eh_context *eh_context_specific ();
3099 #endif
3100
3101 static struct eh_context *(*get_eh_context) () = &eh_context_initialize;
3102
3103 /* Routine to get EH context.
3104    This one will simply call the function pointer. */
3105
3106 void *
3107 __get_eh_context ()
3108 {
3109   return (void *) (*get_eh_context) ();
3110 }
3111
3112 /* Get and set the language specific info pointer. */
3113
3114 void **
3115 __get_eh_info ()
3116 {
3117   struct eh_context *eh = (*get_eh_context) ();
3118   return &eh->info;
3119 }
3120 \f
3121 #if __GTHREADS
3122 static void
3123 eh_threads_initialize ()
3124 {
3125   /* Try to create the key.  If it fails, revert to static method,
3126      otherwise start using thread specific EH contexts. */
3127   if (__gthread_key_create (&eh_context_key, &eh_context_free) == 0)
3128     get_eh_context = &eh_context_specific;
3129   else
3130     get_eh_context = &eh_context_static;
3131 }
3132 #endif /* no __GTHREADS */
3133
3134 /* Initialize EH context.
3135    This will be called only once, since we change GET_EH_CONTEXT
3136    pointer to another routine. */
3137
3138 static struct eh_context *
3139 eh_context_initialize ()
3140 {
3141 #if __GTHREADS
3142
3143   static __gthread_once_t once = __GTHREAD_ONCE_INIT;
3144   /* Make sure that get_eh_context does not point to us anymore.
3145      Some systems have dummy thread routines in their libc that
3146      return a success (Solaris 2.6 for example). */
3147   if (__gthread_once (&once, eh_threads_initialize) != 0
3148       || get_eh_context == &eh_context_initialize)
3149     {
3150       /* Use static version of EH context. */
3151       get_eh_context = &eh_context_static;
3152     }
3153
3154 #else /* no __GTHREADS */
3155
3156   /* Use static version of EH context. */
3157   get_eh_context = &eh_context_static;
3158
3159 #endif /* no __GTHREADS */
3160
3161   return (*get_eh_context) ();
3162 }
3163
3164 /* Return a static EH context. */
3165
3166 static struct eh_context *
3167 eh_context_static ()
3168 {
3169   static struct eh_context eh;
3170   static int initialized;
3171   static void *top_elt[2];
3172
3173   if (! initialized)
3174     {
3175       initialized = 1;
3176       memset (&eh, 0, sizeof eh);
3177       eh.dynamic_handler_chain = top_elt;
3178     }
3179   return &eh;
3180 }
3181
3182 #if __GTHREADS
3183 /* Return a thread specific EH context. */
3184
3185 static struct eh_context *
3186 eh_context_specific ()
3187 {
3188   struct eh_context *eh;
3189   eh = (struct eh_context *) __gthread_getspecific (eh_context_key);
3190   if (! eh)
3191     {
3192       eh = new_eh_context ();
3193       if (__gthread_setspecific (eh_context_key, (void *) eh) != 0)
3194         __terminate ();
3195     }
3196
3197   return eh;
3198 }
3199 #endif __GTHREADS
3200 \f
3201 /* Support routines for setjmp/longjmp exception handling.  */
3202
3203 /* Calls to __sjthrow are generated by the compiler when an exception
3204    is raised when using the setjmp/longjmp exception handling codegen
3205    method.  */
3206
3207 #ifdef DONT_USE_BUILTIN_SETJMP
3208 extern void longjmp (void *, int);
3209 #endif
3210
3211 /* Routine to get the head of the current thread's dynamic handler chain
3212    use for exception handling. */
3213
3214 void ***
3215 __get_dynamic_handler_chain ()
3216 {
3217   struct eh_context *eh = (*get_eh_context) ();
3218   return &eh->dynamic_handler_chain;
3219 }
3220
3221 /* This is used to throw an exception when the setjmp/longjmp codegen
3222    method is used for exception handling.
3223
3224    We call __terminate if there are no handlers left.  Otherwise we run the
3225    cleanup actions off the dynamic cleanup stack, and pop the top of the
3226    dynamic handler chain, and use longjmp to transfer back to the associated
3227    handler.  */
3228
3229 extern void __sjthrow (void) __attribute__ ((__noreturn__));
3230
3231 void
3232 __sjthrow ()
3233 {
3234   struct eh_context *eh = (*get_eh_context) ();
3235   void ***dhc = &eh->dynamic_handler_chain;
3236   void *jmpbuf;
3237   void (*func)(void *, int);
3238   void *arg;
3239   void ***cleanup;
3240
3241   /* The cleanup chain is one word into the buffer.  Get the cleanup
3242      chain.  */
3243   cleanup = (void***)&(*dhc)[1];
3244
3245   /* If there are any cleanups in the chain, run them now.  */
3246   if (cleanup[0])
3247     {
3248       double store[200];
3249       void **buf = (void**)store;
3250       buf[1] = 0;
3251       buf[0] = (*dhc);
3252
3253       /* try { */
3254 #ifdef DONT_USE_BUILTIN_SETJMP
3255       if (! setjmp (&buf[2]))
3256 #else
3257       if (! __builtin_setjmp (&buf[2]))
3258 #endif
3259         {
3260           *dhc = buf;
3261           while (cleanup[0])
3262             {
3263               func = (void(*)(void*, int))cleanup[0][1];
3264               arg = (void*)cleanup[0][2];
3265
3266               /* Update this before running the cleanup.  */
3267               cleanup[0] = (void **)cleanup[0][0];
3268
3269               (*func)(arg, 2);
3270             }
3271           *dhc = buf[0];
3272         }
3273       /* catch (...) */
3274       else
3275         {
3276           __terminate ();
3277         }
3278     }
3279   
3280   /* We must call terminate if we try and rethrow an exception, when
3281      there is no exception currently active and when there are no
3282      handlers left.  */
3283   if (! eh->info || (*dhc)[0] == 0)
3284     __terminate ();
3285     
3286   /* Find the jmpbuf associated with the top element of the dynamic
3287      handler chain.  The jumpbuf starts two words into the buffer.  */
3288   jmpbuf = &(*dhc)[2];
3289
3290   /* Then we pop the top element off the dynamic handler chain.  */
3291   *dhc = (void**)(*dhc)[0];
3292
3293   /* And then we jump to the handler.  */
3294
3295 #ifdef DONT_USE_BUILTIN_SETJMP
3296   longjmp (jmpbuf, 1);
3297 #else
3298   __builtin_longjmp (jmpbuf, 1);
3299 #endif
3300 }
3301
3302 /* Run cleanups on the dynamic cleanup stack for the current dynamic
3303    handler, then pop the handler off the dynamic handler stack, and
3304    then throw.  This is used to skip the first handler, and transfer
3305    control to the next handler in the dynamic handler stack.  */
3306
3307 extern void __sjpopnthrow (void) __attribute__ ((__noreturn__));
3308
3309 void
3310 __sjpopnthrow ()
3311 {
3312   struct eh_context *eh = (*get_eh_context) ();
3313   void ***dhc = &eh->dynamic_handler_chain;
3314   void (*func)(void *, int);
3315   void *arg;
3316   void ***cleanup;
3317
3318   /* The cleanup chain is one word into the buffer.  Get the cleanup
3319      chain.  */
3320   cleanup = (void***)&(*dhc)[1];
3321
3322   /* If there are any cleanups in the chain, run them now.  */
3323   if (cleanup[0])
3324     {
3325       double store[200];
3326       void **buf = (void**)store;
3327       buf[1] = 0;
3328       buf[0] = (*dhc);
3329
3330       /* try { */
3331 #ifdef DONT_USE_BUILTIN_SETJMP
3332       if (! setjmp (&buf[2]))
3333 #else
3334       if (! __builtin_setjmp (&buf[2]))
3335 #endif
3336         {
3337           *dhc = buf;
3338           while (cleanup[0])
3339             {
3340               func = (void(*)(void*, int))cleanup[0][1];
3341               arg = (void*)cleanup[0][2];
3342
3343               /* Update this before running the cleanup.  */
3344               cleanup[0] = (void **)cleanup[0][0];
3345
3346               (*func)(arg, 2);
3347             }
3348           *dhc = buf[0];
3349         }
3350       /* catch (...) */
3351       else
3352         {
3353           __terminate ();
3354         }
3355     }
3356
3357   /* Then we pop the top element off the dynamic handler chain.  */
3358   *dhc = (void**)(*dhc)[0];
3359
3360   __sjthrow ();
3361 }
3362 \f
3363 /* Support code for all exception region-based exception handling.  */
3364
3365 int
3366 __eh_rtime_match (void *rtime)
3367 {
3368   void *info;
3369   __eh_matcher matcher;
3370   void *ret;
3371
3372   info = *(__get_eh_info ());
3373   matcher = ((__eh_info *)info)->match_function;
3374   if (! matcher)
3375     {
3376 #ifndef inhibit_libc
3377       fprintf (stderr, "Internal Compiler Bug: No runtime type matcher.");
3378 #endif
3379       return 0;
3380     }
3381   ret = (*matcher) (info, rtime, (void *)0);
3382   return (ret != NULL);
3383 }
3384
3385 /* This value identifies the place from which an exception is being
3386    thrown.  */
3387
3388 #ifdef EH_TABLE_LOOKUP
3389
3390 EH_TABLE_LOOKUP
3391
3392 #else
3393
3394 #ifdef DWARF2_UNWIND_INFO
3395
3396
3397 /* Return the table version of an exception descriptor */
3398
3399 short 
3400 __get_eh_table_version (exception_descriptor *table) 
3401 {
3402   return table->lang.version;
3403 }
3404
3405 /* Return the originating table language of an exception descriptor */
3406
3407 short 
3408 __get_eh_table_language (exception_descriptor *table)
3409 {
3410   return table->lang.language;
3411 }
3412
3413 /* This routine takes a PC and a pointer to the exception region TABLE for
3414    its translation unit, and returns the address of the exception handler
3415    associated with the closest exception table handler entry associated
3416    with that PC, or 0 if there are no table entries the PC fits in.
3417
3418    In the advent of a tie, we have to give the last entry, as it represents
3419    an inner block.  */
3420
3421 static void *
3422 old_find_exception_handler (void *pc, old_exception_table *table)
3423 {
3424   if (table)
3425     {
3426       int pos;
3427       int best = -1;
3428
3429       /* We can't do a binary search because the table isn't guaranteed
3430          to be sorted from function to function.  */
3431       for (pos = 0; table[pos].start_region != (void *) -1; ++pos)
3432         {
3433           if (table[pos].start_region <= pc && table[pos].end_region > pc)
3434             {
3435               /* This can apply.  Make sure it is at least as small as
3436                  the previous best.  */
3437               if (best == -1 || (table[pos].end_region <= table[best].end_region
3438                         && table[pos].start_region >= table[best].start_region))
3439                 best = pos;
3440             }
3441           /* But it is sorted by starting PC within a function.  */
3442           else if (best >= 0 && table[pos].start_region > pc)
3443             break;
3444         }
3445       if (best != -1)
3446         return table[best].exception_handler;
3447     }
3448
3449   return (void *) 0;
3450 }
3451
3452 /* find_exception_handler finds the correct handler, if there is one, to
3453    handle an exception.
3454    returns a pointer to the handler which controlled should be transferred
3455    to, or NULL if there is nothing left.
3456    Parameters:
3457    PC - pc where the exception originates. If this is a rethrow, 
3458         then this starts out as a pointer to the exception table
3459         entry we wish to rethrow out of.
3460    TABLE - exception table for the current module.
3461    EH_INFO - eh info pointer for this exception.
3462    RETHROW - 1 if this is a rethrow. (see incoming value of PC).
3463    CLEANUP - returned flag indicating whether this is a cleanup handler.
3464 */
3465 static void *
3466 find_exception_handler (void *pc, exception_descriptor *table, 
3467                         __eh_info *eh_info, int rethrow, int *cleanup)
3468 {
3469
3470   void *retval = NULL;
3471   *cleanup = 1;
3472   if (table)
3473     {
3474       int pos = 0;
3475       /* The new model assumed the table is sorted inner-most out so the
3476          first region we find which matches is the correct one */
3477
3478       exception_table *tab = &(table->table[0]);
3479
3480       /* Subtract 1 from the PC to avoid hitting the next region */
3481       if (rethrow) 
3482         {
3483           /* pc is actually the region table entry to rethrow out of */
3484           pos = ((exception_table *) pc) - tab;
3485           pc = ((exception_table *) pc)->end_region - 1;
3486
3487           /* The label is always on the LAST handler entry for a region, 
3488              so we know the next entry is a different region, even if the
3489              addresses are the same. Make sure its not end of table tho. */
3490           if (tab[pos].start_region != (void *) -1)
3491             pos++;
3492         }
3493       else
3494         pc--;
3495       
3496       /* We can't do a binary search because the table is in inner-most
3497          to outermost address ranges within functions */
3498       for ( ; tab[pos].start_region != (void *) -1; pos++)
3499         { 
3500           if (tab[pos].start_region <= pc && tab[pos].end_region > pc)
3501             {
3502               if (tab[pos].match_info)
3503                 {
3504                   __eh_matcher matcher = eh_info->match_function;
3505                   /* match info but no matcher is NOT a match */
3506                   if (matcher) 
3507                     {
3508                       void *ret = (*matcher)((void *) eh_info, 
3509                                              tab[pos].match_info, table);
3510                       if (ret) 
3511                         {
3512                           if (retval == NULL)
3513                             retval = tab[pos].exception_handler;
3514                           *cleanup = 0;
3515                           break;
3516                         }
3517                     }
3518                 }
3519               else
3520                 {
3521                   if (retval == NULL)
3522                     retval = tab[pos].exception_handler;
3523                 }
3524             }
3525         }
3526     }
3527   return retval;
3528 }
3529 #endif /* DWARF2_UNWIND_INFO */
3530 #endif /* EH_TABLE_LOOKUP */
3531 \f
3532 #ifdef DWARF2_UNWIND_INFO
3533 /* Support code for exception handling using static unwind information.  */
3534
3535 #include "frame.h"
3536
3537 /* This type is used in get_reg and put_reg to deal with ABIs where a void*
3538    is smaller than a word, such as the Irix 6 n32 ABI.  We cast twice to
3539    avoid a warning about casting between int and pointer of different
3540    sizes.  */
3541
3542 typedef int ptr_type __attribute__ ((mode (pointer)));
3543
3544 #ifdef INCOMING_REGNO
3545 /* Is the saved value for register REG in frame UDATA stored in a register
3546    window in the previous frame?  */
3547
3548 /* ??? The Sparc INCOMING_REGNO references TARGET_FLAT.  This allows us
3549    to use the macro here.  One wonders, though, that perhaps TARGET_FLAT
3550    compiled functions won't work with the frame-unwind stuff here.  
3551    Perhaps the entireity of in_reg_window should be conditional on having
3552    seen a DW_CFA_GNU_window_save?  */
3553 #define target_flags 0
3554
3555 static int
3556 in_reg_window (int reg, frame_state *udata)
3557 {
3558   if (udata->saved[reg] == REG_SAVED_REG)
3559     return INCOMING_REGNO (reg) == reg;
3560   if (udata->saved[reg] != REG_SAVED_OFFSET)
3561     return 0;
3562
3563 #ifdef STACK_GROWS_DOWNWARD
3564   return udata->reg_or_offset[reg] > 0;
3565 #else
3566   return udata->reg_or_offset[reg] < 0;
3567 #endif
3568 }
3569 #else
3570 static inline int in_reg_window (int reg, frame_state *udata) { return 0; }
3571 #endif /* INCOMING_REGNO */
3572
3573 /* Get the address of register REG as saved in UDATA, where SUB_UDATA is a
3574    frame called by UDATA or 0.  */
3575
3576 static word_type *
3577 get_reg_addr (unsigned reg, frame_state *udata, frame_state *sub_udata)
3578 {
3579   while (udata->saved[reg] == REG_SAVED_REG)
3580     {
3581       reg = udata->reg_or_offset[reg];
3582       if (in_reg_window (reg, udata))
3583         {
3584           udata = sub_udata;
3585           sub_udata = NULL;
3586         }
3587     }
3588   if (udata->saved[reg] == REG_SAVED_OFFSET)
3589     return (word_type *)(udata->cfa + udata->reg_or_offset[reg]);
3590   else
3591     abort ();
3592 }
3593
3594 /* Get the value of register REG as saved in UDATA, where SUB_UDATA is a
3595    frame called by UDATA or 0.  */
3596
3597 static inline void *
3598 get_reg (unsigned reg, frame_state *udata, frame_state *sub_udata)
3599 {
3600   return (void *)(ptr_type) *get_reg_addr (reg, udata, sub_udata);
3601 }
3602
3603 /* Overwrite the saved value for register REG in frame UDATA with VAL.  */
3604
3605 static inline void
3606 put_reg (unsigned reg, void *val, frame_state *udata)
3607 {
3608   *get_reg_addr (reg, udata, NULL) = (word_type)(ptr_type) val;
3609 }
3610
3611 /* Copy the saved value for register REG from frame UDATA to frame
3612    TARGET_UDATA.  Unlike the previous two functions, this can handle
3613    registers that are not one word large.  */
3614
3615 static void
3616 copy_reg (unsigned reg, frame_state *udata, frame_state *target_udata)
3617 {
3618   word_type *preg = get_reg_addr (reg, udata, NULL);
3619   word_type *ptreg = get_reg_addr (reg, target_udata, NULL);
3620
3621   memcpy (ptreg, preg, __builtin_dwarf_reg_size (reg));
3622 }
3623
3624 /* Retrieve the return address for frame UDATA.  */
3625
3626 static inline void *
3627 get_return_addr (frame_state *udata, frame_state *sub_udata)
3628 {
3629   return __builtin_extract_return_addr
3630     (get_reg (udata->retaddr_column, udata, sub_udata));
3631 }
3632
3633 /* Overwrite the return address for frame UDATA with VAL.  */
3634
3635 static inline void
3636 put_return_addr (void *val, frame_state *udata)
3637 {
3638   val = __builtin_frob_return_addr (val);
3639   put_reg (udata->retaddr_column, val, udata);
3640 }
3641
3642 /* Given the current frame UDATA and its return address PC, return the
3643    information about the calling frame in CALLER_UDATA.  */
3644
3645 static void *
3646 next_stack_level (void *pc, frame_state *udata, frame_state *caller_udata)
3647 {
3648   caller_udata = __frame_state_for (pc, caller_udata);
3649   if (! caller_udata)
3650     return 0;
3651
3652   /* Now go back to our caller's stack frame.  If our caller's CFA register
3653      was saved in our stack frame, restore it; otherwise, assume the CFA
3654      register is SP and restore it to our CFA value.  */
3655   if (udata->saved[caller_udata->cfa_reg])
3656     caller_udata->cfa = get_reg (caller_udata->cfa_reg, udata, 0);
3657   else
3658     caller_udata->cfa = udata->cfa;
3659   caller_udata->cfa += caller_udata->cfa_offset;
3660
3661   return caller_udata;
3662 }
3663
3664 /* Hook to call before __terminate if only cleanup handlers remain. */
3665 void 
3666 __unwinding_cleanup ()
3667 {
3668 }
3669
3670 /* throw_helper performs some of the common grunt work for a throw. This
3671    routine is called by throw and rethrows. This is pretty much split 
3672    out from the old __throw routine. An addition has been added which allows
3673    for a dummy call to a routine __unwinding_cleanup() when there are nothing
3674    but cleanups remaining. This allows a debugger to examine the state
3675    at which the throw was executed, before any cleanups, rather than
3676    at the terminate point after the stack has been unwound.
3677
3678    EH is the current eh_context structure.
3679    PC is the address of the call to __throw.
3680    MY_UDATA is the unwind information for __throw.
3681    OFFSET_P is where we return the SP adjustment offset.  */
3682
3683 static void *
3684 throw_helper (eh, pc, my_udata, offset_p)
3685      struct eh_context *eh;
3686      void *pc;
3687      frame_state *my_udata;
3688      long *offset_p;
3689 {
3690   frame_state ustruct2, *udata = &ustruct2;
3691   frame_state ustruct;
3692   frame_state *sub_udata = &ustruct;
3693   void *saved_pc = pc;
3694   void *handler;
3695   void *handler_p;
3696   void *pc_p;
3697   frame_state saved_ustruct;
3698   int new_eh_model;
3699   int cleanup = 0;
3700   int only_cleanup = 0;
3701   int rethrow = 0;
3702   int saved_state = 0;
3703   long args_size;
3704   __eh_info *eh_info = (__eh_info *)eh->info;
3705
3706   /* Do we find a handler based on a re-throw PC? */
3707   if (eh->table_index != (void *) 0)
3708     rethrow = 1;
3709
3710   memcpy (udata, my_udata, sizeof (*udata));
3711
3712   handler = (void *) 0;
3713   for (;;)
3714     { 
3715       frame_state *p = udata;
3716       udata = next_stack_level (pc, udata, sub_udata);
3717       sub_udata = p;
3718
3719       /* If we couldn't find the next frame, we lose.  */
3720       if (! udata)
3721         break;
3722
3723       if (udata->eh_ptr == NULL)
3724         new_eh_model = 0;
3725       else
3726         new_eh_model = (((exception_descriptor *)(udata->eh_ptr))->
3727                                           runtime_id_field == NEW_EH_RUNTIME);
3728
3729       if (rethrow) 
3730         {
3731           rethrow = 0;
3732           handler = find_exception_handler (eh->table_index, udata->eh_ptr, 
3733                                           eh_info, 1, &cleanup);
3734           eh->table_index = (void *)0;
3735         }
3736       else
3737         if (new_eh_model)
3738           handler = find_exception_handler (pc, udata->eh_ptr, eh_info, 
3739                                             0, &cleanup);
3740         else
3741           handler = old_find_exception_handler (pc, udata->eh_ptr);
3742
3743       /* If we found one, we can stop searching, if its not a cleanup. 
3744          for cleanups, we save the state, and keep looking. This allows
3745          us to call a debug hook if there are nothing but cleanups left. */
3746       if (handler)
3747         {
3748           if (cleanup)
3749             {
3750               if (!saved_state)
3751                 {
3752                   saved_ustruct = *udata;
3753                   handler_p = handler;
3754                   pc_p = pc;
3755                   saved_state = 1;
3756                   only_cleanup = 1;
3757                 }
3758             }
3759           else
3760             {
3761               only_cleanup = 0;
3762               break;
3763             }
3764         }
3765
3766       /* Otherwise, we continue searching.  We subtract 1 from PC to avoid
3767          hitting the beginning of the next region.  */
3768       pc = get_return_addr (udata, sub_udata) - 1;
3769     }
3770
3771   if (saved_state) 
3772     {
3773       udata = &saved_ustruct;
3774       handler = handler_p;
3775       pc = pc_p;
3776       if (only_cleanup)
3777         __unwinding_cleanup ();
3778     }
3779
3780   /* If we haven't found a handler by now, this is an unhandled
3781      exception.  */
3782   if (! handler) 
3783     __terminate();
3784
3785   eh->handler_label = handler;
3786
3787   args_size = udata->args_size;
3788
3789   if (pc == saved_pc)
3790     /* We found a handler in the throw context, no need to unwind.  */
3791     udata = my_udata;
3792   else
3793     {
3794       int i;
3795
3796       /* Unwind all the frames between this one and the handler by copying
3797          their saved register values into our register save slots.  */
3798
3799       /* Remember the PC where we found the handler.  */
3800       void *handler_pc = pc;
3801
3802       /* Start from the throw context again.  */
3803       pc = saved_pc;
3804       memcpy (udata, my_udata, sizeof (*udata));
3805
3806       while (pc != handler_pc)
3807         {
3808           frame_state *p = udata;
3809           udata = next_stack_level (pc, udata, sub_udata);
3810           sub_udata = p;
3811
3812           for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
3813             if (i != udata->retaddr_column && udata->saved[i])
3814               {
3815                 /* If you modify the saved value of the return address
3816                    register on the SPARC, you modify the return address for
3817                    your caller's frame.  Don't do that here, as it will
3818                    confuse get_return_addr.  */
3819                 if (in_reg_window (i, udata)
3820                     && udata->saved[udata->retaddr_column] == REG_SAVED_REG
3821                     && udata->reg_or_offset[udata->retaddr_column] == i)
3822                   continue;
3823                 copy_reg (i, udata, my_udata);
3824               }
3825
3826           pc = get_return_addr (udata, sub_udata) - 1;
3827         }
3828
3829       /* But we do need to update the saved return address register from
3830          the last frame we unwind, or the handler frame will have the wrong
3831          return address.  */
3832       if (udata->saved[udata->retaddr_column] == REG_SAVED_REG)
3833         {
3834           i = udata->reg_or_offset[udata->retaddr_column];
3835           if (in_reg_window (i, udata))
3836             copy_reg (i, udata, my_udata);
3837         }
3838     }
3839   /* udata now refers to the frame called by the handler frame.  */
3840
3841   /* We adjust SP by the difference between __throw's CFA and the CFA for
3842      the frame called by the handler frame, because those CFAs correspond
3843      to the SP values at the two call sites.  We need to further adjust by
3844      the args_size of the handler frame itself to get the handler frame's
3845      SP from before the args were pushed for that call.  */
3846 #ifdef STACK_GROWS_DOWNWARD
3847   *offset_p = udata->cfa - my_udata->cfa + args_size;
3848 #else
3849   *offset_p = my_udata->cfa - udata->cfa - args_size;
3850 #endif
3851                        
3852   return handler;
3853 }
3854
3855
3856 /* We first search for an exception handler, and if we don't find
3857    it, we call __terminate on the current stack frame so that we may
3858    use the debugger to walk the stack and understand why no handler
3859    was found.
3860
3861    If we find one, then we unwind the frames down to the one that
3862    has the handler and transfer control into the handler.  */
3863
3864 /*extern void __throw(void) __attribute__ ((__noreturn__));*/
3865
3866 void
3867 __throw ()
3868 {
3869   struct eh_context *eh = (*get_eh_context) ();
3870   void *pc, *handler;
3871   long offset;
3872
3873   /* XXX maybe make my_ustruct static so we don't have to look it up for
3874      each throw.  */
3875   frame_state my_ustruct, *my_udata = &my_ustruct;
3876
3877   /* This is required for C++ semantics.  We must call terminate if we
3878      try and rethrow an exception, when there is no exception currently
3879      active.  */
3880   if (! eh->info)
3881     __terminate ();
3882     
3883   /* Start at our stack frame.  */
3884 label:
3885   my_udata = __frame_state_for (&&label, my_udata);
3886   if (! my_udata)
3887     __terminate ();
3888
3889   /* We need to get the value from the CFA register. */
3890   my_udata->cfa = __builtin_dwarf_cfa ();
3891
3892   /* Do any necessary initialization to access arbitrary stack frames.
3893      On the SPARC, this means flushing the register windows.  */
3894   __builtin_unwind_init ();
3895
3896   /* Now reset pc to the right throw point.  */
3897   pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
3898
3899   handler = throw_helper (eh, pc, my_udata, &offset);
3900
3901   /* Now go!  */
3902
3903   __builtin_eh_return ((void *)eh, offset, handler);
3904
3905   /* Epilogue:  restore the handler frame's register values and return
3906      to the stub.  */
3907 }
3908
3909 /*extern void __rethrow(void *) __attribute__ ((__noreturn__));*/
3910
3911 void
3912 __rethrow (index)
3913      void *index;
3914 {
3915   struct eh_context *eh = (*get_eh_context) ();
3916   void *pc, *handler;
3917   long offset;
3918
3919   /* XXX maybe make my_ustruct static so we don't have to look it up for
3920      each throw.  */
3921   frame_state my_ustruct, *my_udata = &my_ustruct;
3922
3923   /* This is required for C++ semantics.  We must call terminate if we
3924      try and rethrow an exception, when there is no exception currently
3925      active.  */
3926   if (! eh->info)
3927     __terminate ();
3928
3929   /* This is the table index we want to rethrow from. The value of
3930      the END_REGION label is used for the PC of the throw, and the
3931      search begins with the next table entry. */
3932   eh->table_index = index;
3933     
3934   /* Start at our stack frame.  */
3935 label:
3936   my_udata = __frame_state_for (&&label, my_udata);
3937   if (! my_udata)
3938     __terminate ();
3939
3940   /* We need to get the value from the CFA register. */
3941   my_udata->cfa = __builtin_dwarf_cfa ();
3942
3943   /* Do any necessary initialization to access arbitrary stack frames.
3944      On the SPARC, this means flushing the register windows.  */
3945   __builtin_unwind_init ();
3946
3947   /* Now reset pc to the right throw point.  */
3948   pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
3949
3950   handler = throw_helper (eh, pc, my_udata, &offset);
3951
3952   /* Now go!  */
3953
3954   __builtin_eh_return ((void *)eh, offset, handler);
3955
3956   /* Epilogue:  restore the handler frame's register values and return
3957      to the stub.  */
3958 }
3959 #endif /* DWARF2_UNWIND_INFO */
3960
3961 #endif /* L_eh */
3962 \f
3963 #ifdef L_pure
3964 #ifndef inhibit_libc
3965 /* This gets us __GNU_LIBRARY__.  */
3966 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
3967 #include <stdio.h>
3968
3969 #ifdef __GNU_LIBRARY__
3970   /* Avoid forcing the library's meaning of `write' on the user program
3971      by using the "internal" name (for use within the library)  */
3972 #define write(fd, buf, n)       __write((fd), (buf), (n))
3973 #endif
3974 #endif /* inhibit_libc */
3975
3976 #define MESSAGE "pure virtual method called\n"
3977
3978 void
3979 __pure_virtual ()
3980 {
3981 #ifndef inhibit_libc
3982   write (2, MESSAGE, sizeof (MESSAGE) - 1);
3983 #endif
3984   __terminate ();
3985 }
3986 #endif