OSDN Git Service

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