OSDN Git Service

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