OSDN Git Service

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