OSDN Git Service

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