OSDN Git Service

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