OSDN Git Service

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