OSDN Git Service

* configure.in: Arrange to include defaults.h in [ht]config.h/tm.h.
[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, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
4    2001 Free Software Foundation, Inc.
5
6 This file is part of GNU CC.
7
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 In addition to the permissions in the GNU General Public License, the
14 Free Software Foundation gives you unlimited permission to link the
15 compiled version of this file into combinations with other programs,
16 and to distribute those combinations without any restriction coming
17 from the use of this file.  (The General Public License restrictions
18 do apply in other respects; for example, they cover modification of
19 the file, and distribution when not linked into a combine
20 executable.)
21
22 GNU CC is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25 GNU General Public License for more details.
26
27 You should have received a copy of the GNU General Public License
28 along with GNU CC; see the file COPYING.  If not, write to
29 the Free Software Foundation, 59 Temple Place - Suite 330,
30 Boston, MA 02111-1307, USA.  */
31
32 /* It is incorrect to include config.h here, because this file is being
33    compiled for the target, and hence definitions concerning only the host
34    do not apply.  */
35
36 #include "tconfig.h"
37 #include "tsystem.h"
38
39 #include "machmode.h"
40
41 /* Don't use `fancy_abort' here even if config.h says to use it.  */
42 #ifdef abort
43 #undef abort
44 #endif
45
46 #include "libgcc2.h"
47 \f
48 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
49 #if defined (L_divdi3) || defined (L_moddi3)
50 static inline
51 #endif
52 DWtype
53 __negdi2 (DWtype u)
54 {
55   DWunion w;
56   DWunion uu;
57
58   uu.ll = u;
59
60   w.s.low = -uu.s.low;
61   w.s.high = -uu.s.high - ((UWtype) w.s.low > 0);
62
63   return w.ll;
64 }
65 #endif
66
67 #ifdef L_addvsi3
68 Wtype
69 __addvsi3 (Wtype a, Wtype b)
70 {
71   Wtype w;
72
73   w = a + b;
74
75   if (b >= 0 ? w < a : w > a)
76     abort ();
77
78   return w;
79
80 #endif
81 \f
82 #ifdef L_addvdi3
83 DWtype
84 __addvdi3 (DWtype a, DWtype b)
85 {
86   DWtype w;
87
88   w = a + b;
89
90   if (b >= 0 ? w < a : w > a)
91     abort ();
92
93   return w;
94 }
95 #endif
96 \f
97 #ifdef L_subvsi3
98 Wtype
99 __subvsi3 (Wtype a, Wtype b)
100 {
101 #ifdef L_addvsi3
102   return __addvsi3 (a, (-b));
103 #else
104   DWtype w;
105
106   w = a - b;
107
108   if (b >= 0 ? w > a : w < a)
109     abort ();
110
111   return w;
112 #endif
113 }
114 #endif
115 \f
116 #ifdef L_subvdi3
117 DWtype
118 __subvdi3 (DWtype a, DWtype b)
119 {
120 #ifdef L_addvdi3
121   return (a, (-b));
122 #else
123   DWtype w;
124
125   w = a - b;
126
127   if (b >= 0 ? w > a : w < a)
128     abort ();
129
130   return w;
131 #endif
132 }
133 #endif
134 \f
135 #ifdef L_mulvsi3
136 Wtype
137 __mulvsi3 (Wtype a, Wtype b)
138 {
139   DWtype w;
140
141   w = a * b;
142
143   if (((a >= 0) == (b >= 0)) ? w < 0 : w > 0)
144     abort ();
145
146   return w;
147 }
148 #endif
149 \f
150 #ifdef L_negvsi2
151 Wtype
152 __negvsi2 (Wtype a)
153 {
154    Wtype w;
155
156    w  = -a;
157
158   if (a >= 0 ? w > 0 : w < 0)
159     abort ();
160
161    return w;
162 }
163 #endif
164 \f
165 #ifdef L_negvdi2
166 DWtype
167 __negvdi2 (DWtype a)
168 {
169    DWtype w;
170
171    w  = -a;
172
173   if (a >= 0 ? w > 0 : w < 0)
174     abort ();
175
176    return w;
177 }
178 #endif
179 \f
180 #ifdef L_absvsi2
181 Wtype
182 __absvsi2 (Wtype a)
183 {
184    Wtype w = a;
185
186    if (a < 0)
187 #ifdef L_negvsi2
188      w = __negvsi2 (a);
189 #else
190      w = -a;
191
192    if (w < 0)
193      abort ();
194 #endif
195
196    return w;
197 }
198 #endif
199 \f
200 #ifdef L_absvdi2
201 DWtype
202 __absvdi2 (DWtype a)
203 {
204    DWtype w = a;
205
206    if (a < 0)
207 #ifdef L_negvsi2
208      w = __negvsi2 (a);
209 #else
210      w = -a;
211
212    if (w < 0)
213      abort ();
214 #endif
215
216    return w;
217 }
218 #endif
219 \f
220 #ifdef L_mulvdi3
221 DWtype
222 __mulvdi3 (DWtype u, DWtype v)
223 {
224    DWtype w;
225
226   w = u * v;
227
228   if (((u >= 0) == (v >= 0)) ? w < 0 : w > 0)
229     abort ();
230
231   return w;
232 }
233 #endif
234 \f
235
236 /* Unless shift functions are defined whith full ANSI prototypes,
237    parameter b will be promoted to int if word_type is smaller than an int.  */
238 #ifdef L_lshrdi3
239 DWtype
240 __lshrdi3 (DWtype u, word_type b)
241 {
242   DWunion w;
243   word_type bm;
244   DWunion uu;
245
246   if (b == 0)
247     return u;
248
249   uu.ll = u;
250
251   bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
252   if (bm <= 0)
253     {
254       w.s.high = 0;
255       w.s.low = (UWtype) uu.s.high >> -bm;
256     }
257   else
258     {
259       UWtype carries = (UWtype) uu.s.high << bm;
260
261       w.s.high = (UWtype) uu.s.high >> b;
262       w.s.low = ((UWtype) uu.s.low >> b) | carries;
263     }
264
265   return w.ll;
266 }
267 #endif
268
269 #ifdef L_ashldi3
270 DWtype
271 __ashldi3 (DWtype u, word_type b)
272 {
273   DWunion w;
274   word_type bm;
275   DWunion uu;
276
277   if (b == 0)
278     return u;
279
280   uu.ll = u;
281
282   bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
283   if (bm <= 0)
284     {
285       w.s.low = 0;
286       w.s.high = (UWtype) uu.s.low << -bm;
287     }
288   else
289     {
290       UWtype carries = (UWtype) uu.s.low >> bm;
291
292       w.s.low = (UWtype) uu.s.low << b;
293       w.s.high = ((UWtype) uu.s.high << b) | carries;
294     }
295
296   return w.ll;
297 }
298 #endif
299
300 #ifdef L_ashrdi3
301 DWtype
302 __ashrdi3 (DWtype u, word_type b)
303 {
304   DWunion w;
305   word_type bm;
306   DWunion uu;
307
308   if (b == 0)
309     return u;
310
311   uu.ll = u;
312
313   bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
314   if (bm <= 0)
315     {
316       /* w.s.high = 1..1 or 0..0 */
317       w.s.high = uu.s.high >> (sizeof (Wtype) * BITS_PER_UNIT - 1);
318       w.s.low = uu.s.high >> -bm;
319     }
320   else
321     {
322       UWtype carries = (UWtype) uu.s.high << bm;
323
324       w.s.high = uu.s.high >> b;
325       w.s.low = ((UWtype) uu.s.low >> b) | carries;
326     }
327
328   return w.ll;
329 }
330 #endif
331 \f
332 #ifdef L_ffsdi2
333 DWtype
334 __ffsdi2 (DWtype u)
335 {
336   DWunion uu;
337   UWtype word, count, add;
338
339   uu.ll = u;
340   if (uu.s.low != 0)
341     word = uu.s.low, add = 0;
342   else if (uu.s.high != 0)
343     word = uu.s.high, add = BITS_PER_UNIT * sizeof (Wtype);
344   else
345     return 0;
346
347   count_trailing_zeros (count, word);
348   return count + add + 1;
349 }
350 #endif
351 \f
352 #ifdef L_muldi3
353 DWtype
354 __muldi3 (DWtype u, DWtype v)
355 {
356   DWunion w;
357   DWunion uu, vv;
358
359   uu.ll = u,
360   vv.ll = v;
361
362   w.ll = __umulsidi3 (uu.s.low, vv.s.low);
363   w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
364                + (UWtype) uu.s.high * (UWtype) vv.s.low);
365
366   return w.ll;
367 }
368 #endif
369 \f
370 #ifdef L_udiv_w_sdiv
371 #if defined (sdiv_qrnnd)
372 UWtype
373 __udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d)
374 {
375   UWtype q, r;
376   UWtype c0, c1, b1;
377
378   if ((Wtype) d >= 0)
379     {
380       if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1)))
381         {
382           /* dividend, divisor, and quotient are nonnegative */
383           sdiv_qrnnd (q, r, a1, a0, d);
384         }
385       else
386         {
387           /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
388           sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1));
389           /* Divide (c1*2^32 + c0) by d */
390           sdiv_qrnnd (q, r, c1, c0, d);
391           /* Add 2^31 to quotient */
392           q += (UWtype) 1 << (W_TYPE_SIZE - 1);
393         }
394     }
395   else
396     {
397       b1 = d >> 1;                      /* d/2, between 2^30 and 2^31 - 1 */
398       c1 = a1 >> 1;                     /* A/2 */
399       c0 = (a1 << (W_TYPE_SIZE - 1)) + (a0 >> 1);
400
401       if (a1 < b1)                      /* A < 2^32*b1, so A/2 < 2^31*b1 */
402         {
403           sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
404
405           r = 2*r + (a0 & 1);           /* Remainder from A/(2*b1) */
406           if ((d & 1) != 0)
407             {
408               if (r >= q)
409                 r = r - q;
410               else if (q - r <= d)
411                 {
412                   r = r - q + d;
413                   q--;
414                 }
415               else
416                 {
417                   r = r - q + 2*d;
418                   q -= 2;
419                 }
420             }
421         }
422       else if (c1 < b1)                 /* So 2^31 <= (A/2)/b1 < 2^32 */
423         {
424           c1 = (b1 - 1) - c1;
425           c0 = ~c0;                     /* logical NOT */
426
427           sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
428
429           q = ~q;                       /* (A/2)/b1 */
430           r = (b1 - 1) - r;
431
432           r = 2*r + (a0 & 1);           /* A/(2*b1) */
433
434           if ((d & 1) != 0)
435             {
436               if (r >= q)
437                 r = r - q;
438               else if (q - r <= d)
439                 {
440                   r = r - q + d;
441                   q--;
442                 }
443               else
444                 {
445                   r = r - q + 2*d;
446                   q -= 2;
447                 }
448             }
449         }
450       else                              /* Implies c1 = b1 */
451         {                               /* Hence a1 = d - 1 = 2*b1 - 1 */
452           if (a0 >= -d)
453             {
454               q = -1;
455               r = a0 + d;
456             }
457           else
458             {
459               q = -2;
460               r = a0 + 2*d;
461             }
462         }
463     }
464
465   *rp = r;
466   return q;
467 }
468 #else
469 /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv.  */
470 UWtype
471 __udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)),
472                UWtype a1 __attribute__ ((__unused__)),
473                UWtype a0 __attribute__ ((__unused__)),
474                UWtype d __attribute__ ((__unused__)))
475 {
476   return 0;
477 }
478 #endif
479 #endif
480 \f
481 #if (defined (L_udivdi3) || defined (L_divdi3) || \
482      defined (L_umoddi3) || defined (L_moddi3))
483 #define L_udivmoddi4
484 #endif
485
486 #ifdef L_clz
487 const UQItype __clz_tab[] =
488 {
489   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,
490   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,
491   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,
492   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,
493   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,
494   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,
495   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,
496   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,
497 };
498 #endif
499
500 #ifdef L_udivmoddi4
501
502 #if (defined (L_udivdi3) || defined (L_divdi3) || \
503      defined (L_umoddi3) || defined (L_moddi3))
504 static inline
505 #endif
506 UDWtype
507 __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
508 {
509   DWunion ww;
510   DWunion nn, dd;
511   DWunion rr;
512   UWtype d0, d1, n0, n1, n2;
513   UWtype q0, q1;
514   UWtype b, bm;
515
516   nn.ll = n;
517   dd.ll = d;
518
519   d0 = dd.s.low;
520   d1 = dd.s.high;
521   n0 = nn.s.low;
522   n1 = nn.s.high;
523
524 #if !UDIV_NEEDS_NORMALIZATION
525   if (d1 == 0)
526     {
527       if (d0 > n1)
528         {
529           /* 0q = nn / 0D */
530
531           udiv_qrnnd (q0, n0, n1, n0, d0);
532           q1 = 0;
533
534           /* Remainder in n0.  */
535         }
536       else
537         {
538           /* qq = NN / 0d */
539
540           if (d0 == 0)
541             d0 = 1 / d0;        /* Divide intentionally by zero.  */
542
543           udiv_qrnnd (q1, n1, 0, n1, d0);
544           udiv_qrnnd (q0, n0, n1, n0, d0);
545
546           /* Remainder in n0.  */
547         }
548
549       if (rp != 0)
550         {
551           rr.s.low = n0;
552           rr.s.high = 0;
553           *rp = rr.ll;
554         }
555     }
556
557 #else /* UDIV_NEEDS_NORMALIZATION */
558
559   if (d1 == 0)
560     {
561       if (d0 > n1)
562         {
563           /* 0q = nn / 0D */
564
565           count_leading_zeros (bm, d0);
566
567           if (bm != 0)
568             {
569               /* Normalize, i.e. make the most significant bit of the
570                  denominator set.  */
571
572               d0 = d0 << bm;
573               n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
574               n0 = n0 << bm;
575             }
576
577           udiv_qrnnd (q0, n0, n1, n0, d0);
578           q1 = 0;
579
580           /* Remainder in n0 >> bm.  */
581         }
582       else
583         {
584           /* qq = NN / 0d */
585
586           if (d0 == 0)
587             d0 = 1 / d0;        /* Divide intentionally by zero.  */
588
589           count_leading_zeros (bm, d0);
590
591           if (bm == 0)
592             {
593               /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
594                  conclude (the most significant bit of n1 is set) /\ (the
595                  leading quotient digit q1 = 1).
596
597                  This special case is necessary, not an optimization.
598                  (Shifts counts of W_TYPE_SIZE are undefined.)  */
599
600               n1 -= d0;
601               q1 = 1;
602             }
603           else
604             {
605               /* Normalize.  */
606
607               b = W_TYPE_SIZE - bm;
608
609               d0 = d0 << bm;
610               n2 = n1 >> b;
611               n1 = (n1 << bm) | (n0 >> b);
612               n0 = n0 << bm;
613
614               udiv_qrnnd (q1, n1, n2, n1, d0);
615             }
616
617           /* n1 != d0...  */
618
619           udiv_qrnnd (q0, n0, n1, n0, d0);
620
621           /* Remainder in n0 >> bm.  */
622         }
623
624       if (rp != 0)
625         {
626           rr.s.low = n0 >> bm;
627           rr.s.high = 0;
628           *rp = rr.ll;
629         }
630     }
631 #endif /* UDIV_NEEDS_NORMALIZATION */
632
633   else
634     {
635       if (d1 > n1)
636         {
637           /* 00 = nn / DD */
638
639           q0 = 0;
640           q1 = 0;
641
642           /* Remainder in n1n0.  */
643           if (rp != 0)
644             {
645               rr.s.low = n0;
646               rr.s.high = n1;
647               *rp = rr.ll;
648             }
649         }
650       else
651         {
652           /* 0q = NN / dd */
653
654           count_leading_zeros (bm, d1);
655           if (bm == 0)
656             {
657               /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
658                  conclude (the most significant bit of n1 is set) /\ (the
659                  quotient digit q0 = 0 or 1).
660
661                  This special case is necessary, not an optimization.  */
662
663               /* The condition on the next line takes advantage of that
664                  n1 >= d1 (true due to program flow).  */
665               if (n1 > d1 || n0 >= d0)
666                 {
667                   q0 = 1;
668                   sub_ddmmss (n1, n0, n1, n0, d1, d0);
669                 }
670               else
671                 q0 = 0;
672
673               q1 = 0;
674
675               if (rp != 0)
676                 {
677                   rr.s.low = n0;
678                   rr.s.high = n1;
679                   *rp = rr.ll;
680                 }
681             }
682           else
683             {
684               UWtype m1, m0;
685               /* Normalize.  */
686
687               b = W_TYPE_SIZE - bm;
688
689               d1 = (d1 << bm) | (d0 >> b);
690               d0 = d0 << bm;
691               n2 = n1 >> b;
692               n1 = (n1 << bm) | (n0 >> b);
693               n0 = n0 << bm;
694
695               udiv_qrnnd (q0, n1, n2, n1, d1);
696               umul_ppmm (m1, m0, q0, d0);
697
698               if (m1 > n1 || (m1 == n1 && m0 > n0))
699                 {
700                   q0--;
701                   sub_ddmmss (m1, m0, m1, m0, d1, d0);
702                 }
703
704               q1 = 0;
705
706               /* Remainder in (n1n0 - m1m0) >> bm.  */
707               if (rp != 0)
708                 {
709                   sub_ddmmss (n1, n0, n1, n0, m1, m0);
710                   rr.s.low = (n1 << b) | (n0 >> bm);
711                   rr.s.high = n1 >> bm;
712                   *rp = rr.ll;
713                 }
714             }
715         }
716     }
717
718   ww.s.low = q0;
719   ww.s.high = q1;
720   return ww.ll;
721 }
722 #endif
723
724 #ifdef L_divdi3
725 DWtype
726 __divdi3 (DWtype u, DWtype v)
727 {
728   word_type c = 0;
729   DWunion uu, vv;
730   DWtype w;
731
732   uu.ll = u;
733   vv.ll = v;
734
735   if (uu.s.high < 0)
736     c = ~c,
737     uu.ll = __negdi2 (uu.ll);
738   if (vv.s.high < 0)
739     c = ~c,
740     vv.ll = __negdi2 (vv.ll);
741
742   w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
743   if (c)
744     w = __negdi2 (w);
745
746   return w;
747 }
748 #endif
749
750 #ifdef L_moddi3
751 DWtype
752 __moddi3 (DWtype u, DWtype v)
753 {
754   word_type c = 0;
755   DWunion uu, vv;
756   DWtype w;
757
758   uu.ll = u;
759   vv.ll = v;
760
761   if (uu.s.high < 0)
762     c = ~c,
763     uu.ll = __negdi2 (uu.ll);
764   if (vv.s.high < 0)
765     vv.ll = __negdi2 (vv.ll);
766
767   (void) __udivmoddi4 (uu.ll, vv.ll, &w);
768   if (c)
769     w = __negdi2 (w);
770
771   return w;
772 }
773 #endif
774
775 #ifdef L_umoddi3
776 UDWtype
777 __umoddi3 (UDWtype u, UDWtype v)
778 {
779   UDWtype w;
780
781   (void) __udivmoddi4 (u, v, &w);
782
783   return w;
784 }
785 #endif
786
787 #ifdef L_udivdi3
788 UDWtype
789 __udivdi3 (UDWtype n, UDWtype d)
790 {
791   return __udivmoddi4 (n, d, (UDWtype *) 0);
792 }
793 #endif
794 \f
795 #ifdef L_cmpdi2
796 word_type
797 __cmpdi2 (DWtype a, DWtype b)
798 {
799   DWunion au, bu;
800
801   au.ll = a, bu.ll = b;
802
803   if (au.s.high < bu.s.high)
804     return 0;
805   else if (au.s.high > bu.s.high)
806     return 2;
807   if ((UWtype) au.s.low < (UWtype) bu.s.low)
808     return 0;
809   else if ((UWtype) au.s.low > (UWtype) bu.s.low)
810     return 2;
811   return 1;
812 }
813 #endif
814
815 #ifdef L_ucmpdi2
816 word_type
817 __ucmpdi2 (DWtype a, DWtype b)
818 {
819   DWunion au, bu;
820
821   au.ll = a, bu.ll = b;
822
823   if ((UWtype) au.s.high < (UWtype) bu.s.high)
824     return 0;
825   else if ((UWtype) au.s.high > (UWtype) bu.s.high)
826     return 2;
827   if ((UWtype) au.s.low < (UWtype) bu.s.low)
828     return 0;
829   else if ((UWtype) au.s.low > (UWtype) bu.s.low)
830     return 2;
831   return 1;
832 }
833 #endif
834 \f
835 #if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
836 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
837 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
838
839 DWtype
840 __fixunstfDI (TFtype a)
841 {
842   TFtype b;
843   UDWtype v;
844
845   if (a < 0)
846     return 0;
847
848   /* Compute high word of result, as a flonum.  */
849   b = (a / HIGH_WORD_COEFF);
850   /* Convert that to fixed (but not to DWtype!),
851      and shift it into the high word.  */
852   v = (UWtype) b;
853   v <<= WORD_SIZE;
854   /* Remove high part from the TFtype, leaving the low part as flonum.  */
855   a -= (TFtype)v;
856   /* Convert that to fixed (but not to DWtype!) and add it in.
857      Sometimes A comes out negative.  This is significant, since
858      A has more bits than a long int does.  */
859   if (a < 0)
860     v -= (UWtype) (- a);
861   else
862     v += (UWtype) a;
863   return v;
864 }
865 #endif
866
867 #if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
868 DWtype
869 __fixtfdi (TFtype a)
870 {
871   if (a < 0)
872     return - __fixunstfDI (-a);
873   return __fixunstfDI (a);
874 }
875 #endif
876
877 #if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
878 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
879 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
880
881 DWtype
882 __fixunsxfDI (XFtype a)
883 {
884   XFtype b;
885   UDWtype v;
886
887   if (a < 0)
888     return 0;
889
890   /* Compute high word of result, as a flonum.  */
891   b = (a / HIGH_WORD_COEFF);
892   /* Convert that to fixed (but not to DWtype!),
893      and shift it into the high word.  */
894   v = (UWtype) b;
895   v <<= WORD_SIZE;
896   /* Remove high part from the XFtype, leaving the low part as flonum.  */
897   a -= (XFtype)v;
898   /* Convert that to fixed (but not to DWtype!) and add it in.
899      Sometimes A comes out negative.  This is significant, since
900      A has more bits than a long int does.  */
901   if (a < 0)
902     v -= (UWtype) (- a);
903   else
904     v += (UWtype) a;
905   return v;
906 }
907 #endif
908
909 #if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
910 DWtype
911 __fixxfdi (XFtype a)
912 {
913   if (a < 0)
914     return - __fixunsxfDI (-a);
915   return __fixunsxfDI (a);
916 }
917 #endif
918
919 #ifdef L_fixunsdfdi
920 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
921 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
922
923 DWtype
924 __fixunsdfDI (DFtype a)
925 {
926   DFtype b;
927   UDWtype v;
928
929   if (a < 0)
930     return 0;
931
932   /* Compute high word of result, as a flonum.  */
933   b = (a / HIGH_WORD_COEFF);
934   /* Convert that to fixed (but not to DWtype!),
935      and shift it into the high word.  */
936   v = (UWtype) b;
937   v <<= WORD_SIZE;
938   /* Remove high part from the DFtype, leaving the low part as flonum.  */
939   a -= (DFtype)v;
940   /* Convert that to fixed (but not to DWtype!) and add it in.
941      Sometimes A comes out negative.  This is significant, since
942      A has more bits than a long int does.  */
943   if (a < 0)
944     v -= (UWtype) (- a);
945   else
946     v += (UWtype) a;
947   return v;
948 }
949 #endif
950
951 #ifdef L_fixdfdi
952 DWtype
953 __fixdfdi (DFtype a)
954 {
955   if (a < 0)
956     return - __fixunsdfDI (-a);
957   return __fixunsdfDI (a);
958 }
959 #endif
960
961 #ifdef L_fixunssfdi
962 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
963 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
964
965 DWtype
966 __fixunssfDI (SFtype original_a)
967 {
968   /* Convert the SFtype to a DFtype, because that is surely not going
969      to lose any bits.  Some day someone else can write a faster version
970      that avoids converting to DFtype, and verify it really works right.  */
971   DFtype a = original_a;
972   DFtype b;
973   UDWtype v;
974
975   if (a < 0)
976     return 0;
977
978   /* Compute high word of result, as a flonum.  */
979   b = (a / HIGH_WORD_COEFF);
980   /* Convert that to fixed (but not to DWtype!),
981      and shift it into the high word.  */
982   v = (UWtype) b;
983   v <<= WORD_SIZE;
984   /* Remove high part from the DFtype, leaving the low part as flonum.  */
985   a -= (DFtype) v;
986   /* Convert that to fixed (but not to DWtype!) and add it in.
987      Sometimes A comes out negative.  This is significant, since
988      A has more bits than a long int does.  */
989   if (a < 0)
990     v -= (UWtype) (- a);
991   else
992     v += (UWtype) a;
993   return v;
994 }
995 #endif
996
997 #ifdef L_fixsfdi
998 DWtype
999 __fixsfdi (SFtype a)
1000 {
1001   if (a < 0)
1002     return - __fixunssfDI (-a);
1003   return __fixunssfDI (a);
1004 }
1005 #endif
1006
1007 #if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
1008 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1009 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1010 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1011
1012 XFtype
1013 __floatdixf (DWtype u)
1014 {
1015   XFtype d;
1016
1017   d = (Wtype) (u >> WORD_SIZE);
1018   d *= HIGH_HALFWORD_COEFF;
1019   d *= HIGH_HALFWORD_COEFF;
1020   d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1021
1022   return d;
1023 }
1024 #endif
1025
1026 #if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
1027 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1028 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1029 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1030
1031 TFtype
1032 __floatditf (DWtype u)
1033 {
1034   TFtype d;
1035
1036   d = (Wtype) (u >> WORD_SIZE);
1037   d *= HIGH_HALFWORD_COEFF;
1038   d *= HIGH_HALFWORD_COEFF;
1039   d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1040
1041   return d;
1042 }
1043 #endif
1044
1045 #ifdef L_floatdidf
1046 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1047 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1048 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1049
1050 DFtype
1051 __floatdidf (DWtype u)
1052 {
1053   DFtype d;
1054
1055   d = (Wtype) (u >> WORD_SIZE);
1056   d *= HIGH_HALFWORD_COEFF;
1057   d *= HIGH_HALFWORD_COEFF;
1058   d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1059
1060   return d;
1061 }
1062 #endif
1063
1064 #ifdef L_floatdisf
1065 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1066 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1067 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1068 #define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT)
1069
1070 /* Define codes for all the float formats that we know of.  Note
1071    that this is copied from real.h.  */
1072    
1073 #define UNKNOWN_FLOAT_FORMAT 0
1074 #define IEEE_FLOAT_FORMAT 1
1075 #define VAX_FLOAT_FORMAT 2
1076 #define IBM_FLOAT_FORMAT 3
1077
1078 /* Default to IEEE float if not specified.  Nearly all machines use it.  */
1079 #ifndef HOST_FLOAT_FORMAT
1080 #define HOST_FLOAT_FORMAT       IEEE_FLOAT_FORMAT
1081 #endif
1082
1083 #if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1084 #define DF_SIZE 53
1085 #define SF_SIZE 24
1086 #endif
1087
1088 #if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
1089 #define DF_SIZE 56
1090 #define SF_SIZE 24
1091 #endif
1092
1093 #if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
1094 #define DF_SIZE 56
1095 #define SF_SIZE 24
1096 #endif
1097
1098 SFtype
1099 __floatdisf (DWtype u)
1100 {
1101   /* Do the calculation in DFmode
1102      so that we don't lose any of the precision of the high word
1103      while multiplying it.  */
1104   DFtype f;
1105
1106   /* Protect against double-rounding error.
1107      Represent any low-order bits, that might be truncated in DFmode,
1108      by a bit that won't be lost.  The bit can go in anywhere below the
1109      rounding position of the SFmode.  A fixed mask and bit position
1110      handles all usual configurations.  It doesn't handle the case
1111      of 128-bit DImode, however.  */
1112   if (DF_SIZE < DI_SIZE
1113       && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1114     {
1115 #define REP_BIT ((UDWtype) 1 << (DI_SIZE - DF_SIZE))
1116       if (! (- ((DWtype) 1 << DF_SIZE) < u
1117              && u < ((DWtype) 1 << DF_SIZE)))
1118         {
1119           if ((UDWtype) u & (REP_BIT - 1))
1120             u |= REP_BIT;
1121         }
1122     }
1123   f = (Wtype) (u >> WORD_SIZE);
1124   f *= HIGH_HALFWORD_COEFF;
1125   f *= HIGH_HALFWORD_COEFF;
1126   f += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1127
1128   return (SFtype) f;
1129 }
1130 #endif
1131
1132 #if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
1133 /* Reenable the normal types, in case limits.h needs them.  */
1134 #undef char
1135 #undef short
1136 #undef int
1137 #undef long
1138 #undef unsigned
1139 #undef float
1140 #undef double
1141 #undef MIN
1142 #undef MAX
1143 #include <limits.h>
1144
1145 UWtype
1146 __fixunsxfSI (XFtype a)
1147 {
1148   if (a >= - (DFtype) LONG_MIN)
1149     return (Wtype) (a + LONG_MIN) - LONG_MIN;
1150   return (Wtype) a;
1151 }
1152 #endif
1153
1154 #ifdef L_fixunsdfsi
1155 /* Reenable the normal types, in case limits.h needs them.  */
1156 #undef char
1157 #undef short
1158 #undef int
1159 #undef long
1160 #undef unsigned
1161 #undef float
1162 #undef double
1163 #undef MIN
1164 #undef MAX
1165 #include <limits.h>
1166
1167 UWtype
1168 __fixunsdfSI (DFtype a)
1169 {
1170   if (a >= - (DFtype) LONG_MIN)
1171     return (Wtype) (a + LONG_MIN) - LONG_MIN;
1172   return (Wtype) a;
1173 }
1174 #endif
1175
1176 #ifdef L_fixunssfsi
1177 /* Reenable the normal types, in case limits.h needs them.  */
1178 #undef char
1179 #undef short
1180 #undef int
1181 #undef long
1182 #undef unsigned
1183 #undef float
1184 #undef double
1185 #undef MIN
1186 #undef MAX
1187 #include <limits.h>
1188
1189 UWtype
1190 __fixunssfSI (SFtype a)
1191 {
1192   if (a >= - (SFtype) LONG_MIN)
1193     return (Wtype) (a + LONG_MIN) - LONG_MIN;
1194   return (Wtype) a;
1195 }
1196 #endif
1197 \f
1198 /* From here on down, the routines use normal data types.  */
1199
1200 #define SItype bogus_type
1201 #define USItype bogus_type
1202 #define DItype bogus_type
1203 #define UDItype bogus_type
1204 #define SFtype bogus_type
1205 #define DFtype bogus_type
1206 #undef Wtype
1207 #undef UWtype
1208 #undef HWtype
1209 #undef UHWtype
1210 #undef DWtype
1211 #undef UDWtype
1212
1213 #undef char
1214 #undef short
1215 #undef int
1216 #undef long
1217 #undef unsigned
1218 #undef float
1219 #undef double
1220 \f
1221 #ifdef L__gcc_bcmp
1222
1223 /* Like bcmp except the sign is meaningful.
1224    Result is negative if S1 is less than S2,
1225    positive if S1 is greater, 0 if S1 and S2 are equal.  */
1226
1227 int
1228 __gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
1229 {
1230   while (size > 0)
1231     {
1232       unsigned char c1 = *s1++, c2 = *s2++;
1233       if (c1 != c2)
1234         return c1 - c2;
1235       size--;
1236     }
1237   return 0;
1238 }
1239
1240 #endif
1241 \f\f
1242 #ifdef L__dummy
1243 void
1244 __dummy (void) {}
1245 #endif
1246
1247 #ifdef L_varargs
1248 #ifdef __i860__
1249 #if defined(__svr4__) || defined(__alliant__)
1250         asm ("  .text");
1251         asm ("  .align  4");
1252
1253 /* The Alliant needs the added underscore.  */
1254         asm (".globl    __builtin_saveregs");
1255 asm ("__builtin_saveregs:");
1256         asm (".globl    ___builtin_saveregs");
1257 asm ("___builtin_saveregs:");
1258
1259         asm ("  andnot  0x0f,%sp,%sp"); /* round down to 16-byte boundary */
1260         asm ("  adds    -96,%sp,%sp");  /* allocate stack space for reg save
1261                                            area and also for a new va_list
1262                                            structure */
1263         /* Save all argument registers in the arg reg save area.  The
1264            arg reg save area must have the following layout (according
1265            to the svr4 ABI):
1266
1267                 struct {
1268                   union  {
1269                     float freg[8];
1270                     double dreg[4];
1271                   } float_regs;
1272                   long  ireg[12];
1273                 };
1274         */
1275
1276         asm ("  fst.q   %f8,  0(%sp)"); /* save floating regs (f8-f15)  */
1277         asm ("  fst.q   %f12,16(%sp)"); 
1278
1279         asm ("  st.l    %r16,32(%sp)"); /* save integer regs (r16-r27) */
1280         asm ("  st.l    %r17,36(%sp)"); 
1281         asm ("  st.l    %r18,40(%sp)");
1282         asm ("  st.l    %r19,44(%sp)");
1283         asm ("  st.l    %r20,48(%sp)");
1284         asm ("  st.l    %r21,52(%sp)");
1285         asm ("  st.l    %r22,56(%sp)");
1286         asm ("  st.l    %r23,60(%sp)");
1287         asm ("  st.l    %r24,64(%sp)");
1288         asm ("  st.l    %r25,68(%sp)");
1289         asm ("  st.l    %r26,72(%sp)");
1290         asm ("  st.l    %r27,76(%sp)");
1291
1292         asm ("  adds    80,%sp,%r16");  /* compute the address of the new
1293                                            va_list structure.  Put in into
1294                                            r16 so that it will be returned
1295                                            to the caller.  */
1296
1297         /* Initialize all fields of the new va_list structure.  This
1298            structure looks like:
1299
1300                 typedef struct {
1301                     unsigned long       ireg_used;
1302                     unsigned long       freg_used;
1303                     long                *reg_base;
1304                     long                *mem_ptr;
1305                 } va_list;
1306         */
1307
1308         asm ("  st.l    %r0, 0(%r16)"); /* nfixed */
1309         asm ("  st.l    %r0, 4(%r16)"); /* nfloating */
1310         asm ("  st.l    %sp, 8(%r16)"); /* __va_ctl points to __va_struct.  */
1311         asm ("  bri     %r1");          /* delayed return */
1312         asm ("  st.l    %r28,12(%r16)"); /* pointer to overflow args */
1313
1314 #else /* not __svr4__ */
1315 #if defined(__PARAGON__)
1316         /*
1317          *      we'll use SVR4-ish varargs but need SVR3.2 assembler syntax,
1318          *      and we stand a better chance of hooking into libraries
1319          *      compiled by PGI.  [andyp@ssd.intel.com]
1320          */
1321         asm ("  .text");
1322         asm ("  .align  4");
1323         asm (".globl    __builtin_saveregs");
1324 asm ("__builtin_saveregs:");
1325         asm (".globl    ___builtin_saveregs");
1326 asm ("___builtin_saveregs:");
1327
1328         asm ("  andnot  0x0f,sp,sp");   /* round down to 16-byte boundary */
1329         asm ("  adds    -96,sp,sp");    /* allocate stack space for reg save
1330                                            area and also for a new va_list
1331                                            structure */
1332         /* Save all argument registers in the arg reg save area.  The
1333            arg reg save area must have the following layout (according
1334            to the svr4 ABI):
1335
1336                 struct {
1337                   union  {
1338                     float freg[8];
1339                     double dreg[4];
1340                   } float_regs;
1341                   long  ireg[12];
1342                 };
1343         */
1344
1345         asm ("  fst.q   f8,  0(sp)");
1346         asm ("  fst.q   f12,16(sp)"); 
1347         asm ("  st.l    r16,32(sp)");
1348         asm ("  st.l    r17,36(sp)"); 
1349         asm ("  st.l    r18,40(sp)");
1350         asm ("  st.l    r19,44(sp)");
1351         asm ("  st.l    r20,48(sp)");
1352         asm ("  st.l    r21,52(sp)");
1353         asm ("  st.l    r22,56(sp)");
1354         asm ("  st.l    r23,60(sp)");
1355         asm ("  st.l    r24,64(sp)");
1356         asm ("  st.l    r25,68(sp)");
1357         asm ("  st.l    r26,72(sp)");
1358         asm ("  st.l    r27,76(sp)");
1359
1360         asm ("  adds    80,sp,r16");  /* compute the address of the new
1361                                            va_list structure.  Put in into
1362                                            r16 so that it will be returned
1363                                            to the caller.  */
1364
1365         /* Initialize all fields of the new va_list structure.  This
1366            structure looks like:
1367
1368                 typedef struct {
1369                     unsigned long       ireg_used;
1370                     unsigned long       freg_used;
1371                     long                *reg_base;
1372                     long                *mem_ptr;
1373                 } va_list;
1374         */
1375
1376         asm ("  st.l    r0, 0(r16)"); /* nfixed */
1377         asm ("  st.l    r0, 4(r16)"); /* nfloating */
1378         asm ("  st.l    sp, 8(r16)"); /* __va_ctl points to __va_struct.  */
1379         asm ("  bri     r1");           /* delayed return */
1380         asm ("   st.l   r28,12(r16)"); /* pointer to overflow args */
1381 #else /* not __PARAGON__ */
1382         asm ("  .text");
1383         asm ("  .align  4");
1384
1385         asm (".globl    ___builtin_saveregs");
1386         asm ("___builtin_saveregs:");
1387         asm ("  mov     sp,r30");
1388         asm ("  andnot  0x0f,sp,sp");
1389         asm ("  adds    -96,sp,sp");  /* allocate sufficient space on the stack */
1390
1391 /* Fill in the __va_struct.  */
1392         asm ("  st.l    r16, 0(sp)"); /* save integer regs (r16-r27) */
1393         asm ("  st.l    r17, 4(sp)"); /* int    fixed[12] */
1394         asm ("  st.l    r18, 8(sp)");
1395         asm ("  st.l    r19,12(sp)");
1396         asm ("  st.l    r20,16(sp)");
1397         asm ("  st.l    r21,20(sp)");
1398         asm ("  st.l    r22,24(sp)");
1399         asm ("  st.l    r23,28(sp)");
1400         asm ("  st.l    r24,32(sp)");
1401         asm ("  st.l    r25,36(sp)");
1402         asm ("  st.l    r26,40(sp)");
1403         asm ("  st.l    r27,44(sp)");
1404
1405         asm ("  fst.q   f8, 48(sp)"); /* save floating regs (f8-f15) */
1406         asm ("  fst.q   f12,64(sp)"); /* int floating[8] */
1407
1408 /* Fill in the __va_ctl.  */
1409         asm ("  st.l    sp, 80(sp)"); /* __va_ctl points to __va_struct.  */
1410         asm ("  st.l    r28,84(sp)"); /* pointer to more args */
1411         asm ("  st.l    r0, 88(sp)"); /* nfixed */
1412         asm ("  st.l    r0, 92(sp)"); /* nfloating */
1413
1414         asm ("  adds    80,sp,r16");  /* return address of the __va_ctl.  */
1415         asm ("  bri     r1");
1416         asm ("  mov     r30,sp");
1417                                 /* recover stack and pass address to start 
1418                                    of data.  */
1419 #endif /* not __PARAGON__ */
1420 #endif /* not __svr4__ */
1421 #else /* not __i860__ */
1422 #ifdef __sparc__
1423         asm (".global __builtin_saveregs");
1424         asm ("__builtin_saveregs:");
1425         asm (".global ___builtin_saveregs");
1426         asm ("___builtin_saveregs:");
1427 #ifdef NEED_PROC_COMMAND
1428         asm (".proc 020");
1429 #endif
1430         asm ("st %i0,[%fp+68]");
1431         asm ("st %i1,[%fp+72]");
1432         asm ("st %i2,[%fp+76]");
1433         asm ("st %i3,[%fp+80]");
1434         asm ("st %i4,[%fp+84]");
1435         asm ("retl");
1436         asm ("st %i5,[%fp+88]");
1437 #ifdef NEED_TYPE_COMMAND
1438         asm (".type __builtin_saveregs,#function");
1439         asm (".size __builtin_saveregs,.-__builtin_saveregs");
1440 #endif
1441 #else /* not __sparc__ */
1442 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1443
1444   asm ("        .text");
1445 #ifdef __mips16
1446   asm ("        .set nomips16");
1447 #endif
1448   asm ("        .ent __builtin_saveregs");
1449   asm ("        .globl __builtin_saveregs");
1450   asm ("__builtin_saveregs:");
1451   asm ("        sw      $4,0($30)");
1452   asm ("        sw      $5,4($30)");
1453   asm ("        sw      $6,8($30)");
1454   asm ("        sw      $7,12($30)");
1455   asm ("        j       $31");
1456   asm ("        .end __builtin_saveregs");
1457 #else /* not __mips__, etc.  */
1458
1459 void * ATTRIBUTE_NORETURN
1460 __builtin_saveregs ()
1461 {
1462   abort ();
1463 }
1464
1465 #endif /* not __mips__ */
1466 #endif /* not __sparc__ */
1467 #endif /* not __i860__ */
1468 #endif
1469 \f
1470 #ifdef L_eprintf
1471 #ifndef inhibit_libc
1472
1473 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1474 #include <stdio.h>
1475 /* This is used by the `assert' macro.  */
1476 void
1477 __eprintf (const char *string, const char *expression,
1478            unsigned int line, const char *filename)
1479 {
1480   fprintf (stderr, string, expression, line, filename);
1481   fflush (stderr);
1482   abort ();
1483 }
1484
1485 #endif
1486 #endif
1487
1488 #ifdef L_bb
1489
1490 /* Structure emitted by -a  */
1491 struct bb
1492 {
1493   long zero_word;
1494   const char *filename;
1495   long *counts;
1496   long ncounts;
1497   struct bb *next;
1498   const unsigned long *addresses;
1499
1500   /* Older GCC's did not emit these fields.  */
1501   long nwords;
1502   const char **functions;
1503   const long *line_nums;
1504   const char **filenames;
1505   char *flags;
1506 };
1507
1508 #ifdef BLOCK_PROFILER_CODE
1509 BLOCK_PROFILER_CODE
1510 #else
1511 #ifndef inhibit_libc
1512
1513 /* Simple minded basic block profiling output dumper for
1514    systems that don't provide tcov support.  At present,
1515    it requires atexit and stdio.  */
1516
1517 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1518 #include <stdio.h>
1519 char *ctime PARAMS ((const time_t *));
1520
1521 #include "gbl-ctors.h"
1522 #include "gcov-io.h"
1523 #include <string.h>
1524 #ifdef TARGET_HAS_F_SETLKW
1525 #include <fcntl.h>
1526 #include <errno.h>
1527 #endif
1528
1529 static struct bb *bb_head;
1530
1531 static int num_digits (long value, int base) __attribute__ ((const));
1532
1533 /* Return the number of digits needed to print a value */
1534 /* __inline__ */ static int num_digits (long value, int base)
1535 {
1536   int minus = (value < 0 && base != 16);
1537   unsigned long v = (minus) ? -value : value;
1538   int ret = minus;
1539
1540   do
1541     {
1542       v /= base;
1543       ret++;
1544     }
1545   while (v);
1546
1547   return ret;
1548 }
1549
1550 void
1551 __bb_exit_func (void)
1552 {
1553   FILE *da_file, *file;
1554   long time_value;
1555   int i;
1556
1557   if (bb_head == 0)
1558     return;
1559
1560   i = strlen (bb_head->filename) - 3;
1561
1562   if (!strcmp (bb_head->filename+i, ".da"))
1563     {
1564       /* Must be -fprofile-arcs not -a.
1565          Dump data in a form that gcov expects.  */
1566
1567       struct bb *ptr;
1568
1569       for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1570         {
1571           int firstchar;
1572
1573           /* Make sure the output file exists -
1574              but don't clobber exiting data.  */
1575           if ((da_file = fopen (ptr->filename, "a")) != 0)
1576             fclose (da_file);
1577
1578           /* Need to re-open in order to be able to write from the start.  */
1579           da_file = fopen (ptr->filename, "r+b");
1580           /* Some old systems might not allow the 'b' mode modifier.
1581              Therefore, try to open without it.  This can lead to a race
1582              condition so that when you delete and re-create the file, the
1583              file might be opened in text mode, but then, you shouldn't
1584              delete the file in the first place.  */
1585           if (da_file == 0)
1586             da_file = fopen (ptr->filename, "r+");
1587           if (da_file == 0)
1588             {
1589               fprintf (stderr, "arc profiling: Can't open output file %s.\n",
1590                        ptr->filename);
1591               continue;
1592             }
1593
1594           /* After a fork, another process might try to read and/or write
1595              the same file simultanously.  So if we can, lock the file to
1596              avoid race conditions.  */
1597 #if defined (TARGET_HAS_F_SETLKW)
1598           {
1599             struct flock s_flock;
1600
1601             s_flock.l_type = F_WRLCK;
1602             s_flock.l_whence = SEEK_SET;
1603             s_flock.l_start = 0;
1604             s_flock.l_len = 1;
1605             s_flock.l_pid = getpid ();
1606
1607             while (fcntl (fileno (da_file), F_SETLKW, &s_flock)
1608                    && errno == EINTR);
1609           }
1610 #endif
1611
1612           /* If the file is not empty, and the number of counts in it is the
1613              same, then merge them in.  */
1614           firstchar = fgetc (da_file);
1615           if (firstchar == EOF)
1616             {
1617               if (ferror (da_file))
1618                 {
1619                   fprintf (stderr, "arc profiling: Can't read output file ");
1620                   perror (ptr->filename);
1621                 }
1622             }
1623           else
1624             {
1625               long n_counts = 0;
1626               
1627               if (ungetc (firstchar, da_file) == EOF)
1628                 rewind (da_file);
1629               if (__read_long (&n_counts, da_file, 8) != 0)
1630                 {
1631                   fprintf (stderr, "arc profiling: Can't read output file %s.\n",
1632                            ptr->filename);
1633                   continue;
1634                 }
1635
1636               if (n_counts == ptr->ncounts)
1637                 {
1638                   int i;
1639
1640                   for (i = 0; i < n_counts; i++)
1641                     {
1642                       long v = 0;
1643
1644                       if (__read_long (&v, da_file, 8) != 0)
1645                         {
1646                           fprintf (stderr, "arc profiling: Can't read output file %s.\n",
1647                                    ptr->filename);
1648                           break;
1649                         }
1650                       ptr->counts[i] += v;
1651                     }
1652                 }
1653
1654             }
1655
1656           rewind (da_file);
1657
1658           /* ??? Should first write a header to the file.  Preferably, a 4 byte
1659              magic number, 4 bytes containing the time the program was
1660              compiled, 4 bytes containing the last modification time of the
1661              source file, and 4 bytes indicating the compiler options used.
1662
1663              That way we can easily verify that the proper source/executable/
1664              data file combination is being used from gcov.  */
1665
1666           if (__write_long (ptr->ncounts, da_file, 8) != 0)
1667             {
1668               
1669               fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1670                        ptr->filename);
1671             }
1672           else
1673             {
1674               int j;
1675               long *count_ptr = ptr->counts;
1676               int ret = 0;
1677               for (j = ptr->ncounts; j > 0; j--)
1678                 {
1679                   if (__write_long (*count_ptr, da_file, 8) != 0)
1680                     {
1681                       ret=1;
1682                       break;
1683                     }
1684                   count_ptr++;
1685                 }
1686               if (ret)
1687                 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1688                          ptr->filename);
1689             }
1690           
1691           if (fclose (da_file) == EOF)
1692             fprintf (stderr, "arc profiling: Error closing output file %s.\n",
1693                      ptr->filename);
1694         }
1695
1696       return;
1697     }
1698
1699   /* Must be basic block profiling.  Emit a human readable output file.  */
1700
1701   file = fopen ("bb.out", "a");
1702
1703   if (!file)
1704     perror ("bb.out");
1705
1706   else
1707     {
1708       struct bb *ptr;
1709
1710       /* This is somewhat type incorrect, but it avoids worrying about
1711          exactly where time.h is included from.  It should be ok unless
1712          a void * differs from other pointer formats, or if sizeof (long)
1713          is < sizeof (time_t).  It would be nice if we could assume the
1714          use of rationale standards here.  */
1715
1716       time ((void *) &time_value);
1717       fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value));
1718
1719       /* We check the length field explicitly in order to allow compatibility
1720          with older GCC's which did not provide it.  */
1721
1722       for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1723         {
1724           int i;
1725           int func_p    = (ptr->nwords >= (long) sizeof (struct bb)
1726                            && ptr->nwords <= 1000
1727                            && ptr->functions);
1728           int line_p    = (func_p && ptr->line_nums);
1729           int file_p    = (func_p && ptr->filenames);
1730           int addr_p    = (ptr->addresses != 0);
1731           long ncounts  = ptr->ncounts;
1732           long cnt_max  = 0;
1733           long line_max = 0;
1734           long addr_max = 0;
1735           int file_len  = 0;
1736           int func_len  = 0;
1737           int blk_len   = num_digits (ncounts, 10);
1738           int cnt_len;
1739           int line_len;
1740           int addr_len;
1741
1742           fprintf (file, "File %s, %ld basic blocks \n\n",
1743                    ptr->filename, ncounts);
1744
1745           /* Get max values for each field.  */
1746           for (i = 0; i < ncounts; i++)
1747             {
1748               const char *p;
1749               int len;
1750
1751               if (cnt_max < ptr->counts[i])
1752                 cnt_max = ptr->counts[i];
1753
1754               if (addr_p && (unsigned long) addr_max < ptr->addresses[i])
1755                 addr_max = ptr->addresses[i];
1756
1757               if (line_p && line_max < ptr->line_nums[i])
1758                 line_max = ptr->line_nums[i];
1759
1760               if (func_p)
1761                 {
1762                   p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>";
1763                   len = strlen (p);
1764                   if (func_len < len)
1765                     func_len = len;
1766                 }
1767
1768               if (file_p)
1769                 {
1770                   p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>";
1771                   len = strlen (p);
1772                   if (file_len < len)
1773                     file_len = len;
1774                 }
1775             }
1776
1777           addr_len = num_digits (addr_max, 16);
1778           cnt_len  = num_digits (cnt_max, 10);
1779           line_len = num_digits (line_max, 10);
1780
1781           /* Now print out the basic block information.  */
1782           for (i = 0; i < ncounts; i++)
1783             {
1784               fprintf (file,
1785                        "    Block #%*d: executed %*ld time(s)",
1786                        blk_len, i+1,
1787                        cnt_len, ptr->counts[i]);
1788
1789               if (addr_p)
1790                 fprintf (file, " address= 0x%.*lx", addr_len,
1791                          ptr->addresses[i]);
1792
1793               if (func_p)
1794                 fprintf (file, " function= %-*s", func_len,
1795                          (ptr->functions[i]) ? ptr->functions[i] : "<none>");
1796
1797               if (line_p)
1798                 fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]);
1799
1800               if (file_p)
1801                 fprintf (file, " file= %s",
1802                          (ptr->filenames[i]) ? ptr->filenames[i] : "<none>");
1803
1804               fprintf (file, "\n");
1805             }
1806
1807           fprintf (file, "\n");
1808           fflush (file);
1809         }
1810
1811       fprintf (file, "\n\n");
1812       fclose (file);
1813     }
1814 }
1815
1816 void
1817 __bb_init_func (struct bb *blocks)
1818 {
1819   /* User is supposed to check whether the first word is non-0,
1820      but just in case....  */
1821
1822   if (blocks->zero_word)
1823     return;
1824
1825   /* Initialize destructor.  */
1826   if (!bb_head)
1827     atexit (__bb_exit_func);
1828
1829   /* Set up linked list.  */
1830   blocks->zero_word = 1;
1831   blocks->next = bb_head;
1832   bb_head = blocks;
1833 }
1834
1835 /* Called before fork or exec - write out profile information gathered so
1836    far and reset it to zero.  This avoids duplication or loss of the
1837    profile information gathered so far.  */
1838 void
1839 __bb_fork_func (void)
1840 {
1841   struct bb *ptr;
1842
1843   __bb_exit_func ();
1844   for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1845     {
1846       long i;
1847       for (i = ptr->ncounts - 1; i >= 0; i--)
1848         ptr->counts[i] = 0;
1849     }
1850 }
1851
1852 #ifndef MACHINE_STATE_SAVE
1853 #define MACHINE_STATE_SAVE(ID)
1854 #endif
1855 #ifndef MACHINE_STATE_RESTORE
1856 #define MACHINE_STATE_RESTORE(ID)
1857 #endif
1858
1859 /* Number of buckets in hashtable of basic block addresses.  */
1860
1861 #define BB_BUCKETS 311
1862
1863 /* Maximum length of string in file bb.in.  */
1864
1865 #define BBINBUFSIZE 500
1866
1867 struct bb_edge
1868 {
1869   struct bb_edge *next;
1870   unsigned long src_addr;
1871   unsigned long dst_addr;
1872   unsigned long count;
1873 };
1874
1875 enum bb_func_mode
1876 {
1877   TRACE_KEEP = 0, TRACE_ON = 1, TRACE_OFF = 2
1878 };
1879
1880 struct bb_func
1881 {
1882   struct bb_func *next;
1883   char *funcname;
1884   char *filename;
1885   enum bb_func_mode mode;
1886 };
1887
1888 /* This is the connection to the outside world.
1889    The BLOCK_PROFILER macro must set __bb.blocks
1890    and __bb.blockno.  */
1891
1892 struct {
1893   unsigned long blockno;
1894   struct bb *blocks;
1895 } __bb;
1896
1897 /* Vars to store addrs of source and destination basic blocks 
1898    of a jump.  */
1899
1900 static unsigned long bb_src = 0;
1901 static unsigned long bb_dst = 0;
1902
1903 static FILE *bb_tracefile = (FILE *) 0;
1904 static struct bb_edge **bb_hashbuckets = (struct bb_edge **) 0;
1905 static struct bb_func *bb_func_head = (struct bb_func *) 0;
1906 static unsigned long bb_callcount = 0;
1907 static int bb_mode = 0;
1908
1909 static unsigned long *bb_stack = (unsigned long *) 0;
1910 static size_t bb_stacksize = 0;
1911
1912 static int reported = 0;
1913
1914 /* Trace modes:
1915 Always             :   Print execution frequencies of basic blocks
1916                        to file bb.out.
1917 bb_mode & 1 != 0   :   Dump trace of basic blocks to file bbtrace[.gz]
1918 bb_mode & 2 != 0   :   Print jump frequencies to file bb.out.
1919 bb_mode & 4 != 0   :   Cut call instructions from basic block flow.
1920 bb_mode & 8 != 0   :   Insert return instructions in basic block flow.
1921 */
1922
1923 #ifdef HAVE_POPEN
1924
1925 /*#include <sys/types.h>*/
1926 #include <sys/stat.h>
1927 /*#include <malloc.h>*/
1928
1929 /* Commands executed by gopen.  */
1930
1931 #define GOPENDECOMPRESS "gzip -cd "
1932 #define GOPENCOMPRESS "gzip -c >"
1933
1934 /* Like fopen but pipes through gzip.  mode may only be "r" or "w".
1935    If it does not compile, simply replace gopen by fopen and delete
1936    '.gz' from any first parameter to gopen.  */
1937
1938 static FILE *
1939 gopen (char *fn, char *mode)
1940 {
1941   int use_gzip;
1942   char *p;
1943
1944   if (mode[1])
1945     return (FILE *) 0;
1946
1947   if (mode[0] != 'r' && mode[0] != 'w') 
1948     return (FILE *) 0;
1949
1950   p = fn + strlen (fn)-1;
1951   use_gzip = ((p[-1] == '.' && (p[0] == 'Z' || p[0] == 'z'))
1952               || (p[-2] == '.' && p[-1] == 'g' && p[0] == 'z'));
1953
1954   if (use_gzip)
1955     {
1956       if (mode[0]=='r')
1957         {
1958           FILE *f;
1959           char *s = (char *) malloc (sizeof (char) * strlen (fn)
1960                                      + sizeof (GOPENDECOMPRESS));
1961           strcpy (s, GOPENDECOMPRESS);
1962           strcpy (s + (sizeof (GOPENDECOMPRESS)-1), fn);
1963           f = popen (s, mode);
1964           free (s);
1965           return f;
1966         }
1967
1968       else
1969         {
1970           FILE *f;
1971           char *s = (char *) malloc (sizeof (char) * strlen (fn)
1972                                      + sizeof (GOPENCOMPRESS));
1973           strcpy (s, GOPENCOMPRESS);
1974           strcpy (s + (sizeof (GOPENCOMPRESS)-1), fn);
1975           if (!(f = popen (s, mode)))
1976             f = fopen (s, mode);
1977           free (s);
1978           return f;
1979         }
1980     }
1981
1982   else
1983     return fopen (fn, mode);
1984 }
1985
1986 static int
1987 gclose (FILE *f)
1988 {
1989   struct stat buf;
1990
1991   if (f != 0)
1992     {
1993       if (!fstat (fileno (f), &buf) && S_ISFIFO (buf.st_mode))
1994         return pclose (f);
1995
1996       return fclose (f);
1997     }
1998   return 0;
1999 }
2000
2001 #endif /* HAVE_POPEN */
2002
2003 /* Called once per program.  */
2004
2005 static void
2006 __bb_exit_trace_func (void)
2007 {
2008   FILE *file = fopen ("bb.out", "a");
2009   struct bb_func *f;
2010   struct bb *b;
2011         
2012   if (!file)
2013     perror ("bb.out");
2014
2015   if (bb_mode & 1)
2016     {
2017       if (!bb_tracefile)
2018         perror ("bbtrace");
2019       else
2020 #ifdef HAVE_POPEN
2021         gclose (bb_tracefile);
2022 #else
2023         fclose (bb_tracefile);
2024 #endif /* HAVE_POPEN */
2025     }
2026
2027   /* Check functions in `bb.in'.  */
2028
2029   if (file)
2030     {
2031       long time_value;
2032       const struct bb_func *p;
2033       int printed_something = 0;
2034       struct bb *ptr;
2035       long blk;
2036
2037       /* This is somewhat type incorrect.  */
2038       time ((void *) &time_value);
2039
2040       for (p = bb_func_head; p != (struct bb_func *) 0; p = p->next)
2041         {
2042           for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
2043             {
2044               if (!ptr->filename || (p->filename != (char *) 0 && strcmp (p->filename, ptr->filename)))
2045                 continue;
2046               for (blk = 0; blk < ptr->ncounts; blk++)
2047                 {
2048                   if (!strcmp (p->funcname, ptr->functions[blk]))
2049                     goto found;
2050                 }
2051             }
2052   
2053           if (!printed_something)
2054             {
2055               fprintf (file, "Functions in `bb.in' not executed during basic block profiling on %s\n", ctime ((void *) &time_value));
2056               printed_something = 1;
2057             }
2058
2059           fprintf (file, "\tFunction %s", p->funcname);
2060           if (p->filename)
2061               fprintf (file, " of file %s", p->filename);
2062           fprintf (file, "\n" );
2063   
2064 found:        ;
2065         }
2066
2067       if (printed_something)
2068        fprintf (file, "\n");
2069
2070     }
2071
2072   if (bb_mode & 2)
2073     {
2074       if (!bb_hashbuckets)
2075         {
2076           if (!reported)
2077             {
2078               fprintf (stderr, "Profiler: out of memory\n");
2079               reported = 1;
2080             }
2081           return;
2082         }
2083     
2084       else if (file)
2085         {
2086           long time_value;
2087           int i;
2088           unsigned long addr_max = 0;
2089           unsigned long cnt_max  = 0;
2090           int cnt_len;
2091           int addr_len;
2092     
2093           /* This is somewhat type incorrect, but it avoids worrying about
2094              exactly where time.h is included from.  It should be ok unless
2095              a void * differs from other pointer formats, or if sizeof (long)
2096              is < sizeof (time_t).  It would be nice if we could assume the
2097              use of rationale standards here.  */
2098     
2099           time ((void *) &time_value);
2100           fprintf (file, "Basic block jump tracing");
2101
2102           switch (bb_mode & 12)
2103             {
2104               case 0:
2105                 fprintf (file, " (with call)");
2106               break;
2107
2108               case 4:
2109                 /* Print nothing.  */
2110               break;
2111
2112               case 8:
2113                 fprintf (file, " (with call & ret)");
2114               break;
2115
2116               case 12:
2117                 fprintf (file, " (with ret)");
2118               break;
2119             }
2120
2121           fprintf (file, " finished on %s\n", ctime ((void *) &time_value));
2122     
2123           for (i = 0; i < BB_BUCKETS; i++)
2124             {
2125                struct bb_edge *bucket = bb_hashbuckets[i];
2126                for ( ; bucket; bucket = bucket->next )
2127                  {
2128                    if (addr_max < bucket->src_addr) 
2129                      addr_max = bucket->src_addr;
2130                    if (addr_max < bucket->dst_addr) 
2131                      addr_max = bucket->dst_addr;
2132                    if (cnt_max < bucket->count) 
2133                      cnt_max = bucket->count;
2134                  }
2135             }
2136           addr_len = num_digits (addr_max, 16);
2137           cnt_len  = num_digits (cnt_max, 10);
2138     
2139           for ( i = 0; i < BB_BUCKETS; i++)
2140             {
2141                struct bb_edge *bucket = bb_hashbuckets[i];
2142                for ( ; bucket; bucket = bucket->next )
2143                  {
2144                    fprintf (file,
2145         "Jump from block 0x%.*lx to block 0x%.*lx executed %*lu time(s)\n", 
2146                             addr_len, bucket->src_addr, 
2147                             addr_len, bucket->dst_addr, 
2148                             cnt_len, bucket->count);
2149                  }
2150             }
2151   
2152           fprintf (file, "\n");
2153
2154         }
2155     }
2156
2157    if (file)
2158      fclose (file);
2159
2160    /* Free allocated memory.  */
2161
2162    f = bb_func_head;
2163    while (f)
2164      {
2165        struct bb_func *old = f;
2166
2167        f = f->next;
2168        if (old->funcname) free (old->funcname);
2169        if (old->filename) free (old->filename);
2170        free (old);
2171      }
2172
2173    if (bb_stack)
2174      free (bb_stack);
2175
2176    if (bb_hashbuckets)
2177      {
2178        int i;
2179
2180        for (i = 0; i < BB_BUCKETS; i++)
2181          {
2182            struct bb_edge *old, *bucket = bb_hashbuckets[i];
2183
2184            while (bucket)
2185              {
2186                old = bucket;
2187                bucket = bucket->next;
2188                free (old);
2189              }
2190          }
2191        free (bb_hashbuckets);
2192      }
2193
2194    for (b = bb_head; b; b = b->next)
2195      if (b->flags) free (b->flags);
2196 }
2197
2198 /* Called once per program.  */
2199
2200 static void
2201 __bb_init_prg (void)
2202 {
2203   FILE *file;
2204   char buf[BBINBUFSIZE];
2205   const char *p;
2206   const char *pos;
2207   enum bb_func_mode m;
2208   int i;
2209
2210   /* Initialize destructor.  */
2211   atexit (__bb_exit_func);
2212
2213   if (!(file = fopen ("bb.in", "r")))
2214     return;
2215
2216   while(fgets (buf, BBINBUFSIZE, file) != 0)
2217     {
2218       i = strlen (buf);
2219       if (buf[i] == '\n')
2220         buf[i--] = '\0';
2221
2222       p = buf;
2223       if (*p == '-') 
2224         { 
2225           m = TRACE_OFF; 
2226           p++; 
2227         }
2228       else 
2229         { 
2230           m = TRACE_ON; 
2231         }
2232       if (!strcmp (p, "__bb_trace__"))
2233         bb_mode |= 1;
2234       else if (!strcmp (p, "__bb_jumps__"))
2235         bb_mode |= 2;
2236       else if (!strcmp (p, "__bb_hidecall__"))
2237         bb_mode |= 4;
2238       else if (!strcmp (p, "__bb_showret__"))
2239         bb_mode |= 8;
2240       else 
2241         {
2242           struct bb_func *f = (struct bb_func *) malloc (sizeof (struct bb_func));
2243           if (f)
2244             {
2245               unsigned long l;
2246               f->next = bb_func_head;
2247               if ((pos = strchr (p, ':')))
2248                 {
2249                   if (!(f->funcname = (char *) malloc (strlen (pos+1)+1)))
2250                     continue;
2251                   strcpy (f->funcname, pos+1);
2252                   l = pos-p;
2253                   if ((f->filename = (char *) malloc (l+1)))
2254                     {
2255                       strncpy (f->filename, p, l);
2256                       f->filename[l] = '\0';
2257                     }
2258                   else
2259                     f->filename = (char *) 0;
2260                 }
2261               else
2262                 {
2263                   if (!(f->funcname = (char *) malloc (strlen (p)+1)))
2264                     continue;
2265                   strcpy (f->funcname, p);
2266                   f->filename = (char *) 0;
2267                 }
2268               f->mode = m;
2269               bb_func_head = f;
2270             }
2271          }
2272     }
2273   fclose (file);
2274
2275 #ifdef HAVE_POPEN 
2276
2277   if (bb_mode & 1)
2278       bb_tracefile = gopen ("bbtrace.gz", "w");
2279
2280 #else
2281
2282   if (bb_mode & 1)
2283       bb_tracefile = fopen ("bbtrace", "w");
2284
2285 #endif /* HAVE_POPEN */
2286
2287   if (bb_mode & 2)
2288     {
2289       bb_hashbuckets = (struct bb_edge **) 
2290                    malloc (BB_BUCKETS * sizeof (struct bb_edge *));
2291       if (bb_hashbuckets)
2292         /* Use a loop here rather than calling bzero to avoid having to
2293            conditionalize its existance.  */
2294         for (i = 0; i < BB_BUCKETS; i++)
2295           bb_hashbuckets[i] = 0;
2296     }
2297
2298   if (bb_mode & 12)
2299     {
2300       bb_stacksize = 10;
2301       bb_stack = (unsigned long *) malloc (bb_stacksize * sizeof (*bb_stack));
2302     }
2303
2304   /* Initialize destructor.  */
2305   atexit (__bb_exit_trace_func);
2306 }
2307
2308 /* Called upon entering a basic block.  */
2309
2310 void
2311 __bb_trace_func (void)
2312 {
2313   struct bb_edge *bucket;
2314
2315   MACHINE_STATE_SAVE("1")
2316
2317   if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2318     goto skip;
2319
2320   bb_dst = __bb.blocks->addresses[__bb.blockno];
2321   __bb.blocks->counts[__bb.blockno]++;
2322
2323   if (bb_tracefile)
2324     {
2325       fwrite (&bb_dst, sizeof (unsigned long), 1, bb_tracefile);
2326     }
2327
2328   if (bb_hashbuckets)
2329     {
2330       struct bb_edge **startbucket, **oldnext;
2331
2332       oldnext = startbucket
2333         = & bb_hashbuckets[ (((int) bb_src*8) ^ (int) bb_dst) % BB_BUCKETS ];
2334       bucket = *startbucket;
2335
2336       for (bucket = *startbucket; bucket; 
2337            oldnext = &(bucket->next), bucket = *oldnext)
2338         {
2339           if (bucket->src_addr == bb_src
2340               && bucket->dst_addr == bb_dst)
2341             {
2342               bucket->count++;
2343               *oldnext = bucket->next;
2344               bucket->next = *startbucket;
2345               *startbucket = bucket;
2346               goto ret;
2347             }
2348         }
2349
2350       bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2351
2352       if (!bucket)
2353         {
2354           if (!reported)
2355             {
2356               fprintf (stderr, "Profiler: out of memory\n");
2357               reported = 1;
2358             }
2359         }
2360
2361       else
2362         {
2363           bucket->src_addr = bb_src;
2364           bucket->dst_addr = bb_dst;
2365           bucket->next = *startbucket;
2366           *startbucket = bucket;
2367           bucket->count = 1;
2368         }
2369     }
2370
2371 ret:
2372   bb_src = bb_dst;
2373
2374 skip:
2375   ;
2376
2377   MACHINE_STATE_RESTORE("1")
2378
2379 }
2380
2381 /* Called when returning from a function and `__bb_showret__' is set.  */
2382
2383 static void
2384 __bb_trace_func_ret (void)
2385 {
2386   struct bb_edge *bucket;
2387
2388   if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2389     goto skip;
2390
2391   if (bb_hashbuckets)
2392     {
2393       struct bb_edge **startbucket, **oldnext;
2394
2395       oldnext = startbucket
2396         = & bb_hashbuckets[ (((int) bb_dst * 8) ^ (int) bb_src) % BB_BUCKETS ];
2397       bucket = *startbucket;
2398
2399       for (bucket = *startbucket; bucket; 
2400            oldnext = &(bucket->next), bucket = *oldnext)
2401         {
2402           if (bucket->src_addr == bb_dst
2403                && bucket->dst_addr == bb_src)
2404             {
2405               bucket->count++;
2406               *oldnext = bucket->next;
2407               bucket->next = *startbucket;
2408               *startbucket = bucket;
2409               goto ret;
2410             }
2411         }
2412
2413       bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2414
2415       if (!bucket)
2416         {
2417           if (!reported)
2418             {
2419               fprintf (stderr, "Profiler: out of memory\n");
2420               reported = 1;
2421             }
2422         }
2423
2424       else
2425         {
2426           bucket->src_addr = bb_dst;
2427           bucket->dst_addr = bb_src;
2428           bucket->next = *startbucket;
2429           *startbucket = bucket;
2430           bucket->count = 1;
2431         }
2432     }
2433
2434 ret:
2435   bb_dst = bb_src;
2436
2437 skip:
2438   ;
2439
2440 }
2441
2442 /* Called upon entering the first function of a file.  */
2443
2444 static void
2445 __bb_init_file (struct bb *blocks)
2446 {
2447
2448   const struct bb_func *p;
2449   long blk, ncounts = blocks->ncounts;
2450   const char **functions = blocks->functions;
2451
2452   /* Set up linked list.  */
2453   blocks->zero_word = 1;
2454   blocks->next = bb_head;
2455   bb_head = blocks;
2456
2457   blocks->flags = 0;
2458   if (!bb_func_head
2459       || !(blocks->flags = (char *) malloc (sizeof (char) * blocks->ncounts)))
2460     return;
2461
2462   for (blk = 0; blk < ncounts; blk++)
2463     blocks->flags[blk] = 0;
2464
2465   for (blk = 0; blk < ncounts; blk++)
2466     {
2467       for (p = bb_func_head; p; p = p->next)
2468         {
2469           if (!strcmp (p->funcname, functions[blk])
2470               && (!p->filename || !strcmp (p->filename, blocks->filename)))
2471             {
2472               blocks->flags[blk] |= p->mode;
2473             }
2474         }
2475     }
2476
2477 }
2478
2479 /* Called when exiting from a function.  */
2480
2481 void
2482 __bb_trace_ret (void)
2483 {
2484
2485   MACHINE_STATE_SAVE("2")
2486
2487   if (bb_callcount)
2488     {
2489       if ((bb_mode & 12) && bb_stacksize > bb_callcount)
2490         {
2491           bb_src = bb_stack[bb_callcount];
2492           if (bb_mode & 8)
2493             __bb_trace_func_ret ();
2494         }
2495
2496       bb_callcount -= 1;
2497     }
2498
2499   MACHINE_STATE_RESTORE("2")
2500
2501 }
2502
2503 /* Called when entering a function.  */
2504
2505 void
2506 __bb_init_trace_func (struct bb *blocks, unsigned long blockno)
2507 {
2508   static int trace_init = 0;
2509
2510   MACHINE_STATE_SAVE("3")
2511
2512   if (!blocks->zero_word)
2513     { 
2514       if (!trace_init)
2515         { 
2516           trace_init = 1;
2517           __bb_init_prg ();
2518         }
2519       __bb_init_file (blocks);
2520     }
2521
2522   if (bb_callcount)
2523     {
2524
2525       bb_callcount += 1;
2526
2527       if (bb_mode & 12)
2528         {
2529           if (bb_callcount >= bb_stacksize)
2530             {
2531               size_t newsize = bb_callcount + 100;
2532
2533               bb_stack = (unsigned long *) realloc (bb_stack, newsize);
2534               if (! bb_stack)
2535                 {
2536                   if (!reported)
2537                     {
2538                       fprintf (stderr, "Profiler: out of memory\n");
2539                       reported = 1;
2540                     }
2541                   bb_stacksize = 0;
2542                   goto stack_overflow;
2543                 }
2544               bb_stacksize = newsize;
2545             }
2546           bb_stack[bb_callcount] = bb_src;
2547
2548           if (bb_mode & 4)
2549             bb_src = 0;
2550
2551         }
2552
2553 stack_overflow:;
2554
2555     }
2556
2557   else if (blocks->flags && (blocks->flags[blockno] & TRACE_ON))
2558     {
2559       bb_callcount = 1;
2560       bb_src = 0;
2561
2562       if (bb_stack)
2563           bb_stack[bb_callcount] = bb_src;
2564     }
2565
2566   MACHINE_STATE_RESTORE("3")
2567 }
2568
2569 #endif /* not inhibit_libc */
2570 #endif /* not BLOCK_PROFILER_CODE */
2571 #endif /* L_bb */
2572 \f
2573 #ifdef L_clear_cache
2574 /* Clear part of an instruction cache.  */
2575
2576 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
2577
2578 void
2579 __clear_cache (char *beg __attribute__((__unused__)),
2580                char *end __attribute__((__unused__)))
2581 {
2582 #ifdef CLEAR_INSN_CACHE 
2583   CLEAR_INSN_CACHE (beg, end);
2584 #else
2585 #ifdef INSN_CACHE_SIZE
2586   static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
2587   static int initialized;
2588   int offset;
2589   void *start_addr
2590   void *end_addr;
2591   typedef (*function_ptr) (void);
2592
2593 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
2594   /* It's cheaper to clear the whole cache.
2595      Put in a series of jump instructions so that calling the beginning
2596      of the cache will clear the whole thing.  */
2597
2598   if (! initialized)
2599     {
2600       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2601                  & -INSN_CACHE_LINE_WIDTH);
2602       int end_ptr = ptr + INSN_CACHE_SIZE;
2603
2604       while (ptr < end_ptr)
2605         {
2606           *(INSTRUCTION_TYPE *)ptr
2607             = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
2608           ptr += INSN_CACHE_LINE_WIDTH;
2609         }
2610       *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
2611
2612       initialized = 1;
2613     }
2614
2615   /* Call the beginning of the sequence.  */
2616   (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2617                     & -INSN_CACHE_LINE_WIDTH))
2618    ());
2619
2620 #else /* Cache is large.  */
2621
2622   if (! initialized)
2623     {
2624       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2625                  & -INSN_CACHE_LINE_WIDTH);
2626
2627       while (ptr < (int) array + sizeof array)
2628         {
2629           *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
2630           ptr += INSN_CACHE_LINE_WIDTH;
2631         }
2632
2633       initialized = 1;
2634     }
2635
2636   /* Find the location in array that occupies the same cache line as BEG.  */
2637
2638   offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
2639   start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
2640                  & -INSN_CACHE_PLANE_SIZE)
2641                 + offset);
2642
2643   /* Compute the cache alignment of the place to stop clearing.  */
2644 #if 0  /* This is not needed for gcc's purposes.  */
2645   /* If the block to clear is bigger than a cache plane,
2646      we clear the entire cache, and OFFSET is already correct.  */ 
2647   if (end < beg + INSN_CACHE_PLANE_SIZE)
2648 #endif
2649     offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
2650                & -INSN_CACHE_LINE_WIDTH)
2651               & (INSN_CACHE_PLANE_SIZE - 1));
2652
2653 #if INSN_CACHE_DEPTH > 1
2654   end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
2655   if (end_addr <= start_addr)
2656     end_addr += INSN_CACHE_PLANE_SIZE;
2657
2658   for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
2659     {
2660       int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
2661       int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
2662
2663       while (addr != stop)
2664         {
2665           /* Call the return instruction at ADDR.  */
2666           ((function_ptr) addr) ();
2667
2668           addr += INSN_CACHE_LINE_WIDTH;
2669         }
2670     }
2671 #else /* just one plane */
2672   do
2673     {
2674       /* Call the return instruction at START_ADDR.  */
2675       ((function_ptr) start_addr) ();
2676
2677       start_addr += INSN_CACHE_LINE_WIDTH;
2678     }
2679   while ((start_addr % INSN_CACHE_SIZE) != offset);
2680 #endif /* just one plane */
2681 #endif /* Cache is large */
2682 #endif /* Cache exists */
2683 #endif /* CLEAR_INSN_CACHE */
2684 }
2685
2686 #endif /* L_clear_cache */
2687 \f
2688 #ifdef L_trampoline
2689
2690 /* Jump to a trampoline, loading the static chain address.  */
2691
2692 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
2693
2694 long
2695 getpagesize (void)
2696 {
2697 #ifdef _ALPHA_
2698   return 8192;
2699 #else
2700   return 4096;
2701 #endif
2702 }
2703
2704 #ifdef __i386__
2705 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
2706 #endif
2707
2708 int
2709 mprotect (char *addr, int len, int prot)
2710 {
2711   int np, op;
2712
2713   if (prot == 7)
2714     np = 0x40;
2715   else if (prot == 5)
2716     np = 0x20;
2717   else if (prot == 4)
2718     np = 0x10;
2719   else if (prot == 3)
2720     np = 0x04;
2721   else if (prot == 1)
2722     np = 0x02;
2723   else if (prot == 0)
2724     np = 0x01;
2725
2726   if (VirtualProtect (addr, len, np, &op))
2727     return 0;
2728   else
2729     return -1;
2730 }
2731
2732 #endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
2733
2734 #ifdef TRANSFER_FROM_TRAMPOLINE 
2735 TRANSFER_FROM_TRAMPOLINE 
2736 #endif
2737
2738 #if defined (NeXT) && defined (__MACH__)
2739
2740 /* Make stack executable so we can call trampolines on stack.
2741    This is called from INITIALIZE_TRAMPOLINE in next.h.  */
2742 #ifdef NeXTStep21
2743  #include <mach.h>
2744 #else
2745  #include <mach/mach.h>
2746 #endif
2747
2748 void
2749 __enable_execute_stack (char *addr)
2750 {
2751   kern_return_t r;
2752   char *eaddr = addr + TRAMPOLINE_SIZE;
2753   vm_address_t a = (vm_address_t) addr;
2754
2755   /* turn on execute access on stack */
2756   r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
2757   if (r != KERN_SUCCESS)
2758     {
2759       mach_error("vm_protect VM_PROT_ALL", r);
2760       exit(1);
2761     }
2762
2763   /* We inline the i-cache invalidation for speed */
2764
2765 #ifdef CLEAR_INSN_CACHE
2766   CLEAR_INSN_CACHE (addr, eaddr);
2767 #else
2768   __clear_cache ((int) addr, (int) eaddr);
2769 #endif
2770
2771
2772 #endif /* defined (NeXT) && defined (__MACH__) */
2773
2774 #ifdef __convex__
2775
2776 /* Make stack executable so we can call trampolines on stack.
2777    This is called from INITIALIZE_TRAMPOLINE in convex.h.  */
2778
2779 #include <sys/mman.h>
2780 #include <sys/vmparam.h>
2781 #include <machine/machparam.h>
2782
2783 void
2784 __enable_execute_stack (void)
2785 {
2786   int fp;
2787   static unsigned lowest = USRSTACK;
2788   unsigned current = (unsigned) &fp & -NBPG;
2789
2790   if (lowest > current)
2791     {
2792       unsigned len = lowest - current;
2793       mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
2794       lowest = current;
2795     }
2796
2797   /* Clear instruction cache in case an old trampoline is in it.  */
2798   asm ("pich");
2799 }
2800 #endif /* __convex__ */
2801
2802 #ifdef __sysV88__
2803
2804 /* Modified from the convex -code above.  */
2805
2806 #include <sys/param.h>
2807 #include <errno.h>
2808 #include <sys/m88kbcs.h>
2809
2810 void
2811 __enable_execute_stack (void)
2812 {
2813   int save_errno;
2814   static unsigned long lowest = USRSTACK;
2815   unsigned long current = (unsigned long) &save_errno & -NBPC;
2816   
2817   /* Ignore errno being set. memctl sets errno to EINVAL whenever the
2818      address is seen as 'negative'. That is the case with the stack.   */
2819
2820   save_errno=errno;
2821   if (lowest > current)
2822     {
2823       unsigned len=lowest-current;
2824       memctl(current,len,MCT_TEXT);
2825       lowest = current;
2826     }
2827   else
2828     memctl(current,NBPC,MCT_TEXT);
2829   errno=save_errno;
2830 }
2831
2832 #endif /* __sysV88__ */
2833
2834 #ifdef __sysV68__
2835
2836 #include <sys/signal.h>
2837 #include <errno.h>
2838
2839 /* Motorola forgot to put memctl.o in the libp version of libc881.a,
2840    so define it here, because we need it in __clear_insn_cache below */
2841 /* On older versions of this OS, no memctl or MCT_TEXT are defined;
2842    hence we enable this stuff only if MCT_TEXT is #define'd.  */
2843
2844 #ifdef MCT_TEXT
2845 asm("\n\
2846         global memctl\n\
2847 memctl:\n\
2848         movq &75,%d0\n\
2849         trap &0\n\
2850         bcc.b noerror\n\
2851         jmp cerror%\n\
2852 noerror:\n\
2853         movq &0,%d0\n\
2854         rts");
2855 #endif
2856
2857 /* Clear instruction cache so we can call trampolines on stack.
2858    This is called from FINALIZE_TRAMPOLINE in mot3300.h.  */
2859
2860 void
2861 __clear_insn_cache (void)
2862 {
2863 #ifdef MCT_TEXT
2864   int save_errno;
2865
2866   /* Preserve errno, because users would be surprised to have
2867   errno changing without explicitly calling any system-call. */
2868   save_errno = errno;
2869
2870   /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache. 
2871      No need to use an address derived from _start or %sp, as 0 works also. */
2872   memctl(0, 4096, MCT_TEXT);
2873   errno = save_errno;
2874 #endif
2875 }
2876
2877 #endif /* __sysV68__ */
2878
2879 #ifdef __pyr__
2880
2881 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
2882 #include <stdio.h>
2883 #include <sys/mman.h>
2884 #include <sys/types.h>
2885 #include <sys/param.h>
2886 #include <sys/vmmac.h>
2887
2888 /* Modified from the convex -code above.
2889    mremap promises to clear the i-cache.  */
2890
2891 void
2892 __enable_execute_stack (void)
2893 {
2894   int fp;
2895   if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
2896                 PROT_READ|PROT_WRITE|PROT_EXEC))
2897     {
2898       perror ("mprotect in __enable_execute_stack");
2899       fflush (stderr);
2900       abort ();
2901     }
2902 }
2903 #endif /* __pyr__ */
2904
2905 #if defined (sony_news) && defined (SYSTYPE_BSD)
2906
2907 #include <stdio.h>
2908 #include <sys/types.h>
2909 #include <sys/param.h>
2910 #include <syscall.h>
2911 #include <machine/sysnews.h>
2912
2913 /* cacheflush function for NEWS-OS 4.2.
2914    This function is called from trampoline-initialize code
2915    defined in config/mips/mips.h.  */
2916
2917 void
2918 cacheflush (char *beg, int size, int flag)
2919 {
2920   if (syscall (SYS_sysnews, NEWS_CACHEFLUSH, beg, size, FLUSH_BCACHE))
2921     {
2922       perror ("cache_flush");
2923       fflush (stderr);
2924       abort ();
2925     }
2926 }
2927
2928 #endif /* sony_news */
2929 #endif /* L_trampoline */
2930 \f
2931 #ifndef __CYGWIN__
2932 #ifdef L__main
2933
2934 #include "gbl-ctors.h"
2935 /* Some systems use __main in a way incompatible with its use in gcc, in these
2936    cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2937    give the same symbol without quotes for an alternative entry point.  You
2938    must define both, or neither.  */
2939 #ifndef NAME__MAIN
2940 #define NAME__MAIN "__main"
2941 #define SYMBOL__MAIN __main
2942 #endif
2943
2944 #ifdef INIT_SECTION_ASM_OP
2945 #undef HAS_INIT_SECTION
2946 #define HAS_INIT_SECTION
2947 #endif
2948
2949 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
2950
2951 /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
2952    code to run constructors.  In that case, we need to handle EH here, too.  */
2953
2954 #ifdef EH_FRAME_SECTION
2955 #include "frame.h"
2956 extern unsigned char __EH_FRAME_BEGIN__[];
2957 #endif
2958
2959 /* Run all the global destructors on exit from the program.  */
2960
2961 void
2962 __do_global_dtors (void)
2963 {
2964 #ifdef DO_GLOBAL_DTORS_BODY
2965   DO_GLOBAL_DTORS_BODY;
2966 #else
2967   static func_ptr *p = __DTOR_LIST__ + 1;
2968   while (*p)
2969     {
2970       p++;
2971       (*(p-1)) ();
2972     }
2973 #endif
2974 #if defined (EH_FRAME_SECTION) && !defined (HAS_INIT_SECTION)
2975   {
2976     static int completed = 0;
2977     if (! completed)
2978       {
2979         completed = 1;
2980         __deregister_frame_info (__EH_FRAME_BEGIN__);
2981       }
2982   }
2983 #endif
2984 }
2985 #endif
2986
2987 #ifndef HAS_INIT_SECTION
2988 /* Run all the global constructors on entry to the program.  */
2989
2990 void
2991 __do_global_ctors (void)
2992 {
2993 #ifdef EH_FRAME_SECTION
2994   {
2995     static struct object object;
2996     __register_frame_info (__EH_FRAME_BEGIN__, &object);
2997   }
2998 #endif
2999   DO_GLOBAL_CTORS_BODY;
3000   atexit (__do_global_dtors);
3001 }
3002 #endif /* no HAS_INIT_SECTION */
3003
3004 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
3005 /* Subroutine called automatically by `main'.
3006    Compiling a global function named `main'
3007    produces an automatic call to this function at the beginning.
3008
3009    For many systems, this routine calls __do_global_ctors.
3010    For systems which support a .init section we use the .init section
3011    to run __do_global_ctors, so we need not do anything here.  */
3012
3013 void
3014 SYMBOL__MAIN ()
3015 {
3016   /* Support recursive calls to `main': run initializers just once.  */
3017   static int initialized;
3018   if (! initialized)
3019     {
3020       initialized = 1;
3021       __do_global_ctors ();
3022     }
3023 }
3024 #endif /* no HAS_INIT_SECTION or INVOKE__main */
3025
3026 #endif /* L__main */
3027 #endif /* __CYGWIN__ */
3028 \f
3029 #ifdef L_ctors
3030
3031 #include "gbl-ctors.h"
3032
3033 /* Provide default definitions for the lists of constructors and
3034    destructors, so that we don't get linker errors.  These symbols are
3035    intentionally bss symbols, so that gld and/or collect will provide
3036    the right values.  */
3037
3038 /* We declare the lists here with two elements each,
3039    so that they are valid empty lists if no other definition is loaded.
3040
3041    If we are using the old "set" extensions to have the gnu linker
3042    collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
3043    must be in the bss/common section.
3044
3045    Long term no port should use those extensions.  But many still do.  */
3046 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
3047 #if defined (ASM_OUTPUT_CONSTRUCTOR) || defined (USE_COLLECT2)
3048 func_ptr __CTOR_LIST__[2] = {0, 0};
3049 func_ptr __DTOR_LIST__[2] = {0, 0};
3050 #else
3051 func_ptr __CTOR_LIST__[2];
3052 func_ptr __DTOR_LIST__[2];
3053 #endif
3054 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
3055 #endif /* L_ctors */
3056 \f
3057 #ifdef L_exit
3058
3059 #include "gbl-ctors.h"
3060
3061 #ifdef NEED_ATEXIT
3062
3063 #ifndef ON_EXIT
3064
3065 # include <errno.h>
3066
3067 static func_ptr *atexit_chain = 0;
3068 static long atexit_chain_length = 0;
3069 static volatile long last_atexit_chain_slot = -1;
3070
3071 int
3072 atexit (func_ptr func)
3073 {
3074   if (++last_atexit_chain_slot == atexit_chain_length)
3075     {
3076       atexit_chain_length += 32;
3077       if (atexit_chain)
3078         atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
3079                                              * sizeof (func_ptr));
3080       else
3081         atexit_chain = (func_ptr *) malloc (atexit_chain_length
3082                                             * sizeof (func_ptr));
3083       if (! atexit_chain)
3084         {
3085           atexit_chain_length = 0;
3086           last_atexit_chain_slot = -1;
3087           errno = ENOMEM;
3088           return (-1);
3089         }
3090     }
3091   atexit_chain[last_atexit_chain_slot] = func;
3092   return (0);
3093 }
3094
3095 extern void _cleanup (void);
3096 extern void _exit (int) __attribute__ ((__noreturn__));
3097
3098 void 
3099 exit (int status)
3100 {
3101   if (atexit_chain)
3102     {
3103       for ( ; last_atexit_chain_slot-- >= 0; )
3104         {
3105           (*atexit_chain[last_atexit_chain_slot + 1]) ();
3106           atexit_chain[last_atexit_chain_slot + 1] = 0;
3107         }
3108       free (atexit_chain);
3109       atexit_chain = 0;
3110     }
3111 #ifdef EXIT_BODY
3112   EXIT_BODY;
3113 #else
3114   _cleanup ();
3115 #endif
3116   _exit (status);
3117 }
3118
3119 #else /* ON_EXIT */
3120
3121 /* Simple; we just need a wrapper for ON_EXIT.  */
3122 int
3123 atexit (func_ptr func)
3124 {
3125   return ON_EXIT (func);
3126 }
3127
3128 #endif /* ON_EXIT */
3129 #endif /* NEED_ATEXIT */
3130
3131 #endif /* L_exit */
3132 \f
3133 #ifdef L_eh
3134
3135 #include "gthr.h"
3136
3137 /* Shared exception handling support routines.  */
3138
3139 void
3140 __default_terminate (void)
3141 {
3142   abort ();
3143 }
3144
3145 static __terminate_func_ptr __terminate_func =
3146   __default_terminate;
3147
3148 void __attribute__((__noreturn__))
3149 __terminate (void)
3150 {
3151   (*__terminate_func)();
3152 }
3153
3154 __terminate_func_ptr
3155 __terminate_set_func (__terminate_func_ptr newfunc)
3156 {
3157   __terminate_func_ptr oldfunc = __terminate_func;
3158
3159   __terminate_func = newfunc;
3160   return (oldfunc);
3161 }
3162
3163 void *
3164 __throw_type_match (void *catch_type, void *throw_type, void *obj)
3165 {
3166 #if 0
3167  printf ("__throw_type_match (): catch_type = %s, throw_type = %s\n",
3168          catch_type, throw_type);
3169 #endif
3170  if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)
3171    return obj;
3172  return 0;
3173 }
3174
3175 void
3176 __empty (void)
3177 {
3178 }
3179 \f
3180
3181 /* Include definitions of EH context and table layout */
3182
3183 #include "eh-common.h"
3184 #ifndef inhibit_libc
3185 #include <stdio.h>
3186 #endif
3187
3188 /* Allocate and return a new EH context structure. */
3189
3190 #if __GTHREADS
3191 static void *
3192 new_eh_context (void)
3193 {
3194   struct eh_full_context {
3195     struct eh_context c;
3196     void *top_elt[2];
3197   } *ehfc = (struct eh_full_context *) malloc (sizeof *ehfc);
3198
3199   if (! ehfc)
3200     __terminate ();
3201
3202   memset (ehfc, 0, sizeof *ehfc);
3203
3204   ehfc->c.dynamic_handler_chain = (void **) ehfc->top_elt;
3205
3206   /* This should optimize out entirely.  This should always be true,
3207      but just in case it ever isn't, don't allow bogus code to be
3208      generated.  */
3209
3210   if ((void*)(&ehfc->c) != (void*)ehfc)
3211     __terminate ();
3212
3213   return &ehfc->c;
3214 }
3215
3216 static __gthread_key_t eh_context_key;
3217
3218 /* Destructor for struct eh_context. */
3219 static void
3220 eh_context_free (void *ptr)
3221 {
3222   __gthread_key_dtor (eh_context_key, ptr);
3223   if (ptr)
3224     free (ptr);
3225 }
3226 #endif
3227
3228 /* Pointer to function to return EH context. */
3229
3230 static struct eh_context *eh_context_initialize (void);
3231 static struct eh_context *eh_context_static (void);
3232 #if __GTHREADS
3233 static struct eh_context *eh_context_specific (void);
3234 #endif
3235
3236 static struct eh_context *(*get_eh_context) (void) = &eh_context_initialize;
3237
3238 /* Routine to get EH context.
3239    This one will simply call the function pointer. */
3240
3241 void *
3242 __get_eh_context (void)
3243 {
3244   return (void *) (*get_eh_context) ();
3245 }
3246
3247 /* Get and set the language specific info pointer. */
3248
3249 void **
3250 __get_eh_info (void)
3251 {
3252   struct eh_context *eh = (*get_eh_context) ();
3253   return &eh->info;
3254 }
3255 \f
3256 #ifdef DWARF2_UNWIND_INFO
3257 static int dwarf_reg_size_table_initialized = 0;
3258 static char dwarf_reg_size_table[DWARF_FRAME_REGISTERS];
3259
3260 static void
3261 init_reg_size_table (void)
3262 {
3263   __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
3264   dwarf_reg_size_table_initialized = 1;
3265 }
3266 #endif
3267
3268 #if __GTHREADS
3269 static void
3270 eh_threads_initialize (void)
3271 {
3272   /* Try to create the key.  If it fails, revert to static method,
3273      otherwise start using thread specific EH contexts. */
3274   if (__gthread_key_create (&eh_context_key, &eh_context_free) == 0)
3275     get_eh_context = &eh_context_specific;
3276   else
3277     get_eh_context = &eh_context_static;
3278 }
3279 #endif /* no __GTHREADS */
3280
3281 /* Initialize EH context.
3282    This will be called only once, since we change GET_EH_CONTEXT
3283    pointer to another routine. */
3284
3285 static struct eh_context *
3286 eh_context_initialize (void)
3287 {
3288 #if __GTHREADS
3289
3290   static __gthread_once_t once = __GTHREAD_ONCE_INIT;
3291   /* Make sure that get_eh_context does not point to us anymore.
3292      Some systems have dummy thread routines in their libc that
3293      return a success (Solaris 2.6 for example). */
3294   if (__gthread_once (&once, eh_threads_initialize) != 0
3295       || get_eh_context == &eh_context_initialize)
3296     {
3297       /* Use static version of EH context. */
3298       get_eh_context = &eh_context_static;
3299     }
3300 #ifdef DWARF2_UNWIND_INFO
3301   {
3302     static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
3303     if (__gthread_once (&once_regsizes, init_reg_size_table) != 0
3304         || ! dwarf_reg_size_table_initialized)
3305       init_reg_size_table ();
3306   }
3307 #endif
3308
3309 #else /* no __GTHREADS */
3310
3311   /* Use static version of EH context. */
3312   get_eh_context = &eh_context_static;
3313
3314 #ifdef DWARF2_UNWIND_INFO
3315   init_reg_size_table ();
3316 #endif
3317
3318 #endif /* no __GTHREADS */
3319
3320   return (*get_eh_context) ();
3321 }
3322
3323 /* Return a static EH context. */
3324
3325 static struct eh_context *
3326 eh_context_static (void)
3327 {
3328   static struct eh_context eh;
3329   static int initialized;
3330   static void *top_elt[2];
3331
3332   if (! initialized)
3333     {
3334       initialized = 1;
3335       memset (&eh, 0, sizeof eh);
3336       eh.dynamic_handler_chain = top_elt;
3337     }
3338   return &eh;
3339 }
3340
3341 #if __GTHREADS
3342 /* Return a thread specific EH context. */
3343
3344 static struct eh_context *
3345 eh_context_specific (void)
3346 {
3347   struct eh_context *eh;
3348   eh = (struct eh_context *) __gthread_getspecific (eh_context_key);
3349   if (! eh)
3350     {
3351       eh = new_eh_context ();
3352       if (__gthread_setspecific (eh_context_key, (void *) eh) != 0)
3353         __terminate ();
3354     }
3355
3356   return eh;
3357 }
3358 #endif /* __GTHREADS */
3359 \f
3360 /* Support routines for alloc/free during exception handling */
3361
3362 /* __eh_alloc and __eh_free attempt allocation using malloc, but fall back to
3363    the small arena in the eh_context. This is needed because throwing an
3364    out-of-memory exception would fail otherwise. The emergency space is
3365    allocated in blocks of size EH_ALLOC_ALIGN, the
3366    minimum allocation being two blocks. A bitmask indicates which blocks
3367    have been allocated. To indicate the size of an allocation, the bit for
3368    the final block is not set. Hence each allocation is a run of 1s followed
3369    by a zero. */
3370 void *
3371 __eh_alloc (size_t size)
3372 {
3373   void *p;
3374   
3375   if (!size)
3376     abort();
3377   p = malloc (size);
3378   if (p == 0)
3379     {
3380       struct eh_context *eh = __get_eh_context ();
3381       unsigned blocks = (size + EH_ALLOC_ALIGN - 1) / EH_ALLOC_ALIGN;
3382       unsigned real_mask = eh->alloc_mask | (eh->alloc_mask << 1);
3383       unsigned our_mask;
3384       unsigned ix;
3385       
3386       if (blocks > EH_ALLOC_SIZE / EH_ALLOC_ALIGN)
3387         __terminate ();
3388       blocks += blocks == 1;
3389       our_mask = (1 << blocks) - 1;
3390       
3391       for (ix = EH_ALLOC_SIZE / EH_ALLOC_ALIGN - blocks; ix; ix--)
3392         if (! ((real_mask >> ix) & our_mask))
3393           {
3394             /* found some space */
3395             p = &eh->alloc_buffer[ix * EH_ALLOC_ALIGN];
3396             eh->alloc_mask |= (our_mask >> 1) << ix;
3397             return p;
3398           }
3399       __terminate ();
3400     }
3401   return p;
3402 }
3403
3404 /* Free the memory for an cp_eh_info and associated exception, given
3405    a pointer to the cp_eh_info.  */
3406 void
3407 __eh_free (void *p)
3408 {
3409   struct eh_context *eh = __get_eh_context ();
3410
3411   ptrdiff_t  diff = (char *)p - &eh->alloc_buffer[0];
3412   if (diff >= 0 && diff < EH_ALLOC_SIZE)
3413     {
3414       unsigned mask = eh->alloc_mask;
3415       unsigned bit = 1 << (diff / EH_ALLOC_ALIGN);
3416       
3417       do
3418         {
3419           mask ^= bit;
3420           bit <<= 1;
3421         }
3422       while (mask & bit);
3423       eh->alloc_mask = mask;
3424     }
3425   else
3426     free (p);
3427 }
3428 \f
3429 /* Support routines for setjmp/longjmp exception handling.  */
3430
3431 /* Calls to __sjthrow are generated by the compiler when an exception
3432    is raised when using the setjmp/longjmp exception handling codegen
3433    method.  */
3434
3435 #ifdef DONT_USE_BUILTIN_SETJMP
3436 extern void longjmp (void *, int);
3437 #endif
3438
3439 /* Routine to get the head of the current thread's dynamic handler chain
3440    use for exception handling. */
3441
3442 void ***
3443 __get_dynamic_handler_chain (void)
3444 {
3445   struct eh_context *eh = (*get_eh_context) ();
3446   return &eh->dynamic_handler_chain;
3447 }
3448
3449 /* This is used to throw an exception when the setjmp/longjmp codegen
3450    method is used for exception handling.
3451
3452    We call __terminate if there are no handlers left.  Otherwise we run the
3453    cleanup actions off the dynamic cleanup stack, and pop the top of the
3454    dynamic handler chain, and use longjmp to transfer back to the associated
3455    handler.  */
3456
3457 void
3458 __sjthrow (void)
3459 {
3460   struct eh_context *eh = (*get_eh_context) ();
3461   void ***dhc = &eh->dynamic_handler_chain;
3462   void *jmpbuf;
3463   void (*func)(void *, int);
3464   void *arg;
3465   /* The cleanup chain is one word into the buffer.  Get the cleanup chain. */
3466   void ***cleanup = (void***)&(*dhc)[1];
3467
3468   /* If there are any cleanups in the chain, run them now.  */
3469   if (cleanup[0])
3470     {
3471       double store[200];
3472       void **buf = (void**)store;
3473       buf[1] = 0;
3474       buf[0] = (*dhc);
3475
3476       /* try { */
3477 #ifdef DONT_USE_BUILTIN_SETJMP
3478       if (! setjmp (&buf[2]))
3479 #else
3480       if (! __builtin_setjmp (&buf[2]))
3481 #endif
3482         {
3483           *dhc = buf;
3484           while (cleanup[0])
3485             {
3486               func = (void(*)(void*, int))cleanup[0][1];
3487               arg = (void*)cleanup[0][2];
3488
3489               /* Update this before running the cleanup.  */
3490               cleanup[0] = (void **)cleanup[0][0];
3491
3492               (*func)(arg, 2);
3493             }
3494           *dhc = buf[0];
3495         }
3496       /* catch (...) */
3497       else
3498         {
3499           __terminate ();
3500         }
3501     }
3502   
3503   /* We must call terminate if we try and rethrow an exception, when
3504      there is no exception currently active and when there are no
3505      handlers left.  */
3506   if (! eh->info || (*dhc)[0] == 0)
3507     __terminate ();
3508     
3509   /* Find the jmpbuf associated with the top element of the dynamic
3510      handler chain.  The jumpbuf starts two words into the buffer.  */
3511   jmpbuf = &(*dhc)[2];
3512
3513   /* Then we pop the top element off the dynamic handler chain.  */
3514   *dhc = (void**)(*dhc)[0];
3515
3516   /* And then we jump to the handler.  */
3517
3518 #ifdef DONT_USE_BUILTIN_SETJMP
3519   longjmp (jmpbuf, 1);
3520 #else
3521   __builtin_longjmp (jmpbuf, 1);
3522 #endif
3523 }
3524
3525 /* Run cleanups on the dynamic cleanup stack for the current dynamic
3526    handler, then pop the handler off the dynamic handler stack, and
3527    then throw.  This is used to skip the first handler, and transfer
3528    control to the next handler in the dynamic handler stack.  */
3529
3530 void
3531 __sjpopnthrow (void)
3532 {
3533   struct eh_context *eh = (*get_eh_context) ();
3534   void ***dhc = &eh->dynamic_handler_chain;
3535   void (*func)(void *, int);
3536   void *arg;
3537   /* The cleanup chain is one word into the buffer.  Get the cleanup chain. */
3538   void ***cleanup = (void***)&(*dhc)[1];
3539
3540   /* If there are any cleanups in the chain, run them now.  */
3541   if (cleanup[0])
3542     {
3543       double store[200];
3544       void **buf = (void**)store;
3545       buf[1] = 0;
3546       buf[0] = (*dhc);
3547
3548       /* try { */
3549 #ifdef DONT_USE_BUILTIN_SETJMP
3550       if (! setjmp (&buf[2]))
3551 #else
3552       if (! __builtin_setjmp (&buf[2]))
3553 #endif
3554         {
3555           *dhc = buf;
3556           while (cleanup[0])
3557             {
3558               func = (void(*)(void*, int))cleanup[0][1];
3559               arg = (void*)cleanup[0][2];
3560
3561               /* Update this before running the cleanup.  */
3562               cleanup[0] = (void **)cleanup[0][0];
3563
3564               (*func)(arg, 2);
3565             }
3566           *dhc = buf[0];
3567         }
3568       /* catch (...) */
3569       else
3570         {
3571           __terminate ();
3572         }
3573     }
3574
3575   /* Then we pop the top element off the dynamic handler chain.  */
3576   *dhc = (void**)(*dhc)[0];
3577
3578   __sjthrow ();
3579 }
3580 \f
3581 /* Support code for all exception region-based exception handling.  */
3582
3583 int
3584 __eh_rtime_match (void *rtime)
3585 {
3586   void *info;
3587   __eh_matcher matcher;
3588   void *ret;
3589
3590   info = *(__get_eh_info ());
3591   matcher = ((__eh_info *)info)->match_function;
3592   if (! matcher)
3593     {
3594 #ifndef inhibit_libc
3595       fprintf (stderr, "Internal Compiler Bug: No runtime type matcher.");
3596 #endif
3597       return 0;
3598     }
3599   ret = (*matcher) (info, rtime, (void *)0);
3600   return (ret != NULL);
3601 }
3602
3603 /* This value identifies the place from which an exception is being
3604    thrown.  */
3605
3606 #ifdef EH_TABLE_LOOKUP
3607
3608 EH_TABLE_LOOKUP
3609
3610 #else
3611
3612 #ifdef DWARF2_UNWIND_INFO
3613
3614 /* Return the table version of an exception descriptor */
3615
3616 short 
3617 __get_eh_table_version (exception_descriptor *table) 
3618 {
3619   return table->lang.version;
3620 }
3621
3622 /* Return the originating table language of an exception descriptor */
3623
3624 short 
3625 __get_eh_table_language (exception_descriptor *table)
3626 {
3627   return table->lang.language;
3628 }
3629
3630 /* This routine takes a PC and a pointer to the exception region TABLE for
3631    its translation unit, and returns the address of the exception handler
3632    associated with the closest exception table handler entry associated
3633    with that PC, or 0 if there are no table entries the PC fits in.
3634
3635    In the advent of a tie, we have to give the last entry, as it represents
3636    an inner block.  */
3637
3638 static void *
3639 old_find_exception_handler (void *pc, old_exception_table *table)
3640 {
3641   if (table)
3642     {
3643       int pos;
3644       int best = -1;
3645
3646       /* We can't do a binary search because the table isn't guaranteed
3647          to be sorted from function to function.  */
3648       for (pos = 0; table[pos].start_region != (void *) -1; ++pos)
3649         {
3650           if (table[pos].start_region <= pc && table[pos].end_region > pc)
3651             {
3652               /* This can apply.  Make sure it is at least as small as
3653                  the previous best.  */
3654               if (best == -1 || (table[pos].end_region <= table[best].end_region
3655                         && table[pos].start_region >= table[best].start_region))
3656                 best = pos;
3657             }
3658           /* But it is sorted by starting PC within a function.  */
3659           else if (best >= 0 && table[pos].start_region > pc)
3660             break;
3661         }
3662       if (best != -1)
3663         return table[best].exception_handler;
3664     }
3665
3666   return (void *) 0;
3667 }
3668
3669 /* find_exception_handler finds the correct handler, if there is one, to
3670    handle an exception.
3671    returns a pointer to the handler which controlled should be transferred
3672    to, or NULL if there is nothing left.
3673    Parameters:
3674    PC - pc where the exception originates. If this is a rethrow, 
3675         then this starts out as a pointer to the exception table
3676         entry we wish to rethrow out of.
3677    TABLE - exception table for the current module.
3678    EH_INFO - eh info pointer for this exception.
3679    RETHROW - 1 if this is a rethrow. (see incoming value of PC).
3680    CLEANUP - returned flag indicating whether this is a cleanup handler.
3681 */
3682 static void *
3683 find_exception_handler (void *pc, exception_descriptor *table, 
3684                         __eh_info *eh_info, int rethrow, int *cleanup)
3685 {
3686
3687   void *retval = NULL;
3688   *cleanup = 1;
3689   if (table)
3690     {
3691       int pos = 0;
3692       /* The new model assumed the table is sorted inner-most out so the
3693          first region we find which matches is the correct one */
3694
3695       exception_table *tab = &(table->table[0]);
3696
3697       /* Subtract 1 from the PC to avoid hitting the next region */
3698       if (rethrow) 
3699         {
3700           /* pc is actually the region table entry to rethrow out of */
3701           pos = ((exception_table *) pc) - tab;
3702           pc = ((exception_table *) pc)->end_region - 1;
3703
3704           /* The label is always on the LAST handler entry for a region, 
3705              so we know the next entry is a different region, even if the
3706              addresses are the same. Make sure its not end of table tho. */
3707           if (tab[pos].start_region != (void *) -1)
3708             pos++;
3709         }
3710       else
3711         pc--;
3712       
3713       /* We can't do a binary search because the table is in inner-most
3714          to outermost address ranges within functions */
3715       for ( ; tab[pos].start_region != (void *) -1; pos++)
3716         { 
3717           if (tab[pos].start_region <= pc && tab[pos].end_region > pc)
3718             {
3719               if (tab[pos].match_info)
3720                 {
3721                   __eh_matcher matcher = eh_info->match_function;
3722                   /* match info but no matcher is NOT a match */
3723                   if (matcher) 
3724                     {
3725                       void *ret = (*matcher)((void *) eh_info, 
3726                                              tab[pos].match_info, table);
3727                       if (ret) 
3728                         {
3729                           if (retval == NULL)
3730                             retval = tab[pos].exception_handler;
3731                           *cleanup = 0;
3732                           break;
3733                         }
3734                     }
3735                 }
3736               else
3737                 {
3738                   if (retval == NULL)
3739                     retval = tab[pos].exception_handler;
3740                 }
3741             }
3742         }
3743     }
3744   return retval;
3745 }
3746 #endif /* DWARF2_UNWIND_INFO */
3747 #endif /* EH_TABLE_LOOKUP */
3748 \f
3749 #ifdef DWARF2_UNWIND_INFO
3750 /* Support code for exception handling using static unwind information.  */
3751
3752 #include "frame.h"
3753
3754 /* This type is used in get_reg and put_reg to deal with ABIs where a void*
3755    is smaller than a word, such as the Irix 6 n32 ABI.  We cast twice to
3756    avoid a warning about casting between int and pointer of different
3757    sizes.  */
3758
3759 typedef int ptr_type __attribute__ ((mode (pointer)));
3760
3761 typedef struct
3762 {
3763   word_type *reg[DWARF_FRAME_REGISTERS];
3764 } saved_regs_t;
3765
3766 #ifdef INCOMING_REGNO
3767 /* Is the saved value for register REG in frame UDATA stored in a register
3768    window in the previous frame?  */
3769
3770 /* ??? The Sparc INCOMING_REGNO references TARGET_FLAT.  This allows us
3771    to use the macro here.  One wonders, though, that perhaps TARGET_FLAT
3772    compiled functions won't work with the frame-unwind stuff here.  
3773    Perhaps the entireity of in_reg_window should be conditional on having
3774    seen a DW_CFA_GNU_window_save?  */
3775 #define target_flags 0
3776
3777 static int
3778 in_reg_window (int reg, frame_state *udata)
3779 {
3780   if (udata->saved[reg] == REG_SAVED_REG)
3781     return INCOMING_REGNO (reg) == reg;
3782   if (udata->saved[reg] != REG_SAVED_OFFSET)
3783     return 0;
3784
3785 #ifdef STACK_GROWS_DOWNWARD
3786   return udata->reg_or_offset[reg] > 0;
3787 #else
3788   return udata->reg_or_offset[reg] < 0;
3789 #endif
3790 }
3791 #else
3792 static inline int
3793 in_reg_window (int reg __attribute__ ((__unused__)),
3794                frame_state *udata __attribute__ ((__unused__)))
3795 {
3796   return 0;
3797 }
3798 #endif /* INCOMING_REGNO */
3799
3800 /* Get the address of register REG as saved in UDATA, where SUB_UDATA is a
3801    frame called by UDATA or 0.  */
3802
3803 static word_type *
3804 get_reg_addr (unsigned reg, frame_state *udata, frame_state *sub_udata)
3805 {
3806   while (udata->saved[reg] == REG_SAVED_REG)
3807     {
3808       reg = udata->reg_or_offset[reg];
3809       if (in_reg_window (reg, udata))
3810         {
3811           udata = sub_udata;
3812           sub_udata = NULL;
3813         }
3814     }
3815   if (udata->saved[reg] == REG_SAVED_OFFSET)
3816     return (word_type *)(udata->cfa + udata->reg_or_offset[reg]);
3817   else
3818     /* We don't have a saved copy of this register.  */
3819     return NULL;
3820 }
3821
3822 /* Get the value of register REG as saved in UDATA, where SUB_UDATA is a
3823    frame called by UDATA or 0.  */
3824
3825 static inline void *
3826 get_reg (unsigned reg, frame_state *udata, frame_state *sub_udata)
3827 {
3828   return (void *)(ptr_type) *get_reg_addr (reg, udata, sub_udata);
3829 }
3830
3831 /* Overwrite the saved value for register REG in frame UDATA with VAL.  */
3832
3833 static inline void
3834 put_reg (unsigned reg, void *val, frame_state *udata)
3835 {
3836   *get_reg_addr (reg, udata, NULL) = (word_type)(ptr_type) val;
3837 }
3838
3839 /* Copy the saved value for register REG from PTREG to frame
3840    TARGET_UDATA.  Unlike the previous two functions, this can handle
3841    registers that are not one word large.  */
3842
3843 static void
3844 copy_reg (unsigned reg, word_type *preg, frame_state *target_udata)
3845 {
3846   word_type *ptreg = get_reg_addr (reg, target_udata, NULL);
3847   memcpy (ptreg, preg, dwarf_reg_size_table [reg]);
3848 }
3849
3850 /* Retrieve the return address for frame UDATA.  */
3851
3852 static inline void *
3853 get_return_addr (frame_state *udata, frame_state *sub_udata)
3854 {
3855   return __builtin_extract_return_addr
3856     (get_reg (udata->retaddr_column, udata, sub_udata));
3857 }
3858
3859 /* Overwrite the return address for frame UDATA with VAL.  */
3860
3861 static inline void
3862 put_return_addr (void *val, frame_state *udata)
3863 {
3864   val = __builtin_frob_return_addr (val);
3865   put_reg (udata->retaddr_column, val, udata);
3866 }
3867
3868 /* Given the current frame UDATA and its return address PC, return the
3869    information about the calling frame in CALLER_UDATA and update the
3870    register array in SAVED_REGS.  */
3871
3872 static void *
3873 next_stack_level (void *pc, frame_state *udata, frame_state *caller_udata,
3874                   saved_regs_t *saved_regs)
3875 {
3876   int i;
3877   word_type *p;
3878
3879   /* Collect all of the registers for the current frame.  */
3880   for (i = 0; i < DWARF_FRAME_REGISTERS; i++)
3881     if (udata->saved[i])
3882       saved_regs->reg[i] = get_reg_addr (i, udata, caller_udata);
3883
3884   caller_udata = __frame_state_for (pc, caller_udata);
3885   if (! caller_udata)
3886     return 0;
3887
3888   /* Now go back to our caller's stack frame.  If our caller's CFA was
3889      saved in a register in this stack frame or a previous one,
3890      restore it; otherwise, assume CFA register was saved in SP and
3891      restore it to our CFA value.  */
3892
3893   p = saved_regs->reg[caller_udata->cfa_reg];
3894   if (p)
3895     caller_udata->cfa = (void *)(ptr_type)*p;
3896   else
3897     caller_udata->cfa = udata->cfa;
3898  
3899   if (caller_udata->indirect)
3900     caller_udata->cfa = * (void **) ((unsigned char *)caller_udata->cfa 
3901                                      + caller_udata->base_offset);
3902   caller_udata->cfa += caller_udata->cfa_offset;
3903
3904   return caller_udata;
3905 }
3906
3907 /* Hook to call before __terminate if only cleanup handlers remain. */
3908 void 
3909 __unwinding_cleanup (void)
3910 {
3911 }
3912
3913 /* throw_helper performs some of the common grunt work for a throw. This
3914    routine is called by throw and rethrows. This is pretty much split 
3915    out from the old __throw routine. An addition has been added which allows
3916    for a dummy call to a routine __unwinding_cleanup() when there are nothing
3917    but cleanups remaining. This allows a debugger to examine the state
3918    at which the throw was executed, before any cleanups, rather than
3919    at the terminate point after the stack has been unwound.
3920
3921    EH is the current eh_context structure.
3922    PC is the address of the call to __throw.
3923    MY_UDATA is the unwind information for __throw.
3924    OFFSET_P is where we return the SP adjustment offset.  */
3925
3926 static void *
3927 throw_helper (struct eh_context *eh, void *pc, frame_state *my_udata,
3928               long *offset_p)
3929 {
3930   frame_state ustruct2, *udata = &ustruct2;
3931   frame_state ustruct;
3932   frame_state *sub_udata = &ustruct;
3933   void *saved_pc = pc;
3934   void *handler;
3935   void *handler_p = 0;
3936   void *pc_p = 0;
3937   void *callee_cfa = 0;
3938   frame_state saved_ustruct;
3939   int new_eh_model;
3940   int cleanup = 0;
3941   int only_cleanup = 0;
3942   int rethrow = 0;
3943   int saved_state = 0;
3944   long args_size;
3945   saved_regs_t saved_regs, cleanup_regs;
3946   __eh_info *eh_info = (__eh_info *)eh->info;
3947   int i;
3948
3949   memset (saved_regs.reg, 0, sizeof saved_regs.reg);
3950   memset (sub_udata->saved, REG_UNSAVED, sizeof sub_udata->saved);
3951
3952   /* Do we find a handler based on a re-throw PC? */
3953   if (eh->table_index != (void *) 0)
3954     rethrow = 1;
3955
3956   memcpy (udata, my_udata, sizeof (*udata));
3957
3958   handler = (void *) 0;
3959   for (;;)
3960     { 
3961       frame_state *p = udata;
3962
3963       udata = next_stack_level (pc, udata, sub_udata, &saved_regs);
3964       sub_udata = p;
3965
3966       /* If we couldn't find the next frame, we lose.  */
3967       if (! udata)
3968         break;
3969
3970       if (udata->eh_ptr == NULL)
3971         new_eh_model = 0;
3972       else
3973         new_eh_model = (((exception_descriptor *)(udata->eh_ptr))->
3974                         runtime_id_field == NEW_EH_RUNTIME);
3975
3976       if (rethrow) 
3977         {
3978           rethrow = 0;
3979           handler = find_exception_handler (eh->table_index, udata->eh_ptr, 
3980                                             eh_info, 1, &cleanup);
3981           eh->table_index = (void *)0;
3982         }
3983       else
3984         if (new_eh_model)
3985           handler = find_exception_handler (pc, udata->eh_ptr, eh_info, 
3986                                             0, &cleanup);
3987         else
3988           handler = old_find_exception_handler (pc, udata->eh_ptr);
3989
3990       /* If we found one, we can stop searching, if its not a cleanup. 
3991          for cleanups, we save the state, and keep looking. This allows
3992          us to call a debug hook if there are nothing but cleanups left. */
3993       if (handler)
3994         {
3995           /* sub_udata now refers to the frame called by the handler frame.  */
3996
3997           if (cleanup)
3998             {
3999               if (!saved_state)
4000                 {
4001                   saved_ustruct = *udata;
4002                   cleanup_regs = saved_regs;
4003                   handler_p = handler;
4004                   pc_p = pc;
4005                   saved_state = 1;
4006                   only_cleanup = 1;
4007                   /* Save the CFA of the frame called by the handler
4008                      frame.  */
4009                   callee_cfa = sub_udata->cfa;
4010                 }
4011             }
4012           else
4013             {
4014               only_cleanup = 0;
4015               if (!saved_state)
4016                 callee_cfa = sub_udata->cfa;
4017               break;
4018             }
4019         }
4020
4021       /* Otherwise, we continue searching.  We subtract 1 from PC to avoid
4022          hitting the beginning of the next region.  */
4023       pc = get_return_addr (udata, sub_udata) - 1;
4024     }
4025
4026   if (saved_state) 
4027     {
4028       udata = &saved_ustruct;
4029       saved_regs = cleanup_regs;
4030       handler = handler_p;
4031       pc = pc_p;
4032       if (only_cleanup)
4033         __unwinding_cleanup ();
4034     }
4035
4036   /* If we haven't found a handler by now, this is an unhandled
4037      exception.  */
4038   if (! handler) 
4039     __terminate();
4040
4041   eh->handler_label = handler;
4042
4043   args_size = udata->args_size;
4044
4045   /* We adjust SP by the difference between __throw's CFA and the CFA for
4046      the frame called by the handler frame, because those CFAs correspond
4047      to the SP values at the two call sites.  We need to further adjust by
4048      the args_size of the handler frame itself to get the handler frame's
4049      SP from before the args were pushed for that call.  */
4050 #ifdef STACK_GROWS_DOWNWARD
4051   *offset_p = callee_cfa - my_udata->cfa + args_size;
4052 #else
4053   *offset_p = my_udata->cfa - callee_cfa - args_size;
4054 #endif
4055                        
4056   /* If we found a handler in the throw context there's no need to
4057      unwind.  */
4058   if (pc != saved_pc)
4059     {
4060       /* Copy saved register values into our register save slots.  */
4061       for (i = 0; i < DWARF_FRAME_REGISTERS; i++)
4062         if (i != udata->retaddr_column && saved_regs.reg[i])
4063           copy_reg (i, saved_regs.reg[i], my_udata);
4064     }
4065
4066   return handler;
4067 }
4068
4069
4070 /* We first search for an exception handler, and if we don't find
4071    it, we call __terminate on the current stack frame so that we may
4072    use the debugger to walk the stack and understand why no handler
4073    was found.
4074
4075    If we find one, then we unwind the frames down to the one that
4076    has the handler and transfer control into the handler.  */
4077
4078 /*extern void __throw(void) __attribute__ ((__noreturn__));*/
4079
4080 void
4081 __throw (void)
4082 {
4083   struct eh_context *eh = (*get_eh_context) ();
4084   void *pc, *handler;
4085   long offset;
4086
4087   /* XXX maybe make my_ustruct static so we don't have to look it up for
4088      each throw.  */
4089   frame_state my_ustruct, *my_udata = &my_ustruct;
4090
4091   /* This is required for C++ semantics.  We must call terminate if we
4092      try and rethrow an exception, when there is no exception currently
4093      active.  */
4094   if (! eh->info)
4095     __terminate ();
4096     
4097   /* Start at our stack frame.  */
4098 label:
4099   my_udata = __frame_state_for (&&label, my_udata);
4100   if (! my_udata)
4101     __terminate ();
4102
4103   /* We need to get the value from the CFA register. */
4104   my_udata->cfa = __builtin_dwarf_cfa ();
4105
4106   /* Do any necessary initialization to access arbitrary stack frames.
4107      On the SPARC, this means flushing the register windows.  */
4108   __builtin_unwind_init ();
4109
4110   /* Now reset pc to the right throw point.  */
4111   pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
4112
4113   handler = throw_helper (eh, pc, my_udata, &offset);
4114
4115   /* Now go!  */
4116
4117   __builtin_eh_return ((void *)eh, offset, handler);
4118
4119   /* Epilogue:  restore the handler frame's register values and return
4120      to the stub.  */
4121 }
4122
4123 /*extern void __rethrow(void *) __attribute__ ((__noreturn__));*/
4124
4125 void
4126 __rethrow (void *index)
4127 {
4128   struct eh_context *eh = (*get_eh_context) ();
4129   void *pc, *handler;
4130   long offset;
4131
4132   /* XXX maybe make my_ustruct static so we don't have to look it up for
4133      each throw.  */
4134   frame_state my_ustruct, *my_udata = &my_ustruct;
4135
4136   /* This is required for C++ semantics.  We must call terminate if we
4137      try and rethrow an exception, when there is no exception currently
4138      active.  */
4139   if (! eh->info)
4140     __terminate ();
4141
4142   /* This is the table index we want to rethrow from. The value of
4143      the END_REGION label is used for the PC of the throw, and the
4144      search begins with the next table entry. */
4145   eh->table_index = index;
4146     
4147   /* Start at our stack frame.  */
4148 label:
4149   my_udata = __frame_state_for (&&label, my_udata);
4150   if (! my_udata)
4151     __terminate ();
4152
4153   /* We need to get the value from the CFA register. */
4154   my_udata->cfa = __builtin_dwarf_cfa ();
4155
4156   /* Do any necessary initialization to access arbitrary stack frames.
4157      On the SPARC, this means flushing the register windows.  */
4158   __builtin_unwind_init ();
4159
4160   /* Now reset pc to the right throw point.  */
4161   pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
4162
4163   handler = throw_helper (eh, pc, my_udata, &offset);
4164
4165   /* Now go!  */
4166
4167   __builtin_eh_return ((void *)eh, offset, handler);
4168
4169   /* Epilogue:  restore the handler frame's register values and return
4170      to the stub.  */
4171 }
4172 #endif /* DWARF2_UNWIND_INFO */
4173
4174 #ifdef IA64_UNWIND_INFO
4175 #include "frame.h"
4176
4177 /* Return handler to which we want to transfer control, NULL if we don't
4178    intend to handle this exception here.  */
4179 void *
4180 __ia64_personality_v1 (void *pc, old_exception_table *table)
4181 {
4182   if (table)
4183     {
4184       int pos;
4185       int best = -1;
4186
4187       for (pos = 0; table[pos].start_region != (void *) -1; ++pos)
4188         {
4189           if (table[pos].start_region <= pc && table[pos].end_region > pc)
4190             {
4191               /* This can apply.  Make sure it is at least as small as
4192                  the previous best.  */
4193               if (best == -1 || (table[pos].end_region <= table[best].end_region
4194                         && table[pos].start_region >= table[best].start_region))
4195                 best = pos;
4196             }
4197           /* It is sorted by starting PC within a function.  */
4198           else if (best >= 0 && table[pos].start_region > pc)
4199             break;
4200         }
4201       if (best != -1)
4202         return table[best].exception_handler;
4203     }
4204   return (void *) 0;
4205 }
4206
4207 static void
4208 ia64_throw_helper (ia64_frame_state *throw_frame, ia64_frame_state *caller,
4209                    void *throw_bsp, void *throw_sp)
4210 {
4211   void *throw_pc = __builtin_return_address (0);
4212   unwind_info_ptr *info;
4213   void *pc, *handler = NULL;
4214   void *pc_base;
4215   int frame_count;
4216   void *bsp;
4217
4218   __builtin_ia64_flushrs ();      /*  Make the local register stacks available.  */
4219
4220   /* Start at our stack frame, get our state.  */
4221   __build_ia64_frame_state (throw_pc, throw_frame, throw_bsp, throw_sp,
4222                             &pc_base);
4223
4224   /* Now we have to find the proper frame for pc, and see if there
4225      is a handler for it. if not, we keep going back frames until
4226      we do find one. Otherwise we call uncaught ().  */
4227
4228   frame_count = 0;
4229   memcpy (caller, throw_frame, sizeof (*caller));
4230   while (!handler)
4231     {
4232       void *(*personality) (void *, old_exception_table *);
4233       void *eh_table;
4234
4235       frame_count++;
4236       /* We only care about the RP right now, so we dont need to keep
4237          any other information about a call frame right now.  */
4238       pc = __get_real_reg_value (&caller->rp) - 1;
4239       bsp = __calc_caller_bsp ((long)__get_real_reg_value (&caller->pfs),
4240                                caller->my_bsp);
4241       info = __build_ia64_frame_state (pc, caller, bsp, caller->my_psp,
4242                                        &pc_base);
4243
4244       /* If we couldn't find the next frame, we lose.  */
4245       if (! info)
4246         break;
4247
4248       personality = __get_personality (info); 
4249       /* TODO Haven't figured out how to actually load the personality address
4250          yet, so just always default to the one we expect for now.  */
4251       if (personality != 0)
4252         personality = __ia64_personality_v1;
4253       eh_table = __get_except_table (info);
4254       /* If there is no personality routine, we'll keep unwinding.  */
4255       if (personality)
4256         /* Pass a segment relative PC address to the personality routine,
4257            because the unwind_info section uses segrel relocs.  */
4258         handler = personality ((void *)(pc - pc_base), eh_table);
4259     }
4260   
4261   if (!handler)
4262     __terminate ();
4263
4264   /* Handler is a segment relative address, so we must adjust it here.  */
4265   handler += (long) pc_base;
4266
4267   /* If we found a handler, we need to unwind the stack to that point.
4268      We do this by copying saved values from previous frames into the
4269      save slot for the throw_frame saved slots.  when __throw returns,
4270      it'll pickup the correct values.  */
4271   
4272   /* Start with where __throw saved things, and copy each saved register
4273      of each previous frame until we get to the one before we're 
4274      throwing back to.  */
4275   memcpy (caller, throw_frame, sizeof (*caller));
4276   for ( ; frame_count > 0; frame_count--)
4277     {
4278       pc = __get_real_reg_value (&caller->rp) - 1;
4279       bsp = __calc_caller_bsp ((long)__get_real_reg_value (&caller->pfs),
4280                                caller->my_bsp);
4281       __build_ia64_frame_state (pc, caller, bsp, caller->my_psp, &pc_base);
4282       /* Any regs that were saved can be put in the throw frame now.  */
4283       /* We don't want to copy any saved register from the 
4284          target destination, but we do want to load up it's frame.  */
4285       if (frame_count > 1)
4286         __copy_saved_reg_state (throw_frame, caller);
4287     }
4288
4289   /* Set return address of the throw frame to the handler. */
4290   __set_real_reg_value (&throw_frame->rp, handler);
4291
4292   /* TODO, do we need to do anything to make the values we wrote 'stick'? */
4293   /* DO we need to go through the whole loadrs seqeunce?  */
4294 }
4295
4296
4297 void
4298 __throw ()
4299 {
4300   register void *stack_pointer __asm__("r12");
4301   struct eh_context *eh = (*get_eh_context) ();
4302   ia64_frame_state my_frame;
4303   ia64_frame_state originator;  /* For the context handler is in.  */
4304   void *bsp, *tmp_bsp;
4305   long offset;
4306
4307   /* This is required for C++ semantics.  We must call terminate if we
4308      try and rethrow an exception, when there is no exception currently
4309      active.  */
4310   if (! eh->info)
4311     __terminate ();
4312
4313   __builtin_unwind_init ();
4314
4315   /* We have to call another routine to actually process the frame 
4316      information, which will force all of __throw's local registers into
4317      backing store.  */
4318
4319   /* Get the value of ar.bsp while we're here.  */
4320
4321   bsp = __builtin_ia64_bsp ();
4322   ia64_throw_helper (&my_frame, &originator, bsp, stack_pointer);
4323
4324   /* Now we have to fudge the bsp by the amount in our (__throw)
4325      frame marker, since the return is going to adjust it by that much. */
4326
4327   tmp_bsp = __calc_caller_bsp ((long)__get_real_reg_value (&my_frame.pfs), 
4328                              my_frame.my_bsp);
4329   offset = (char *)my_frame.my_bsp - (char *)tmp_bsp;
4330   tmp_bsp = (char *)originator.my_bsp + offset;
4331
4332   __builtin_eh_return (tmp_bsp, offset, originator.my_sp);
4333
4334   /* The return address was already set by throw_helper.  */
4335 }
4336
4337 #endif /* IA64_UNWIND_INFO  */
4338
4339 #endif /* L_eh */