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