OSDN Git Service

Merge from gcc-2.8
[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
1450 static struct bb *bb_head;
1451
1452 /* Return the number of digits needed to print a value */
1453 /* __inline__ */ static int num_digits (long value, int base)
1454 {
1455   int minus = (value < 0 && base != 16);
1456   unsigned long v = (minus) ? -value : value;
1457   int ret = minus;
1458
1459   do
1460     {
1461       v /= base;
1462       ret++;
1463     }
1464   while (v);
1465
1466   return ret;
1467 }
1468
1469 void
1470 __bb_exit_func (void)
1471 {
1472   FILE *da_file, *file;
1473   long time_value;
1474   int i;
1475
1476   if (bb_head == 0)
1477     return;
1478
1479   i = strlen (bb_head->filename) - 3;
1480
1481   if (!strcmp (bb_head->filename+i, ".da"))
1482     {
1483       /* Must be -fprofile-arcs not -a.
1484          Dump data in a form that gcov expects.  */
1485
1486       struct bb *ptr;
1487
1488       for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1489         {
1490           /* If the file exists, and the number of counts in it is the same,
1491              then merge them in.  */
1492              
1493           if ((da_file = fopen (ptr->filename, "r")) != 0)
1494             {
1495               long n_counts = 0;
1496               unsigned char tmp;
1497               int i;
1498               int ret = 0;
1499
1500               
1501               if (__read_long (&n_counts, da_file, 8) != 0)
1502                 {
1503                   fprintf (stderr, "arc profiling: Can't read output file %s.\n",
1504                            ptr->filename);
1505                   continue;
1506                 }
1507
1508               if (n_counts == ptr->ncounts)
1509                 {
1510                   int i;
1511
1512                   for (i = 0; i < n_counts; i++)
1513                     {
1514                       long v = 0;
1515                       unsigned char tmp;
1516                       int j;
1517                       int ret = 0;
1518
1519                       if (__read_long (&v, da_file, 8) != 0)
1520                         {
1521                           fprintf (stderr, "arc profiling: Can't read output file %s.\n",
1522                                    ptr->filename);
1523                           break;
1524                         }
1525                       ptr->counts[i] += v;
1526                     }
1527                 }
1528
1529               if (fclose (da_file) == EOF)
1530                 fprintf (stderr, "arc profiling: Error closing output file %s.\n",
1531                          ptr->filename);
1532             }
1533           if ((da_file = fopen (ptr->filename, "w")) < 0)
1534             {
1535               fprintf (stderr, "arc profiling: Can't open output file %s.\n",
1536                        ptr->filename);
1537               continue;
1538             }
1539
1540           /* ??? Should first write a header to the file.  Preferably, a 4 byte
1541              magic number, 4 bytes containing the time the program was
1542              compiled, 4 bytes containing the last modification time of the
1543              source file, and 4 bytes indicating the compiler options used.
1544
1545              That way we can easily verify that the proper source/executable/
1546              data file combination is being used from gcov.  */
1547
1548           if (__write_long (ptr->ncounts, da_file, 8) != 0)
1549             {
1550               
1551               fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1552                        ptr->filename);
1553             }
1554           else
1555             {
1556               int j;
1557               long *count_ptr = ptr->counts;
1558               int ret = 0;
1559               for (j = ptr->ncounts; j > 0; j--)
1560                 {
1561                   if (__write_long (*count_ptr, da_file, 8) != 0)
1562                     {
1563                       ret=1;
1564                       break;
1565                     }
1566                   count_ptr++;
1567                 }
1568               if (ret)
1569                 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1570                          ptr->filename);
1571             }
1572           
1573           if (fclose (da_file) == EOF)
1574             fprintf (stderr, "arc profiling: Error closing output file %s.\n",
1575                      ptr->filename);
1576         }
1577
1578       return;
1579     }
1580
1581   /* Must be basic block profiling.  Emit a human readable output file.  */
1582
1583   file = fopen ("bb.out", "a");
1584
1585   if (!file)
1586     perror ("bb.out");
1587
1588   else
1589     {
1590       struct bb *ptr;
1591
1592       /* This is somewhat type incorrect, but it avoids worrying about
1593          exactly where time.h is included from.  It should be ok unless
1594          a void * differs from other pointer formats, or if sizeof (long)
1595          is < sizeof (time_t).  It would be nice if we could assume the
1596          use of rationale standards here.  */
1597
1598       time ((void *) &time_value);
1599       fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value));
1600
1601       /* We check the length field explicitly in order to allow compatibility
1602          with older GCC's which did not provide it.  */
1603
1604       for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1605         {
1606           int i;
1607           int func_p    = (ptr->nwords >= sizeof (struct bb)
1608                            && ptr->nwords <= 1000
1609                            && ptr->functions);
1610           int line_p    = (func_p && ptr->line_nums);
1611           int file_p    = (func_p && ptr->filenames);
1612           int addr_p    = (ptr->addresses != 0);
1613           long ncounts  = ptr->ncounts;
1614           long cnt_max  = 0;
1615           long line_max = 0;
1616           long addr_max = 0;
1617           int file_len  = 0;
1618           int func_len  = 0;
1619           int blk_len   = num_digits (ncounts, 10);
1620           int cnt_len;
1621           int line_len;
1622           int addr_len;
1623
1624           fprintf (file, "File %s, %ld basic blocks \n\n",
1625                    ptr->filename, ncounts);
1626
1627           /* Get max values for each field.  */
1628           for (i = 0; i < ncounts; i++)
1629             {
1630               const char *p;
1631               int len;
1632
1633               if (cnt_max < ptr->counts[i])
1634                 cnt_max = ptr->counts[i];
1635
1636               if (addr_p && addr_max < ptr->addresses[i])
1637                 addr_max = ptr->addresses[i];
1638
1639               if (line_p && line_max < ptr->line_nums[i])
1640                 line_max = ptr->line_nums[i];
1641
1642               if (func_p)
1643                 {
1644                   p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>";
1645                   len = strlen (p);
1646                   if (func_len < len)
1647                     func_len = len;
1648                 }
1649
1650               if (file_p)
1651                 {
1652                   p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>";
1653                   len = strlen (p);
1654                   if (file_len < len)
1655                     file_len = len;
1656                 }
1657             }
1658
1659           addr_len = num_digits (addr_max, 16);
1660           cnt_len  = num_digits (cnt_max, 10);
1661           line_len = num_digits (line_max, 10);
1662
1663           /* Now print out the basic block information.  */
1664           for (i = 0; i < ncounts; i++)
1665             {
1666               fprintf (file,
1667                        "    Block #%*d: executed %*ld time(s)",
1668                        blk_len, i+1,
1669                        cnt_len, ptr->counts[i]);
1670
1671               if (addr_p)
1672                 fprintf (file, " address= 0x%.*lx", addr_len,
1673                          ptr->addresses[i]);
1674
1675               if (func_p)
1676                 fprintf (file, " function= %-*s", func_len,
1677                          (ptr->functions[i]) ? ptr->functions[i] : "<none>");
1678
1679               if (line_p)
1680                 fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]);
1681
1682               if (file_p)
1683                 fprintf (file, " file= %s",
1684                          (ptr->filenames[i]) ? ptr->filenames[i] : "<none>");
1685
1686               fprintf (file, "\n");
1687             }
1688
1689           fprintf (file, "\n");
1690           fflush (file);
1691         }
1692
1693       fprintf (file, "\n\n");
1694       fclose (file);
1695     }
1696 }
1697
1698 void
1699 __bb_init_func (struct bb *blocks)
1700 {
1701   /* User is supposed to check whether the first word is non-0,
1702      but just in case....  */
1703
1704   if (blocks->zero_word)
1705     return;
1706
1707 #ifdef ON_EXIT
1708   /* Initialize destructor.  */
1709   if (!bb_head)
1710     ON_EXIT (__bb_exit_func, 0);
1711 #endif
1712
1713   /* Set up linked list.  */
1714   blocks->zero_word = 1;
1715   blocks->next = bb_head;
1716   bb_head = blocks;
1717 }
1718
1719 #ifndef MACHINE_STATE_SAVE
1720 #define MACHINE_STATE_SAVE(ID)
1721 #endif
1722 #ifndef MACHINE_STATE_RESTORE
1723 #define MACHINE_STATE_RESTORE(ID)
1724 #endif
1725
1726 #include <string.h>
1727
1728 /* Number of buckets in hashtable of basic block addresses.  */
1729
1730 #define BB_BUCKETS 311
1731
1732 /* Maximum length of string in file bb.in.  */
1733
1734 #define BBINBUFSIZE 500
1735
1736 /* BBINBUFSIZE-1 with double quotes. We could use #BBINBUFSIZE or
1737    "BBINBUFSIZE" but want to avoid trouble with preprocessors.  */
1738
1739 #define BBINBUFSIZESTR "499"
1740
1741 struct bb_edge
1742 {
1743   struct bb_edge *next;
1744   unsigned long src_addr;
1745   unsigned long dst_addr;
1746   unsigned long count;
1747 };
1748
1749 enum bb_func_mode
1750 {
1751   TRACE_KEEP = 0, TRACE_ON = 1, TRACE_OFF = 2
1752 };
1753
1754 struct bb_func
1755 {
1756   struct bb_func *next;
1757   char *funcname;
1758   char *filename;
1759   enum bb_func_mode mode;
1760 };
1761
1762 /* This is the connection to the outside world.
1763    The BLOCK_PROFILER macro must set __bb.blocks
1764    and __bb.blockno.  */
1765
1766 struct {
1767   unsigned long blockno;
1768   struct bb *blocks;
1769 } __bb;
1770
1771 /* Vars to store addrs of source and destination basic blocks 
1772    of a jump.  */
1773
1774 static unsigned long bb_src = 0;
1775 static unsigned long bb_dst = 0;
1776
1777 static FILE *bb_tracefile = (FILE *) 0;
1778 static struct bb_edge **bb_hashbuckets = (struct bb_edge **) 0;
1779 static struct bb_func *bb_func_head = (struct bb_func *) 0;
1780 static unsigned long bb_callcount = 0;
1781 static int bb_mode = 0;
1782
1783 static unsigned long *bb_stack = (unsigned long *) 0;
1784 static size_t bb_stacksize = 0;
1785
1786 static int reported = 0;
1787
1788 /* Trace modes:
1789 Always             :   Print execution frequencies of basic blocks
1790                        to file bb.out.
1791 bb_mode & 1 != 0   :   Dump trace of basic blocks to file bbtrace[.gz]
1792 bb_mode & 2 != 0   :   Print jump frequencies to file bb.out.
1793 bb_mode & 4 != 0   :   Cut call instructions from basic block flow.
1794 bb_mode & 8 != 0   :   Insert return instructions in basic block flow.
1795 */
1796
1797 #ifdef HAVE_POPEN
1798
1799 /*#include <sys/types.h>*/
1800 #include <sys/stat.h>
1801 /*#include <malloc.h>*/
1802
1803 /* Commands executed by gopen.  */
1804
1805 #define GOPENDECOMPRESS "gzip -cd "
1806 #define GOPENCOMPRESS "gzip -c >"
1807
1808 /* Like fopen but pipes through gzip.  mode may only be "r" or "w".
1809    If it does not compile, simply replace gopen by fopen and delete
1810    '.gz' from any first parameter to gopen.  */
1811
1812 static FILE *
1813 gopen (char *fn, char *mode)
1814 {
1815   int use_gzip;
1816   char *p;
1817
1818   if (mode[1])
1819     return (FILE *) 0;
1820
1821   if (mode[0] != 'r' && mode[0] != 'w') 
1822     return (FILE *) 0;
1823
1824   p = fn + strlen (fn)-1;
1825   use_gzip = ((p[-1] == '.' && (p[0] == 'Z' || p[0] == 'z'))
1826               || (p[-2] == '.' && p[-1] == 'g' && p[0] == 'z'));
1827
1828   if (use_gzip)
1829     {
1830       if (mode[0]=='r')
1831         {
1832           FILE *f;
1833           char *s = (char *) malloc (sizeof (char) * strlen (fn)
1834                                      + sizeof (GOPENDECOMPRESS));
1835           strcpy (s, GOPENDECOMPRESS);
1836           strcpy (s + (sizeof (GOPENDECOMPRESS)-1), fn);
1837           f = popen (s, mode);
1838           free (s);
1839           return f;
1840         }
1841
1842       else
1843         {
1844           FILE *f;
1845           char *s = (char *) malloc (sizeof (char) * strlen (fn)
1846                                      + sizeof (GOPENCOMPRESS));
1847           strcpy (s, GOPENCOMPRESS);
1848           strcpy (s + (sizeof (GOPENCOMPRESS)-1), fn);
1849           if (!(f = popen (s, mode)))
1850             f = fopen (s, mode);
1851           free (s);
1852           return f;
1853         }
1854     }
1855
1856   else
1857     return fopen (fn, mode);
1858 }
1859
1860 static int
1861 gclose (FILE *f)
1862 {
1863   struct stat buf;
1864
1865   if (f != 0)
1866     {
1867       if (!fstat (fileno (f), &buf) && S_ISFIFO (buf.st_mode))
1868         return pclose (f);
1869
1870       return fclose (f);
1871     }
1872   return 0;
1873 }
1874
1875 #endif /* HAVE_POPEN */
1876
1877 /* Called once per program.  */
1878
1879 static void
1880 __bb_exit_trace_func ()
1881 {
1882   FILE *file = fopen ("bb.out", "a");
1883   struct bb_func *f;
1884   struct bb_edge *e;
1885   struct bb *b;
1886         
1887   if (!file)
1888     perror ("bb.out");
1889
1890   if (bb_mode & 1)
1891     {
1892       if (!bb_tracefile)
1893         perror ("bbtrace");
1894       else
1895 #ifdef HAVE_POPEN
1896         gclose (bb_tracefile);
1897 #else
1898         fclose (bb_tracefile);
1899 #endif /* HAVE_POPEN */
1900     }
1901
1902   /* Check functions in `bb.in'.  */
1903
1904   if (file)
1905     {
1906       long time_value;
1907       const struct bb_func *p;
1908       int printed_something = 0;
1909       struct bb *ptr;
1910       long blk;
1911
1912       /* This is somewhat type incorrect.  */
1913       time ((void *) &time_value);
1914
1915       for (p = bb_func_head; p != (struct bb_func *) 0; p = p->next)
1916         {
1917           for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1918             {
1919               if (!ptr->filename || p->filename != (char *) 0 && strcmp (p->filename, ptr->filename))
1920                 continue;
1921               for (blk = 0; blk < ptr->ncounts; blk++)
1922                 {
1923                   if (!strcmp (p->funcname, ptr->functions[blk]))
1924                     goto found;
1925                 }
1926             }
1927   
1928           if (!printed_something)
1929             {
1930               fprintf (file, "Functions in `bb.in' not executed during basic block profiling on %s\n", ctime ((void *) &time_value));
1931               printed_something = 1;
1932             }
1933
1934           fprintf (file, "\tFunction %s", p->funcname);
1935           if (p->filename)
1936               fprintf (file, " of file %s", p->filename);
1937           fprintf (file, "\n" );
1938   
1939 found:        ;
1940         }
1941
1942       if (printed_something)
1943        fprintf (file, "\n");
1944
1945     }
1946
1947   if (bb_mode & 2)
1948     {
1949       if (!bb_hashbuckets)
1950         {
1951           if (!reported)
1952             {
1953               fprintf (stderr, "Profiler: out of memory\n");
1954               reported = 1;
1955             }
1956           return;
1957         }
1958     
1959       else if (file)
1960         {
1961           long time_value;
1962           int i;
1963           unsigned long addr_max = 0;
1964           unsigned long cnt_max  = 0;
1965           int cnt_len;
1966           int addr_len;
1967     
1968           /* This is somewhat type incorrect, but it avoids worrying about
1969              exactly where time.h is included from.  It should be ok unless
1970              a void * differs from other pointer formats, or if sizeof (long)
1971              is < sizeof (time_t).  It would be nice if we could assume the
1972              use of rationale standards here.  */
1973     
1974           time ((void *) &time_value);
1975           fprintf (file, "Basic block jump tracing");
1976
1977           switch (bb_mode & 12)
1978             {
1979               case 0:
1980                 fprintf (file, " (with call)");
1981               break;
1982
1983               case 4:
1984                 /* Print nothing.  */
1985               break;
1986
1987               case 8:
1988                 fprintf (file, " (with call & ret)");
1989               break;
1990
1991               case 12:
1992                 fprintf (file, " (with ret)");
1993               break;
1994             }
1995
1996           fprintf (file, " finished on %s\n", ctime ((void *) &time_value));
1997     
1998           for (i = 0; i < BB_BUCKETS; i++)
1999             {
2000                struct bb_edge *bucket = bb_hashbuckets[i];
2001                for ( ; bucket; bucket = bucket->next )
2002                  {
2003                    if (addr_max < bucket->src_addr) 
2004                      addr_max = bucket->src_addr;
2005                    if (addr_max < bucket->dst_addr) 
2006                      addr_max = bucket->dst_addr;
2007                    if (cnt_max < bucket->count) 
2008                      cnt_max = bucket->count;
2009                  }
2010             }
2011           addr_len = num_digits (addr_max, 16);
2012           cnt_len  = num_digits (cnt_max, 10);
2013     
2014           for ( i = 0; i < BB_BUCKETS; i++)
2015             {
2016                struct bb_edge *bucket = bb_hashbuckets[i];
2017                for ( ; bucket; bucket = bucket->next )
2018                  {
2019                    fprintf (file, "Jump from block 0x%.*lx to "
2020                                   "block 0x%.*lx executed %*d time(s)\n", 
2021                             addr_len, bucket->src_addr, 
2022                             addr_len, bucket->dst_addr, 
2023                             cnt_len, bucket->count);
2024                  }
2025             }
2026   
2027           fprintf (file, "\n");
2028
2029         }
2030     }
2031
2032    if (file)
2033      fclose (file);
2034
2035    /* Free allocated memory.  */
2036
2037    f = bb_func_head;
2038    while (f)
2039      {
2040        struct bb_func *old = f;
2041
2042        f = f->next;
2043        if (old->funcname) free (old->funcname);
2044        if (old->filename) free (old->filename);
2045        free (old);
2046      }
2047
2048    if (bb_stack)
2049      free (bb_stack);
2050
2051    if (bb_hashbuckets)
2052      {
2053        int i;
2054
2055        for (i = 0; i < BB_BUCKETS; i++)
2056          {
2057            struct bb_edge *old, *bucket = bb_hashbuckets[i];
2058
2059            while (bucket)
2060              {
2061                old = bucket;
2062                bucket = bucket->next;
2063                free (old);
2064              }
2065          }
2066        free (bb_hashbuckets);
2067      }
2068
2069    for (b = bb_head; b; b = b->next)
2070      if (b->flags) free (b->flags);
2071 }
2072
2073 /* Called once per program.  */
2074
2075 static void
2076 __bb_init_prg ()
2077 {
2078
2079   FILE *file;
2080   char buf[BBINBUFSIZE];
2081   const char *p;
2082   const char *pos;
2083   enum bb_func_mode m;
2084
2085 #ifdef ON_EXIT
2086   /* Initialize destructor.  */
2087   ON_EXIT (__bb_exit_func, 0);
2088 #endif
2089
2090   if (!(file = fopen ("bb.in", "r")))
2091     return;
2092
2093   while(fscanf (file, " %" BBINBUFSIZESTR "s ", buf) != EOF)
2094     {
2095       p = buf;
2096       if (*p == '-') 
2097         { 
2098           m = TRACE_OFF; 
2099           p++; 
2100         }
2101       else 
2102         { 
2103           m = TRACE_ON; 
2104         }
2105       if (!strcmp (p, "__bb_trace__"))
2106         bb_mode |= 1;
2107       else if (!strcmp (p, "__bb_jumps__"))
2108         bb_mode |= 2;
2109       else if (!strcmp (p, "__bb_hidecall__"))
2110         bb_mode |= 4;
2111       else if (!strcmp (p, "__bb_showret__"))
2112         bb_mode |= 8;
2113       else 
2114         {
2115           struct bb_func *f = (struct bb_func *) malloc (sizeof (struct bb_func));
2116           if (f)
2117             {
2118               unsigned long l;
2119               f->next = bb_func_head;
2120               if (pos = strchr (p, ':'))
2121                 {
2122                   if (!(f->funcname = (char *) malloc (strlen (pos+1)+1)))
2123                     continue;
2124                   strcpy (f->funcname, pos+1);
2125                   l = pos-p;
2126                   if ((f->filename = (char *) malloc (l+1)))
2127                     {
2128                       strncpy (f->filename, p, l);
2129                       f->filename[l] = '\0';
2130                     }
2131                   else
2132                     f->filename = (char *) 0;
2133                 }
2134               else
2135                 {
2136                   if (!(f->funcname = (char *) malloc (strlen (p)+1)))
2137                     continue;
2138                   strcpy (f->funcname, p);
2139                   f->filename = (char *) 0;
2140                 }
2141               f->mode = m;
2142               bb_func_head = f;
2143             }
2144          }
2145     }
2146   fclose (file);
2147
2148 #ifdef HAVE_POPEN 
2149
2150   if (bb_mode & 1)
2151       bb_tracefile = gopen ("bbtrace.gz", "w");
2152
2153 #else
2154
2155   if (bb_mode & 1)
2156       bb_tracefile = fopen ("bbtrace", "w");
2157
2158 #endif /* HAVE_POPEN */
2159
2160   if (bb_mode & 2)
2161     {
2162       bb_hashbuckets = (struct bb_edge **) 
2163                    malloc (BB_BUCKETS * sizeof (struct bb_edge *));
2164       if (bb_hashbuckets)
2165         bzero ((char *) bb_hashbuckets, BB_BUCKETS);
2166     }
2167
2168   if (bb_mode & 12)
2169     {
2170       bb_stacksize = 10;
2171       bb_stack = (unsigned long *) malloc (bb_stacksize * sizeof (*bb_stack));
2172     }
2173
2174 #ifdef ON_EXIT
2175       /* Initialize destructor.  */
2176       ON_EXIT (__bb_exit_trace_func, 0);
2177 #endif
2178
2179 }
2180
2181 /* Called upon entering a basic block.  */
2182
2183 void
2184 __bb_trace_func ()
2185 {
2186   struct bb_edge *bucket;
2187
2188   MACHINE_STATE_SAVE("1")
2189
2190   if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2191     goto skip;
2192
2193   bb_dst = __bb.blocks->addresses[__bb.blockno];
2194   __bb.blocks->counts[__bb.blockno]++;
2195
2196   if (bb_tracefile)
2197     {
2198       fwrite (&bb_dst, sizeof (unsigned long), 1, bb_tracefile);
2199     }
2200
2201   if (bb_hashbuckets)
2202     {
2203       struct bb_edge **startbucket, **oldnext;
2204
2205       oldnext = startbucket
2206         = & bb_hashbuckets[ (((int) bb_src*8) ^ (int) bb_dst) % BB_BUCKETS ];
2207       bucket = *startbucket;
2208
2209       for (bucket = *startbucket; bucket; 
2210            oldnext = &(bucket->next), bucket = *oldnext)
2211         {
2212           if (bucket->src_addr == bb_src
2213               && bucket->dst_addr == bb_dst)
2214             {
2215               bucket->count++;
2216               *oldnext = bucket->next;
2217               bucket->next = *startbucket;
2218               *startbucket = bucket;
2219               goto ret;
2220             }
2221         }
2222
2223       bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2224
2225       if (!bucket)
2226         {
2227           if (!reported)
2228             {
2229               fprintf (stderr, "Profiler: out of memory\n");
2230               reported = 1;
2231             }
2232         }
2233
2234       else
2235         {
2236           bucket->src_addr = bb_src;
2237           bucket->dst_addr = bb_dst;
2238           bucket->next = *startbucket;
2239           *startbucket = bucket;
2240           bucket->count = 1;
2241         }
2242     }
2243
2244 ret:
2245   bb_src = bb_dst;
2246
2247 skip:
2248   ;
2249
2250   MACHINE_STATE_RESTORE("1")
2251
2252 }
2253
2254 /* Called when returning from a function and `__bb_showret__' is set.  */
2255
2256 static void
2257 __bb_trace_func_ret ()
2258 {
2259   struct bb_edge *bucket;
2260
2261   if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2262     goto skip;
2263
2264   if (bb_hashbuckets)
2265     {
2266       struct bb_edge **startbucket, **oldnext;
2267
2268       oldnext = startbucket
2269         = & bb_hashbuckets[ (((int) bb_dst * 8) ^ (int) bb_src) % BB_BUCKETS ];
2270       bucket = *startbucket;
2271
2272       for (bucket = *startbucket; bucket; 
2273            oldnext = &(bucket->next), bucket = *oldnext)
2274         {
2275           if (bucket->src_addr == bb_dst
2276                && bucket->dst_addr == bb_src)
2277             {
2278               bucket->count++;
2279               *oldnext = bucket->next;
2280               bucket->next = *startbucket;
2281               *startbucket = bucket;
2282               goto ret;
2283             }
2284         }
2285
2286       bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2287
2288       if (!bucket)
2289         {
2290           if (!reported)
2291             {
2292               fprintf (stderr, "Profiler: out of memory\n");
2293               reported = 1;
2294             }
2295         }
2296
2297       else
2298         {
2299           bucket->src_addr = bb_dst;
2300           bucket->dst_addr = bb_src;
2301           bucket->next = *startbucket;
2302           *startbucket = bucket;
2303           bucket->count = 1;
2304         }
2305     }
2306
2307 ret:
2308   bb_dst = bb_src;
2309
2310 skip:
2311   ;
2312
2313 }
2314
2315 /* Called upon entering the first function of a file.  */
2316
2317 static void
2318 __bb_init_file (struct bb *blocks)
2319 {
2320
2321   const struct bb_func *p;
2322   long blk, ncounts = blocks->ncounts;
2323   const char **functions = blocks->functions;
2324
2325   /* Set up linked list.  */
2326   blocks->zero_word = 1;
2327   blocks->next = bb_head;
2328   bb_head = blocks;
2329
2330   blocks->flags = 0;
2331   if (!bb_func_head
2332       || !(blocks->flags = (char *) malloc (sizeof (char) * blocks->ncounts)))
2333     return;
2334
2335   for (blk = 0; blk < ncounts; blk++)
2336     blocks->flags[blk] = 0;
2337
2338   for (blk = 0; blk < ncounts; blk++)
2339     {
2340       for (p = bb_func_head; p; p = p->next)
2341         {
2342           if (!strcmp (p->funcname, functions[blk])
2343               && (!p->filename || !strcmp (p->filename, blocks->filename)))
2344             {
2345               blocks->flags[blk] |= p->mode;
2346             }
2347         }
2348     }
2349
2350 }
2351
2352 /* Called when exiting from a function.  */
2353
2354 void
2355 __bb_trace_ret ()
2356 {
2357
2358   MACHINE_STATE_SAVE("2")
2359
2360   if (bb_callcount)
2361     {
2362       if ((bb_mode & 12) && bb_stacksize > bb_callcount)
2363         {
2364           bb_src = bb_stack[bb_callcount];
2365           if (bb_mode & 8)
2366             __bb_trace_func_ret ();
2367         }
2368
2369       bb_callcount -= 1;
2370     }
2371
2372   MACHINE_STATE_RESTORE("2")
2373
2374 }
2375
2376 /* Called when entering a function.  */
2377
2378 void
2379 __bb_init_trace_func (struct bb *blocks, unsigned long blockno)
2380 {
2381   static int trace_init = 0;
2382
2383   MACHINE_STATE_SAVE("3")
2384
2385   if (!blocks->zero_word)
2386     { 
2387       if (!trace_init)
2388         { 
2389           trace_init = 1;
2390           __bb_init_prg ();
2391         }
2392       __bb_init_file (blocks);
2393     }
2394
2395   if (bb_callcount)
2396     {
2397
2398       bb_callcount += 1;
2399
2400       if (bb_mode & 12)
2401         {
2402           if (bb_callcount >= bb_stacksize)
2403             {
2404               size_t newsize = bb_callcount + 100;
2405
2406               bb_stack = (unsigned long *) realloc (bb_stack, newsize);
2407               if (! bb_stack)
2408                 {
2409                   if (!reported)
2410                     {
2411                       fprintf (stderr, "Profiler: out of memory\n");
2412                       reported = 1;
2413                     }
2414                   bb_stacksize = 0;
2415                   goto stack_overflow;
2416                 }
2417               bb_stacksize = newsize;
2418             }
2419           bb_stack[bb_callcount] = bb_src;
2420
2421           if (bb_mode & 4)
2422             bb_src = 0;
2423
2424         }
2425
2426 stack_overflow:;
2427
2428     }
2429
2430   else if (blocks->flags && (blocks->flags[blockno] & TRACE_ON))
2431     {
2432       bb_callcount = 1;
2433       bb_src = 0;
2434
2435       if (bb_stack)
2436           bb_stack[bb_callcount] = bb_src;
2437     }
2438
2439   MACHINE_STATE_RESTORE("3")
2440 }
2441
2442 #endif /* not inhibit_libc */
2443 #endif /* not BLOCK_PROFILER_CODE */
2444 #endif /* L_bb */
2445 \f
2446 #ifdef L_shtab
2447 unsigned int __shtab[] = {
2448     0x00000001, 0x00000002, 0x00000004, 0x00000008,
2449     0x00000010, 0x00000020, 0x00000040, 0x00000080,
2450     0x00000100, 0x00000200, 0x00000400, 0x00000800,
2451     0x00001000, 0x00002000, 0x00004000, 0x00008000,
2452     0x00010000, 0x00020000, 0x00040000, 0x00080000,
2453     0x00100000, 0x00200000, 0x00400000, 0x00800000,
2454     0x01000000, 0x02000000, 0x04000000, 0x08000000,
2455     0x10000000, 0x20000000, 0x40000000, 0x80000000
2456   };
2457 #endif
2458 \f
2459 #ifdef L_clear_cache
2460 /* Clear part of an instruction cache.  */
2461
2462 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
2463
2464 void
2465 __clear_cache (char *beg, char *end)
2466 {
2467 #ifdef CLEAR_INSN_CACHE 
2468   CLEAR_INSN_CACHE (beg, end);
2469 #else
2470 #ifdef INSN_CACHE_SIZE
2471   static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
2472   static int initialized;
2473   int offset;
2474   void *start_addr
2475   void *end_addr;
2476   typedef (*function_ptr) ();
2477
2478 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
2479   /* It's cheaper to clear the whole cache.
2480      Put in a series of jump instructions so that calling the beginning
2481      of the cache will clear the whole thing.  */
2482
2483   if (! initialized)
2484     {
2485       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2486                  & -INSN_CACHE_LINE_WIDTH);
2487       int end_ptr = ptr + INSN_CACHE_SIZE;
2488
2489       while (ptr < end_ptr)
2490         {
2491           *(INSTRUCTION_TYPE *)ptr
2492             = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
2493           ptr += INSN_CACHE_LINE_WIDTH;
2494         }
2495       *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
2496
2497       initialized = 1;
2498     }
2499
2500   /* Call the beginning of the sequence.  */
2501   (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2502                     & -INSN_CACHE_LINE_WIDTH))
2503    ());
2504
2505 #else /* Cache is large.  */
2506
2507   if (! initialized)
2508     {
2509       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2510                  & -INSN_CACHE_LINE_WIDTH);
2511
2512       while (ptr < (int) array + sizeof array)
2513         {
2514           *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
2515           ptr += INSN_CACHE_LINE_WIDTH;
2516         }
2517
2518       initialized = 1;
2519     }
2520
2521   /* Find the location in array that occupies the same cache line as BEG.  */
2522
2523   offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
2524   start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
2525                  & -INSN_CACHE_PLANE_SIZE)
2526                 + offset);
2527
2528   /* Compute the cache alignment of the place to stop clearing.  */
2529 #if 0  /* This is not needed for gcc's purposes.  */
2530   /* If the block to clear is bigger than a cache plane,
2531      we clear the entire cache, and OFFSET is already correct.  */ 
2532   if (end < beg + INSN_CACHE_PLANE_SIZE)
2533 #endif
2534     offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
2535                & -INSN_CACHE_LINE_WIDTH)
2536               & (INSN_CACHE_PLANE_SIZE - 1));
2537
2538 #if INSN_CACHE_DEPTH > 1
2539   end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
2540   if (end_addr <= start_addr)
2541     end_addr += INSN_CACHE_PLANE_SIZE;
2542
2543   for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
2544     {
2545       int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
2546       int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
2547
2548       while (addr != stop)
2549         {
2550           /* Call the return instruction at ADDR.  */
2551           ((function_ptr) addr) ();
2552
2553           addr += INSN_CACHE_LINE_WIDTH;
2554         }
2555     }
2556 #else /* just one plane */
2557   do
2558     {
2559       /* Call the return instruction at START_ADDR.  */
2560       ((function_ptr) start_addr) ();
2561
2562       start_addr += INSN_CACHE_LINE_WIDTH;
2563     }
2564   while ((start_addr % INSN_CACHE_SIZE) != offset);
2565 #endif /* just one plane */
2566 #endif /* Cache is large */
2567 #endif /* Cache exists */
2568 #endif /* CLEAR_INSN_CACHE */
2569 }
2570
2571 #endif /* L_clear_cache */
2572 \f
2573 #ifdef L_trampoline
2574
2575 /* Jump to a trampoline, loading the static chain address.  */
2576
2577 #if defined(WINNT) && ! defined(__CYGWIN32__)
2578
2579 long getpagesize()
2580 {
2581 #ifdef _ALPHA_
2582   return 8192;
2583 #else
2584   return 4096;
2585 #endif
2586 }
2587
2588 #ifdef i386
2589 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
2590 #endif
2591
2592 int
2593 mprotect (char *addr, int len, int prot)
2594 {
2595   int np, op;
2596
2597   if (prot == 7)
2598     np = 0x40;
2599   else if (prot == 5)
2600     np = 0x20;
2601   else if (prot == 4)
2602     np = 0x10;
2603   else if (prot == 3)
2604     np = 0x04;
2605   else if (prot == 1)
2606     np = 0x02;
2607   else if (prot == 0)
2608     np = 0x01;
2609
2610   if (VirtualProtect (addr, len, np, &op))
2611     return 0;
2612   else
2613     return -1;
2614 }
2615
2616 #endif
2617
2618 #ifdef TRANSFER_FROM_TRAMPOLINE 
2619 TRANSFER_FROM_TRAMPOLINE 
2620 #endif
2621
2622 #if defined (NeXT) && defined (__MACH__)
2623
2624 /* Make stack executable so we can call trampolines on stack.
2625    This is called from INITIALIZE_TRAMPOLINE in next.h.  */
2626 #ifdef NeXTStep21
2627  #include <mach.h>
2628 #else
2629  #include <mach/mach.h>
2630 #endif
2631
2632 void
2633 __enable_execute_stack (char *addr)
2634 {
2635   kern_return_t r;
2636   char *eaddr = addr + TRAMPOLINE_SIZE;
2637   vm_address_t a = (vm_address_t) addr;
2638
2639   /* turn on execute access on stack */
2640   r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
2641   if (r != KERN_SUCCESS)
2642     {
2643       mach_error("vm_protect VM_PROT_ALL", r);
2644       exit(1);
2645     }
2646
2647   /* We inline the i-cache invalidation for speed */
2648
2649 #ifdef CLEAR_INSN_CACHE
2650   CLEAR_INSN_CACHE (addr, eaddr);
2651 #else
2652   __clear_cache ((int) addr, (int) eaddr);
2653 #endif
2654
2655
2656 #endif /* defined (NeXT) && defined (__MACH__) */
2657
2658 #ifdef __convex__
2659
2660 /* Make stack executable so we can call trampolines on stack.
2661    This is called from INITIALIZE_TRAMPOLINE in convex.h.  */
2662
2663 #include <sys/mman.h>
2664 #include <sys/vmparam.h>
2665 #include <machine/machparam.h>
2666
2667 void
2668 __enable_execute_stack ()
2669 {
2670   int fp;
2671   static unsigned lowest = USRSTACK;
2672   unsigned current = (unsigned) &fp & -NBPG;
2673
2674   if (lowest > current)
2675     {
2676       unsigned len = lowest - current;
2677       mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
2678       lowest = current;
2679     }
2680
2681   /* Clear instruction cache in case an old trampoline is in it.  */
2682   asm ("pich");
2683 }
2684 #endif /* __convex__ */
2685
2686 #ifdef __sysV88__
2687
2688 /* Modified from the convex -code above.  */
2689
2690 #include <sys/param.h>
2691 #include <errno.h>
2692 #include <sys/m88kbcs.h>
2693
2694 void
2695 __enable_execute_stack ()
2696 {
2697   int save_errno;
2698   static unsigned long lowest = USRSTACK;
2699   unsigned long current = (unsigned long) &save_errno & -NBPC;
2700   
2701   /* Ignore errno being set. memctl sets errno to EINVAL whenever the
2702      address is seen as 'negative'. That is the case with the stack.   */
2703
2704   save_errno=errno;
2705   if (lowest > current)
2706     {
2707       unsigned len=lowest-current;
2708       memctl(current,len,MCT_TEXT);
2709       lowest = current;
2710     }
2711   else
2712     memctl(current,NBPC,MCT_TEXT);
2713   errno=save_errno;
2714 }
2715
2716 #endif /* __sysV88__ */
2717
2718 #ifdef __pyr__
2719
2720 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
2721 #include <stdio.h>
2722 #include <sys/mman.h>
2723 #include <sys/types.h>
2724 #include <sys/param.h>
2725 #include <sys/vmmac.h>
2726
2727 /* Modified from the convex -code above.
2728    mremap promises to clear the i-cache.  */
2729
2730 void
2731 __enable_execute_stack ()
2732 {
2733   int fp;
2734   if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
2735                 PROT_READ|PROT_WRITE|PROT_EXEC))
2736     {
2737       perror ("mprotect in __enable_execute_stack");
2738       fflush (stderr);
2739       abort ();
2740     }
2741 }
2742 #endif /* __pyr__ */
2743
2744 #if defined (sony_news) && defined (SYSTYPE_BSD)
2745
2746 #include <stdio.h>
2747 #include <sys/types.h>
2748 #include <sys/param.h>
2749 #include <syscall.h>
2750 #include <machine/sysnews.h>
2751
2752 /* cacheflush function for NEWS-OS 4.2.
2753    This function is called from trampoline-initialize code
2754    defined in config/mips/mips.h.  */
2755
2756 void
2757 cacheflush (char *beg, int size, int flag)
2758 {
2759   if (syscall (SYS_sysnews, NEWS_CACHEFLUSH, beg, size, FLUSH_BCACHE))
2760     {
2761       perror ("cache_flush");
2762       fflush (stderr);
2763       abort ();
2764     }
2765 }
2766
2767 #endif /* sony_news */
2768 #endif /* L_trampoline */
2769 \f
2770 #ifdef L__main
2771
2772 #include "gbl-ctors.h"
2773 /* Some systems use __main in a way incompatible with its use in gcc, in these
2774    cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2775    give the same symbol without quotes for an alternative entry point.  You
2776    must define both, or neither.  */
2777 #ifndef NAME__MAIN
2778 #define NAME__MAIN "__main"
2779 #define SYMBOL__MAIN __main
2780 #endif
2781
2782 #ifdef INIT_SECTION_ASM_OP
2783 #undef HAS_INIT_SECTION
2784 #define HAS_INIT_SECTION
2785 #endif
2786
2787 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
2788 /* Run all the global destructors on exit from the program.  */
2789
2790 void
2791 __do_global_dtors ()
2792 {
2793 #ifdef DO_GLOBAL_DTORS_BODY
2794   DO_GLOBAL_DTORS_BODY;
2795 #else
2796   static func_ptr *p = __DTOR_LIST__ + 1;
2797   while (*p)
2798     {
2799       p++;
2800       (*(p-1)) ();
2801     }
2802 #endif
2803 }
2804 #endif
2805
2806 #ifndef HAS_INIT_SECTION
2807 /* Run all the global constructors on entry to the program.  */
2808
2809 #ifndef ON_EXIT
2810 #define ON_EXIT(a, b)
2811 #else
2812 /* Make sure the exit routine is pulled in to define the globals as
2813    bss symbols, just in case the linker does not automatically pull
2814    bss definitions from the library.  */
2815
2816 extern int _exit_dummy_decl;
2817 int *_exit_dummy_ref = &_exit_dummy_decl;
2818 #endif /* ON_EXIT */
2819
2820 void
2821 __do_global_ctors ()
2822 {
2823   DO_GLOBAL_CTORS_BODY;
2824   ON_EXIT (__do_global_dtors, 0);
2825 }
2826 #endif /* no HAS_INIT_SECTION */
2827
2828 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
2829 /* Subroutine called automatically by `main'.
2830    Compiling a global function named `main'
2831    produces an automatic call to this function at the beginning.
2832
2833    For many systems, this routine calls __do_global_ctors.
2834    For systems which support a .init section we use the .init section
2835    to run __do_global_ctors, so we need not do anything here.  */
2836
2837 void
2838 SYMBOL__MAIN ()
2839 {
2840   /* Support recursive calls to `main': run initializers just once.  */
2841   static int initialized;
2842   if (! initialized)
2843     {
2844       initialized = 1;
2845       __do_global_ctors ();
2846     }
2847 }
2848 #endif /* no HAS_INIT_SECTION or INVOKE__main */
2849
2850 #endif /* L__main */
2851 \f
2852 #ifdef L_ctors
2853
2854 #include "gbl-ctors.h"
2855
2856 /* Provide default definitions for the lists of constructors and
2857    destructors, so that we don't get linker errors.  These symbols are
2858    intentionally bss symbols, so that gld and/or collect will provide
2859    the right values.  */
2860
2861 /* We declare the lists here with two elements each,
2862    so that they are valid empty lists if no other definition is loaded.  */
2863 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
2864 #if defined(__NeXT__) || defined(_AIX)
2865 /* After 2.3, try this definition on all systems.  */
2866 func_ptr __CTOR_LIST__[2] = {0, 0};
2867 func_ptr __DTOR_LIST__[2] = {0, 0};
2868 #else
2869 func_ptr __CTOR_LIST__[2];
2870 func_ptr __DTOR_LIST__[2];
2871 #endif
2872 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
2873 #endif /* L_ctors */
2874 \f
2875 #ifdef L_exit
2876
2877 #include "gbl-ctors.h"
2878
2879 #ifdef NEED_ATEXIT
2880 # ifdef ON_EXIT
2881 #  undef ON_EXIT
2882 # endif
2883 int _exit_dummy_decl = 0;       /* prevent compiler & linker warnings */
2884 #endif
2885
2886 #ifndef ON_EXIT
2887
2888 #ifdef NEED_ATEXIT
2889 # include <errno.h>
2890
2891 static func_ptr *atexit_chain = 0;
2892 static long atexit_chain_length = 0;
2893 static volatile long last_atexit_chain_slot = -1;
2894
2895 int atexit (func_ptr func)
2896 {
2897   if (++last_atexit_chain_slot == atexit_chain_length)
2898     {
2899       atexit_chain_length += 32;
2900       if (atexit_chain)
2901         atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
2902                                              * sizeof (func_ptr));
2903       else
2904         atexit_chain = (func_ptr *) malloc (atexit_chain_length
2905                                             * sizeof (func_ptr));
2906       if (! atexit_chain)
2907         {
2908           atexit_chain_length = 0;
2909           last_atexit_chain_slot = -1;
2910           errno = ENOMEM;
2911           return (-1);
2912         }
2913     }
2914   atexit_chain[last_atexit_chain_slot] = func;
2915   return (0);
2916 }
2917 #endif /* NEED_ATEXIT */
2918
2919 /* If we have no known way of registering our own __do_global_dtors
2920    routine so that it will be invoked at program exit time, then we
2921    have to define our own exit routine which will get this to happen.  */
2922
2923 extern void __do_global_dtors ();
2924 extern void __bb_exit_func ();
2925 extern void _cleanup ();
2926 extern void _exit () __attribute__ ((noreturn));
2927
2928 void 
2929 exit (int status)
2930 {
2931 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2932 #ifdef NEED_ATEXIT
2933   if (atexit_chain)
2934     {
2935       for ( ; last_atexit_chain_slot-- >= 0; )
2936         {
2937           (*atexit_chain[last_atexit_chain_slot + 1]) ();
2938           atexit_chain[last_atexit_chain_slot + 1] = 0;
2939         }
2940       free (atexit_chain);
2941       atexit_chain = 0;
2942     }
2943 #else /* No NEED_ATEXIT */
2944   __do_global_dtors ();
2945 #endif /* No NEED_ATEXIT */
2946 #endif
2947 #ifndef inhibit_libc
2948   __bb_exit_func ();
2949 #endif
2950 #ifdef EXIT_BODY
2951   EXIT_BODY;
2952 #else
2953   _cleanup ();
2954 #endif
2955   _exit (status);
2956 }
2957
2958 #else
2959 int _exit_dummy_decl = 0;       /* prevent compiler & linker warnings */
2960 #endif
2961
2962 #endif /* L_exit */
2963 \f
2964 #ifdef L_eh
2965
2966 /* Shared exception handling support routines.  */
2967
2968 /* Language-specific information about the active exception(s).  If there
2969    are no active exceptions, it is set to 0.  */
2970 void *__eh_info;
2971
2972 void
2973 __default_terminate ()
2974 {
2975   abort ();
2976 }
2977
2978 void (*__terminate_func)() = __default_terminate;
2979
2980 void
2981 __terminate ()
2982 {
2983   (*__terminate_func)();
2984 }
2985
2986 void *
2987 __throw_type_match (void *catch_type, void *throw_type, void *obj)
2988 {
2989 #if 0
2990  printf ("__throw_type_match (): catch_type = %s, throw_type = %s\n",
2991          catch_type, throw_type);
2992 #endif
2993  if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)
2994    return obj;
2995  return 0;
2996 }
2997
2998 void
2999 __empty ()
3000 {
3001 }
3002 \f
3003 /* Support routines for setjmp/longjmp exception handling.  */
3004
3005 /* Calls to __sjthrow are generated by the compiler when an exception
3006    is raised when using the setjmp/longjmp exception handling codegen
3007    method.  */
3008
3009 extern void longjmp (void *, int);
3010
3011 static void *top_elt[2];
3012 void **__dynamic_handler_chain = top_elt;
3013
3014 /* Routine to get the head of the current thread's dynamic handler chain
3015    use for exception handling.
3016
3017    TODO: make thread safe.  */
3018
3019 void ***
3020 __get_dynamic_handler_chain ()
3021 {
3022   return &__dynamic_handler_chain;
3023 }
3024
3025 /* This is used to throw an exception when the setjmp/longjmp codegen
3026    method is used for exception handling.
3027
3028    We call __terminate if there are no handlers left (we know this
3029    when the dynamic handler chain is top_elt).  Otherwise we run the
3030    cleanup actions off the dynamic cleanup stack, and pop the top of
3031    the dynamic handler chain, and use longjmp to transfer back to the
3032    associated handler.  */
3033
3034 void
3035 __sjthrow ()
3036 {
3037   void ***dhc = __get_dynamic_handler_chain ();
3038   void *jmpbuf;
3039   void (*func)(void *, int);
3040   void *arg;
3041   void ***cleanup;
3042
3043   /* The cleanup chain is one word into the buffer.  Get the cleanup
3044      chain.  */
3045   cleanup = (void***)&(*dhc)[1];
3046
3047   /* If there are any cleanups in the chain, run them now.  */
3048   if (cleanup[0])
3049     {
3050       double store[200];
3051       void **buf = (void**)store;
3052       buf[1] = 0;
3053       buf[0] = (*dhc);
3054
3055       /* try { */
3056 #ifdef DONT_USE_BUILTIN_SETJMP
3057       if (! setjmp (&buf[2]))
3058 #else
3059       if (! __builtin_setjmp (&buf[2]))
3060 #endif
3061         {
3062           *dhc = buf;
3063           while (cleanup[0])
3064             {
3065               func = (void(*)(void*, int))cleanup[0][1];
3066               arg = (void*)cleanup[0][2];
3067
3068               /* Update this before running the cleanup.  */
3069               cleanup[0] = (void **)cleanup[0][0];
3070
3071               (*func)(arg, 2);
3072             }
3073           *dhc = buf[0];
3074         }
3075       /* catch (...) */
3076       else
3077         {
3078           __terminate ();
3079         }
3080     }
3081   
3082   /* We must call terminate if we try and rethrow an exception, when
3083      there is no exception currently active and when there are no
3084      handlers left.  */
3085   if (! __eh_info || (*dhc) == top_elt)
3086     __terminate ();
3087     
3088   /* Find the jmpbuf associated with the top element of the dynamic
3089      handler chain.  The jumpbuf starts two words into the buffer.  */
3090   jmpbuf = &(*dhc)[2];
3091
3092   /* Then we pop the top element off the dynamic handler chain.  */
3093   *dhc = (void**)(*dhc)[0];
3094
3095   /* And then we jump to the handler.  */
3096
3097 #ifdef DONT_USE_BUILTIN_SETJMP
3098   longjmp (jmpbuf, 1);
3099 #else
3100   __builtin_longjmp (jmpbuf, 1);
3101 #endif
3102 }
3103
3104 /* Run cleanups on the dynamic cleanup stack for the current dynamic
3105    handler, then pop the handler off the dynamic handler stack, and
3106    then throw.  This is used to skip the first handler, and transfer
3107    control to the next handler in the dynamic handler stack.  */
3108
3109 void
3110 __sjpopnthrow ()
3111 {
3112   void ***dhc = __get_dynamic_handler_chain ();
3113   void *jmpbuf;
3114   void (*func)(void *, int);
3115   void *arg;
3116   void ***cleanup;
3117
3118   /* The cleanup chain is one word into the buffer.  Get the cleanup
3119      chain.  */
3120   cleanup = (void***)&(*dhc)[1];
3121
3122   /* If there are any cleanups in the chain, run them now.  */
3123   if (cleanup[0])
3124     {
3125       double store[200];
3126       void **buf = (void**)store;
3127       buf[1] = 0;
3128       buf[0] = (*dhc);
3129
3130       /* try { */
3131 #ifdef DONT_USE_BUILTIN_SETJMP
3132       if (! setjmp (&buf[2]))
3133 #else
3134       if (! __builtin_setjmp (&buf[2]))
3135 #endif
3136         {
3137           *dhc = buf;
3138           while (cleanup[0])
3139             {
3140               func = (void(*)(void*, int))cleanup[0][1];
3141               arg = (void*)cleanup[0][2];
3142
3143               /* Update this before running the cleanup.  */
3144               cleanup[0] = (void **)cleanup[0][0];
3145
3146               (*func)(arg, 2);
3147             }
3148           *dhc = buf[0];
3149         }
3150       /* catch (...) */
3151       else
3152         {
3153           __terminate ();
3154         }
3155     }
3156
3157   /* Then we pop the top element off the dynamic handler chain.  */
3158   *dhc = (void**)(*dhc)[0];
3159
3160   __sjthrow ();
3161 }
3162 \f
3163 /* Support code for all exception region-based exception handling.  */
3164
3165 /* This value identifies the place from which an exception is being
3166    thrown.  */
3167
3168 #ifdef EH_TABLE_LOOKUP
3169
3170 EH_TABLE_LOOKUP
3171
3172 #else
3173
3174 typedef struct exception_table {
3175   void *start;
3176   void *end;
3177   void *exception_handler;
3178 } exception_table;
3179
3180 /* This routine takes a PC and a pointer to the exception region TABLE for
3181    its translation unit, and returns the address of the exception handler
3182    associated with the closest exception table handler entry associated
3183    with that PC, or 0 if there are no table entries the PC fits in.
3184
3185    In the advent of a tie, we have to give the last entry, as it represents
3186    an inner block.  */
3187
3188 static void *
3189 find_exception_handler (void *pc, exception_table *table)
3190 {
3191   if (table)
3192     {
3193       int pos;
3194       int best = -1;
3195
3196       /* We can't do a binary search because the table isn't guaranteed
3197          to be sorted from function to function.  */
3198       for (pos = 0; table[pos].exception_handler != (void *) -1; ++pos)
3199         {
3200           if (table[pos].start <= pc && table[pos].end > pc)
3201             {
3202               /* This can apply.  Make sure it is at least as small as
3203                  the previous best.  */
3204               if (best == -1 || (table[pos].end <= table[best].end
3205                                  && table[pos].start >= table[best].start))
3206                 best = pos;
3207             }
3208           /* But it is sorted by starting PC within a function.  */
3209           else if (best >= 0 && table[pos].start > pc)
3210             break;
3211         }
3212       if (best != -1)
3213         return table[best].exception_handler;
3214     }
3215
3216   return (void *) 0;
3217 }
3218 #endif /* EH_TABLE_LOOKUP */
3219 \f
3220 #ifndef DWARF2_UNWIND_INFO
3221 /* Support code for exception handling using inline unwinders or
3222    __unwind_function.  */
3223
3224 void *__eh_pc;
3225
3226 #ifndef EH_TABLE_LOOKUP
3227 typedef struct exception_table_node {
3228   exception_table *table;
3229   void *start;
3230   void *end;
3231   struct exception_table_node *next;
3232 } exception_table_node;
3233
3234 static struct exception_table_node *exception_table_list;
3235
3236 void *
3237 __find_first_exception_table_match (void *pc)
3238 {
3239   register exception_table_node *tnp;
3240
3241   for (tnp = exception_table_list; tnp != 0; tnp = tnp->next)
3242     {
3243       if (tnp->start <= pc && tnp->end >= pc)
3244         return find_exception_handler (pc, tnp->table);
3245     }
3246
3247   return (void *) 0;
3248 }
3249
3250 void
3251 __register_exceptions (exception_table *table)
3252 {
3253   exception_table_node *node;
3254   exception_table *range = table + 1;
3255
3256   if (range->start == (void *) -1)
3257     return;
3258
3259   node = (exception_table_node *) malloc (sizeof (exception_table_node));
3260   node->table = table;
3261
3262   /* This look can be optimized away either if the table
3263      is sorted, or if we pass in extra parameters.  */
3264   node->start = range->start;
3265   node->end = range->end;
3266   for (range++ ; range->start != (void *) (-1); range++)
3267     {
3268       if (range->start < node->start)
3269         node->start = range->start;
3270       if (range->end > node->end)
3271         node->end = range->end;
3272     }
3273
3274   node->next = exception_table_list;
3275   exception_table_list = node;
3276 }
3277 #endif /* !EH_TABLE_LOOKUP */
3278
3279 /* Throw stub routine.
3280
3281    This is work in progress, but not completed yet.  */
3282
3283 void
3284 __throw ()
3285 {
3286   abort ();
3287 }
3288
3289 /* See expand_builtin_throw for details.  */
3290
3291 void **__eh_pcnthrow () {
3292   static void *buf[2] = {
3293     &__eh_pc,
3294     &__throw
3295   };
3296   return buf;
3297 }
3298
3299 #if #machine(i386)
3300 void
3301 __unwind_function(void *ptr)
3302 {
3303   asm("movl 8(%esp),%ecx");
3304   /* Undo current frame */
3305   asm("movl %ebp,%esp");
3306   asm("popl %ebp");
3307   /* like ret, but stay here */
3308   asm("addl $4,%esp");
3309   
3310   /* Now, undo previous frame.  */
3311   /* This is a test routine, as we have to dynamically probe to find out
3312      what to pop for certain, this is just a guess.  */
3313   asm("leal -16(%ebp),%esp");
3314   asm("pop %ebx");
3315   asm("pop %esi");
3316   asm("pop %edi");
3317   asm("movl %ebp,%esp");
3318   asm("popl %ebp");
3319
3320   asm("movl %ecx,0(%esp)");
3321   asm("ret");
3322 }
3323 #elif #machine(rs6000) && !defined _ARCH_PPC
3324 __unwind_function(void *ptr)
3325 {
3326   asm("mr 31,1");
3327   asm("l 1,0(1)");
3328   asm("l 31,-4(1)");
3329   asm("# br");
3330
3331   asm("mr 31,1");
3332   asm("l 1,0(1)");
3333   /* use 31 as a scratch register to restore the link register.  */
3334   asm("l 31, 8(1);mtlr 31 # l lr,8(1)");
3335   asm("l 31,-4(1)");
3336   asm("# br");
3337   asm("mtctr 3;bctr # b 3");
3338 }
3339 #elif (#machine(rs6000) || #machine(powerpc)) && defined _ARCH_PPC
3340 __unwind_function(void *ptr)
3341 {
3342   asm("mr 31,1");
3343   asm("lwz 1,0(1)");
3344   asm("lwz 31,-4(1)");
3345   asm("# br");
3346
3347   asm("mr 31,1");
3348   asm("lwz 1,0(1)");
3349   /* use 31 as a scratch register to restore the link register.  */
3350   asm("lwz 31, 8(1);mtlr 31 # l lr,8(1)");
3351   asm("lwz 31,-4(1)");
3352   asm("# br");
3353   asm("mtctr 3;bctr # b 3");
3354 }
3355 #elif #machine(vax)
3356 __unwind_function(void *ptr)
3357 {
3358   __label__ return_again;
3359
3360   /* Replace our frame's return address with the label below.
3361      During execution, we will first return here instead of to
3362      caller, then second return takes caller's frame off the stack.
3363      Two returns matches two actual calls, so is less likely to
3364      confuse debuggers.  `16' corresponds to RETURN_ADDRESS_OFFSET.  */
3365   __asm ("movl %0,16(fp)" : : "p" (&& return_again));
3366   return;
3367
3368  return_again:
3369   return;
3370 }
3371 #else
3372 __unwind_function(void *ptr)
3373 {
3374   abort ();
3375 }
3376 #endif /* powerpc */
3377 \f
3378 #else /* DWARF2_UNWIND_INFO */
3379 /* Support code for exception handling using static unwind information.  */
3380
3381 #include "frame.h"
3382
3383 /* This type is used in get_reg and put_reg to deal with ABIs where a void*
3384    is smaller than a word, such as the Irix 6 n32 ABI.  We cast twice to
3385    avoid a warning about casting between int and pointer of different
3386    sizes.  */
3387
3388 typedef int ptr_type __attribute__ ((mode (pointer)));
3389
3390 /* Get the value of register REG as saved in UDATA, where SUB_UDATA is a
3391    frame called by UDATA or 0.  */
3392
3393 static void*
3394 get_reg (unsigned reg, frame_state *udata, frame_state *sub_udata)
3395 {
3396   if (udata->saved[reg] == REG_SAVED_OFFSET)
3397     return (void *)(ptr_type)
3398       *(word_type *)(udata->cfa + udata->reg_or_offset[reg]);
3399   else if (udata->saved[reg] == REG_SAVED_REG && sub_udata)
3400     return get_reg (udata->reg_or_offset[reg], sub_udata, 0);
3401   else
3402     abort ();
3403 }
3404
3405 /* Overwrite the saved value for register REG in frame UDATA with VAL.  */
3406
3407 static void
3408 put_reg (unsigned reg, void *val, frame_state *udata)
3409 {
3410   if (udata->saved[reg] == REG_SAVED_OFFSET)
3411     *(word_type *)(udata->cfa + udata->reg_or_offset[reg])
3412       = (word_type)(ptr_type) val;
3413   else
3414     abort ();
3415 }
3416
3417 /* Copy the saved value for register REG from frame UDATA to frame
3418    TARGET_UDATA.  Unlike the previous two functions, this can handle
3419    registers that are not one word large.  */
3420
3421 static void
3422 copy_reg (unsigned reg, frame_state *udata, frame_state *target_udata)
3423 {
3424   if (udata->saved[reg] == REG_SAVED_OFFSET
3425       && target_udata->saved[reg] == REG_SAVED_OFFSET)
3426     memcpy (target_udata->cfa + target_udata->reg_or_offset[reg],
3427             udata->cfa + udata->reg_or_offset[reg],
3428             __builtin_dwarf_reg_size (reg));
3429   else
3430     abort ();
3431 }
3432
3433 /* Retrieve the return address for frame UDATA, where SUB_UDATA is a
3434    frame called by UDATA or 0.  */
3435
3436 static inline void *
3437 get_return_addr (frame_state *udata, frame_state *sub_udata)
3438 {
3439   return __builtin_extract_return_addr
3440     (get_reg (udata->retaddr_column, udata, sub_udata));
3441 }
3442
3443 /* Overwrite the return address for frame UDATA with VAL.  */
3444
3445 static inline void
3446 put_return_addr (void *val, frame_state *udata)
3447 {
3448   val = __builtin_frob_return_addr (val);
3449   put_reg (udata->retaddr_column, val, udata);
3450 }
3451
3452 /* Given the current frame UDATA and its return address PC, return the
3453    information about the calling frame in CALLER_UDATA.  */
3454
3455 static void *
3456 next_stack_level (void *pc, frame_state *udata, frame_state *caller_udata)
3457 {
3458   caller_udata = __frame_state_for (pc, caller_udata);
3459   if (! caller_udata)
3460     return 0;
3461
3462   /* Now go back to our caller's stack frame.  If our caller's CFA register
3463      was saved in our stack frame, restore it; otherwise, assume the CFA
3464      register is SP and restore it to our CFA value.  */
3465   if (udata->saved[caller_udata->cfa_reg])
3466     caller_udata->cfa = get_reg (caller_udata->cfa_reg, udata, 0);
3467   else
3468     caller_udata->cfa = udata->cfa;
3469   caller_udata->cfa += caller_udata->cfa_offset;
3470
3471   return caller_udata;
3472 }
3473
3474 #ifdef INCOMING_REGNO
3475 /* Is the saved value for register REG in frame UDATA stored in a register
3476    window in the previous frame?  */
3477
3478 static int
3479 in_reg_window (int reg, frame_state *udata)
3480 {
3481   if (udata->saved[reg] != REG_SAVED_OFFSET)
3482     return 0;
3483
3484 #ifdef STACK_GROWS_DOWNWARD
3485   return udata->reg_or_offset[reg] > 0;
3486 #else
3487   return udata->reg_or_offset[reg] < 0;
3488 #endif
3489 }
3490 #endif /* INCOMING_REGNO */
3491
3492 /* We first search for an exception handler, and if we don't find
3493    it, we call __terminate on the current stack frame so that we may
3494    use the debugger to walk the stack and understand why no handler
3495    was found.
3496
3497    If we find one, then we unwind the frames down to the one that
3498    has the handler and transfer control into the handler.  */
3499
3500 void
3501 __throw ()
3502 {
3503   void *pc, *handler, *retaddr, *__eh_pc;
3504   frame_state ustruct, ustruct2;
3505   frame_state *udata = &ustruct;
3506   frame_state *sub_udata = &ustruct2;
3507   frame_state my_ustruct, *my_udata = &my_ustruct;
3508   long args_size;
3509
3510   /* This is required for C++ semantics.  We must call terminate if we
3511      try and rethrow an exception, when there is no exception currently
3512      active.  */
3513   if (! __eh_info)
3514     __terminate ();
3515     
3516   /* Start at our stack frame.  */
3517 label:
3518   udata = __frame_state_for (&&label, udata);
3519   if (! udata)
3520     __terminate ();
3521
3522   /* We need to get the value from the CFA register.  At this point in
3523      compiling __throw we don't know whether or not we will use the frame
3524      pointer register for the CFA, so we check our unwind info.  */
3525   if (udata->cfa_reg == __builtin_dwarf_fp_regnum ())
3526     udata->cfa = __builtin_fp ();
3527   else
3528     udata->cfa = __builtin_sp ();
3529   udata->cfa += udata->cfa_offset;
3530
3531   memcpy (my_udata, udata, sizeof (*udata));
3532
3533   /* Do any necessary initialization to access arbitrary stack frames.
3534      On the SPARC, this means flushing the register windows.  */
3535   __builtin_unwind_init ();
3536
3537   /* Now reset pc to the right throw point.  */
3538   __eh_pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
3539   pc = __eh_pc;
3540
3541   handler = 0;
3542   for (;;)
3543     { 
3544       frame_state *p = udata;
3545       udata = next_stack_level (pc, udata, sub_udata);
3546       sub_udata = p;
3547
3548       /* If we couldn't find the next frame, we lose.  */
3549       if (! udata)
3550         break;
3551
3552       handler = find_exception_handler (pc, udata->eh_ptr);
3553
3554       /* If we found one, we can stop searching.  */
3555       if (handler)
3556         {
3557           args_size = udata->args_size;
3558           break;
3559         }
3560
3561       /* Otherwise, we continue searching.  We subtract 1 from PC to avoid
3562          hitting the beginning of the next region.  */
3563       pc = get_return_addr (udata, sub_udata) - 1;
3564     }
3565
3566   /* If we haven't found a handler by now, this is an unhandled
3567      exception.  */
3568   if (! handler)
3569     __terminate ();
3570
3571   if (pc == __eh_pc)
3572     /* We found a handler in the throw context, no need to unwind.  */
3573     udata = my_udata;
3574   else
3575     {
3576       int i;
3577       void *val;
3578
3579       /* Unwind all the frames between this one and the handler by copying
3580          their saved register values into our register save slots.  */
3581
3582       /* Remember the PC where we found the handler.  */
3583       void *handler_pc = pc;
3584
3585       /* Start from the throw context again.  */
3586       pc = __eh_pc;
3587       memcpy (udata, my_udata, sizeof (*udata));
3588
3589       while (pc != handler_pc)
3590         {
3591           frame_state *p = udata;
3592           udata = next_stack_level (pc, udata, sub_udata);
3593           sub_udata = p;
3594
3595           for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
3596             if (i != udata->retaddr_column && udata->saved[i])
3597               {
3598 #ifdef INCOMING_REGNO
3599                 /* If you modify the saved value of the return address
3600                    register on the SPARC, you modify the return address for
3601                    your caller's frame.  Don't do that here, as it will
3602                    confuse get_return_addr.  */
3603                 if (in_reg_window (i, udata)
3604                     && udata->saved[udata->retaddr_column] == REG_SAVED_REG
3605                     && udata->reg_or_offset[udata->retaddr_column] == i)
3606                   continue;
3607 #endif
3608                 copy_reg (i, udata, my_udata);
3609               }
3610
3611           pc = get_return_addr (udata, sub_udata) - 1;
3612         }
3613
3614 #ifdef INCOMING_REGNO
3615       /* But we do need to update the saved return address register from
3616          the last frame we unwind, or the handler frame will have the wrong
3617          return address.  */
3618       if (udata->saved[udata->retaddr_column] == REG_SAVED_REG)
3619         {
3620           i = udata->reg_or_offset[udata->retaddr_column];
3621           if (in_reg_window (i, udata))
3622             copy_reg (i, udata, my_udata);
3623         }
3624 #endif
3625     }
3626   /* udata now refers to the frame called by the handler frame.  */
3627
3628   /* Emit the stub to adjust sp and jump to the handler.  */
3629   retaddr = __builtin_eh_stub ();
3630
3631   /* And then set our return address to point to the stub.  */
3632   if (my_udata->saved[my_udata->retaddr_column] == REG_SAVED_OFFSET)
3633     put_return_addr (retaddr, my_udata);
3634   else
3635     __builtin_set_return_addr_reg (retaddr);
3636
3637   /* Set up the registers we use to communicate with the stub.
3638      We check STACK_GROWS_DOWNWARD so the stub can use adjust_stack.  */
3639   __builtin_set_eh_regs (handler,
3640 #ifdef STACK_GROWS_DOWNWARD
3641                          udata->cfa - my_udata->cfa
3642 #else
3643                          my_udata->cfa - udata->cfa
3644 #endif
3645                          + args_size
3646                          );
3647
3648   /* Epilogue:  restore the handler frame's register values and return
3649      to the stub.  */
3650 }
3651 #endif /* !DWARF2_UNWIND_INFO */
3652
3653 #endif /* L_eh */
3654 \f
3655 #ifdef L_pure
3656 #ifndef inhibit_libc
3657 /* This gets us __GNU_LIBRARY__.  */
3658 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
3659 #include <stdio.h>
3660
3661 #ifdef __GNU_LIBRARY__
3662   /* Avoid forcing the library's meaning of `write' on the user program
3663      by using the "internal" name (for use within the library)  */
3664 #define write(fd, buf, n)       __write((fd), (buf), (n))
3665 #endif
3666 #endif /* inhibit_libc */
3667
3668 #define MESSAGE "pure virtual method called\n"
3669
3670 void
3671 __pure_virtual ()
3672 {
3673 #ifndef inhibit_libc
3674   write (2, MESSAGE, sizeof (MESSAGE) - 1);
3675 #endif
3676   _exit (-1);
3677 }
3678 #endif