OSDN Git Service

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