OSDN Git Service

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