* pa.md (subsi3): Turn into an expander. Create two anonymous
[official-gcc.git] / gcc / libgcc2.c
blob6e1742ee6d53d0de1dd6e75a3160edc6f3201bcd
1 /* More subroutines needed by GCC output code on some machines. */
2 /* Compile this one with gcc. */
3 /* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* As a special exception, if you link this library with other files,
23 some of which are compiled with GCC, to produce an executable,
24 this library does not by itself cause the resulting executable
25 to be covered by the GNU General Public License.
26 This exception does not however invalidate any other reasons why
27 the executable file might be covered by the GNU General Public License. */
29 /* It is incorrect to include config.h here, because this file is being
30 compiled for the target, and hence definitions concerning only the host
31 do not apply. */
33 #include "tconfig.h"
35 /* We disable this when inhibit_libc, so that gcc can still be built without
36 needing header files first. */
37 /* ??? This is not a good solution, since prototypes may be required in
38 some cases for correct code. See also frame.c. */
39 #ifndef inhibit_libc
40 /* fixproto guarantees these system headers exist. */
41 #include <stdlib.h>
42 #include <unistd.h>
43 #endif
45 #include "machmode.h"
46 #include "defaults.h"
47 #ifndef L_trampoline
48 #include <stddef.h>
49 #endif
51 /* Don't use `fancy_abort' here even if config.h says to use it. */
52 #ifdef abort
53 #undef abort
54 #endif
56 /* In a cross-compilation situation, default to inhibiting compilation
57 of routines that use libc. */
59 #if defined(CROSS_COMPILE) && !defined(inhibit_libc)
60 #define inhibit_libc
61 #endif
63 /* Permit the tm.h file to select the endianness to use just for this
64 file. This is used when the endianness is determined when the
65 compiler is run. */
67 #ifndef LIBGCC2_WORDS_BIG_ENDIAN
68 #define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
69 #endif
71 #ifndef LIBGCC2_LONG_DOUBLE_TYPE_SIZE
72 #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE LONG_DOUBLE_TYPE_SIZE
73 #endif
75 /* In the first part of this file, we are interfacing to calls generated
76 by the compiler itself. These calls pass values into these routines
77 which have very specific modes (rather than very specific types), and
78 these compiler-generated calls also expect any return values to have
79 very specific modes (rather than very specific types). Thus, we need
80 to avoid using regular C language type names in this part of the file
81 because the sizes for those types can be configured to be anything.
82 Instead we use the following special type names. */
84 typedef unsigned int UQItype __attribute__ ((mode (QI)));
85 typedef int SItype __attribute__ ((mode (SI)));
86 typedef unsigned int USItype __attribute__ ((mode (SI)));
87 typedef int DItype __attribute__ ((mode (DI)));
88 typedef unsigned int UDItype __attribute__ ((mode (DI)));
90 typedef float SFtype __attribute__ ((mode (SF)));
91 typedef float DFtype __attribute__ ((mode (DF)));
93 #if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
94 typedef float XFtype __attribute__ ((mode (XF)));
95 #endif
96 #if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128
97 typedef float TFtype __attribute__ ((mode (TF)));
98 #endif
100 typedef int word_type __attribute__ ((mode (__word__)));
102 /* Make sure that we don't accidentally use any normal C language built-in
103 type names in the first part of this file. Instead we want to use *only*
104 the type names defined above. The following macro definitions insure
105 that if we *do* accidentally use some normal C language built-in type name,
106 we will get a syntax error. */
108 #define char bogus_type
109 #define short bogus_type
110 #define int bogus_type
111 #define long bogus_type
112 #define unsigned bogus_type
113 #define float bogus_type
114 #define double bogus_type
116 #define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
118 /* DIstructs are pairs of SItype values in the order determined by
119 LIBGCC2_WORDS_BIG_ENDIAN. */
121 #if LIBGCC2_WORDS_BIG_ENDIAN
122 struct DIstruct {SItype high, low;};
123 #else
124 struct DIstruct {SItype low, high;};
125 #endif
127 /* We need this union to unpack/pack DImode values, since we don't have
128 any arithmetic yet. Incoming DImode parameters are stored into the
129 `ll' field, and the unpacked result is read from the struct `s'. */
131 typedef union
133 struct DIstruct s;
134 DItype ll;
135 } DIunion;
137 #if (defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_w_sdiv)\
138 || defined (L_divdi3) || defined (L_udivdi3) \
139 || defined (L_moddi3) || defined (L_umoddi3))
141 #include "longlong.h"
143 #endif /* udiv or mul */
145 extern DItype __fixunssfdi (SFtype a);
146 extern DItype __fixunsdfdi (DFtype a);
147 #if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
148 extern DItype __fixunsxfdi (XFtype a);
149 #endif
150 #if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128
151 extern DItype __fixunstfdi (TFtype a);
152 #endif
154 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
155 #if defined (L_divdi3) || defined (L_moddi3)
156 static inline
157 #endif
158 DItype
159 __negdi2 (DItype u)
161 DIunion w;
162 DIunion uu;
164 uu.ll = u;
166 w.s.low = -uu.s.low;
167 w.s.high = -uu.s.high - ((USItype) w.s.low > 0);
169 return w.ll;
171 #endif
173 /* Unless shift functions are defined whith full ANSI prototypes,
174 parameter b will be promoted to int if word_type is smaller than an int. */
175 #ifdef L_lshrdi3
176 DItype
177 __lshrdi3 (DItype u, word_type b)
179 DIunion w;
180 word_type bm;
181 DIunion uu;
183 if (b == 0)
184 return u;
186 uu.ll = u;
188 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
189 if (bm <= 0)
191 w.s.high = 0;
192 w.s.low = (USItype)uu.s.high >> -bm;
194 else
196 USItype carries = (USItype)uu.s.high << bm;
197 w.s.high = (USItype)uu.s.high >> b;
198 w.s.low = ((USItype)uu.s.low >> b) | carries;
201 return w.ll;
203 #endif
205 #ifdef L_ashldi3
206 DItype
207 __ashldi3 (DItype u, word_type b)
209 DIunion w;
210 word_type bm;
211 DIunion uu;
213 if (b == 0)
214 return u;
216 uu.ll = u;
218 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
219 if (bm <= 0)
221 w.s.low = 0;
222 w.s.high = (USItype)uu.s.low << -bm;
224 else
226 USItype carries = (USItype)uu.s.low >> bm;
227 w.s.low = (USItype)uu.s.low << b;
228 w.s.high = ((USItype)uu.s.high << b) | carries;
231 return w.ll;
233 #endif
235 #ifdef L_ashrdi3
236 DItype
237 __ashrdi3 (DItype u, word_type b)
239 DIunion w;
240 word_type bm;
241 DIunion uu;
243 if (b == 0)
244 return u;
246 uu.ll = u;
248 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
249 if (bm <= 0)
251 /* w.s.high = 1..1 or 0..0 */
252 w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
253 w.s.low = uu.s.high >> -bm;
255 else
257 USItype carries = (USItype)uu.s.high << bm;
258 w.s.high = uu.s.high >> b;
259 w.s.low = ((USItype)uu.s.low >> b) | carries;
262 return w.ll;
264 #endif
266 #ifdef L_ffsdi2
267 DItype
268 __ffsdi2 (DItype u)
270 DIunion uu, w;
271 uu.ll = u;
272 w.s.high = 0;
273 w.s.low = ffs (uu.s.low);
274 if (w.s.low != 0)
275 return w.ll;
276 w.s.low = ffs (uu.s.high);
277 if (w.s.low != 0)
279 w.s.low += BITS_PER_UNIT * sizeof (SItype);
280 return w.ll;
282 return w.ll;
284 #endif
286 #ifdef L_muldi3
287 DItype
288 __muldi3 (DItype u, DItype v)
290 DIunion w;
291 DIunion uu, vv;
293 uu.ll = u,
294 vv.ll = v;
296 w.ll = __umulsidi3 (uu.s.low, vv.s.low);
297 w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
298 + (USItype) uu.s.high * (USItype) vv.s.low);
300 return w.ll;
302 #endif
304 #ifdef L_udiv_w_sdiv
305 #if defined (sdiv_qrnnd)
306 USItype
307 __udiv_w_sdiv (USItype *rp, USItype a1, USItype a0, USItype d)
309 USItype q, r;
310 USItype c0, c1, b1;
312 if ((SItype) d >= 0)
314 if (a1 < d - a1 - (a0 >> (SI_TYPE_SIZE - 1)))
316 /* dividend, divisor, and quotient are nonnegative */
317 sdiv_qrnnd (q, r, a1, a0, d);
319 else
321 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
322 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (SI_TYPE_SIZE - 1));
323 /* Divide (c1*2^32 + c0) by d */
324 sdiv_qrnnd (q, r, c1, c0, d);
325 /* Add 2^31 to quotient */
326 q += (USItype) 1 << (SI_TYPE_SIZE - 1);
329 else
331 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
332 c1 = a1 >> 1; /* A/2 */
333 c0 = (a1 << (SI_TYPE_SIZE - 1)) + (a0 >> 1);
335 if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
337 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
339 r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
340 if ((d & 1) != 0)
342 if (r >= q)
343 r = r - q;
344 else if (q - r <= d)
346 r = r - q + d;
347 q--;
349 else
351 r = r - q + 2*d;
352 q -= 2;
356 else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
358 c1 = (b1 - 1) - c1;
359 c0 = ~c0; /* logical NOT */
361 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
363 q = ~q; /* (A/2)/b1 */
364 r = (b1 - 1) - r;
366 r = 2*r + (a0 & 1); /* A/(2*b1) */
368 if ((d & 1) != 0)
370 if (r >= q)
371 r = r - q;
372 else if (q - r <= d)
374 r = r - q + d;
375 q--;
377 else
379 r = r - q + 2*d;
380 q -= 2;
384 else /* Implies c1 = b1 */
385 { /* Hence a1 = d - 1 = 2*b1 - 1 */
386 if (a0 >= -d)
388 q = -1;
389 r = a0 + d;
391 else
393 q = -2;
394 r = a0 + 2*d;
399 *rp = r;
400 return q;
402 #else
403 /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */
404 USItype
405 __udiv_w_sdiv (USItype *rp __attribute__ ((__unused__)),
406 USItype a1 __attribute__ ((__unused__)),
407 USItype a0 __attribute__ ((__unused__)),
408 USItype d __attribute__ ((__unused__)))
410 return 0;
412 #endif
413 #endif
415 #if (defined (L_udivdi3) || defined (L_divdi3) || \
416 defined (L_umoddi3) || defined (L_moddi3))
417 #define L_udivmoddi4
418 #endif
420 #ifdef L_udivmoddi4
421 static const UQItype __clz_tab[] =
423 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,
424 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,
425 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,
426 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,
427 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,
428 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,
429 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,
430 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,
433 #if (defined (L_udivdi3) || defined (L_divdi3) || \
434 defined (L_umoddi3) || defined (L_moddi3))
435 static inline
436 #endif
437 UDItype
438 __udivmoddi4 (UDItype n, UDItype d, UDItype *rp)
440 DIunion ww;
441 DIunion nn, dd;
442 DIunion rr;
443 USItype d0, d1, n0, n1, n2;
444 USItype q0, q1;
445 USItype b, bm;
447 nn.ll = n;
448 dd.ll = d;
450 d0 = dd.s.low;
451 d1 = dd.s.high;
452 n0 = nn.s.low;
453 n1 = nn.s.high;
455 #if !UDIV_NEEDS_NORMALIZATION
456 if (d1 == 0)
458 if (d0 > n1)
460 /* 0q = nn / 0D */
462 udiv_qrnnd (q0, n0, n1, n0, d0);
463 q1 = 0;
465 /* Remainder in n0. */
467 else
469 /* qq = NN / 0d */
471 if (d0 == 0)
472 d0 = 1 / d0; /* Divide intentionally by zero. */
474 udiv_qrnnd (q1, n1, 0, n1, d0);
475 udiv_qrnnd (q0, n0, n1, n0, d0);
477 /* Remainder in n0. */
480 if (rp != 0)
482 rr.s.low = n0;
483 rr.s.high = 0;
484 *rp = rr.ll;
488 #else /* UDIV_NEEDS_NORMALIZATION */
490 if (d1 == 0)
492 if (d0 > n1)
494 /* 0q = nn / 0D */
496 count_leading_zeros (bm, d0);
498 if (bm != 0)
500 /* Normalize, i.e. make the most significant bit of the
501 denominator set. */
503 d0 = d0 << bm;
504 n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
505 n0 = n0 << bm;
508 udiv_qrnnd (q0, n0, n1, n0, d0);
509 q1 = 0;
511 /* Remainder in n0 >> bm. */
513 else
515 /* qq = NN / 0d */
517 if (d0 == 0)
518 d0 = 1 / d0; /* Divide intentionally by zero. */
520 count_leading_zeros (bm, d0);
522 if (bm == 0)
524 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
525 conclude (the most significant bit of n1 is set) /\ (the
526 leading quotient digit q1 = 1).
528 This special case is necessary, not an optimization.
529 (Shifts counts of SI_TYPE_SIZE are undefined.) */
531 n1 -= d0;
532 q1 = 1;
534 else
536 /* Normalize. */
538 b = SI_TYPE_SIZE - bm;
540 d0 = d0 << bm;
541 n2 = n1 >> b;
542 n1 = (n1 << bm) | (n0 >> b);
543 n0 = n0 << bm;
545 udiv_qrnnd (q1, n1, n2, n1, d0);
548 /* n1 != d0... */
550 udiv_qrnnd (q0, n0, n1, n0, d0);
552 /* Remainder in n0 >> bm. */
555 if (rp != 0)
557 rr.s.low = n0 >> bm;
558 rr.s.high = 0;
559 *rp = rr.ll;
562 #endif /* UDIV_NEEDS_NORMALIZATION */
564 else
566 if (d1 > n1)
568 /* 00 = nn / DD */
570 q0 = 0;
571 q1 = 0;
573 /* Remainder in n1n0. */
574 if (rp != 0)
576 rr.s.low = n0;
577 rr.s.high = n1;
578 *rp = rr.ll;
581 else
583 /* 0q = NN / dd */
585 count_leading_zeros (bm, d1);
586 if (bm == 0)
588 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
589 conclude (the most significant bit of n1 is set) /\ (the
590 quotient digit q0 = 0 or 1).
592 This special case is necessary, not an optimization. */
594 /* The condition on the next line takes advantage of that
595 n1 >= d1 (true due to program flow). */
596 if (n1 > d1 || n0 >= d0)
598 q0 = 1;
599 sub_ddmmss (n1, n0, n1, n0, d1, d0);
601 else
602 q0 = 0;
604 q1 = 0;
606 if (rp != 0)
608 rr.s.low = n0;
609 rr.s.high = n1;
610 *rp = rr.ll;
613 else
615 USItype m1, m0;
616 /* Normalize. */
618 b = SI_TYPE_SIZE - bm;
620 d1 = (d1 << bm) | (d0 >> b);
621 d0 = d0 << bm;
622 n2 = n1 >> b;
623 n1 = (n1 << bm) | (n0 >> b);
624 n0 = n0 << bm;
626 udiv_qrnnd (q0, n1, n2, n1, d1);
627 umul_ppmm (m1, m0, q0, d0);
629 if (m1 > n1 || (m1 == n1 && m0 > n0))
631 q0--;
632 sub_ddmmss (m1, m0, m1, m0, d1, d0);
635 q1 = 0;
637 /* Remainder in (n1n0 - m1m0) >> bm. */
638 if (rp != 0)
640 sub_ddmmss (n1, n0, n1, n0, m1, m0);
641 rr.s.low = (n1 << b) | (n0 >> bm);
642 rr.s.high = n1 >> bm;
643 *rp = rr.ll;
649 ww.s.low = q0;
650 ww.s.high = q1;
651 return ww.ll;
653 #endif
655 #ifdef L_divdi3
656 UDItype __udivmoddi4 ();
658 DItype
659 __divdi3 (DItype u, DItype v)
661 word_type c = 0;
662 DIunion uu, vv;
663 DItype w;
665 uu.ll = u;
666 vv.ll = v;
668 if (uu.s.high < 0)
669 c = ~c,
670 uu.ll = __negdi2 (uu.ll);
671 if (vv.s.high < 0)
672 c = ~c,
673 vv.ll = __negdi2 (vv.ll);
675 w = __udivmoddi4 (uu.ll, vv.ll, (UDItype *) 0);
676 if (c)
677 w = __negdi2 (w);
679 return w;
681 #endif
683 #ifdef L_moddi3
684 UDItype __udivmoddi4 ();
685 DItype
686 __moddi3 (DItype u, DItype v)
688 word_type c = 0;
689 DIunion uu, vv;
690 DItype w;
692 uu.ll = u;
693 vv.ll = v;
695 if (uu.s.high < 0)
696 c = ~c,
697 uu.ll = __negdi2 (uu.ll);
698 if (vv.s.high < 0)
699 vv.ll = __negdi2 (vv.ll);
701 (void) __udivmoddi4 (uu.ll, vv.ll, &w);
702 if (c)
703 w = __negdi2 (w);
705 return w;
707 #endif
709 #ifdef L_umoddi3
710 UDItype __udivmoddi4 ();
711 UDItype
712 __umoddi3 (UDItype u, UDItype v)
714 UDItype w;
716 (void) __udivmoddi4 (u, v, &w);
718 return w;
720 #endif
722 #ifdef L_udivdi3
723 UDItype __udivmoddi4 ();
724 UDItype
725 __udivdi3 (UDItype n, UDItype d)
727 return __udivmoddi4 (n, d, (UDItype *) 0);
729 #endif
731 #ifdef L_cmpdi2
732 word_type
733 __cmpdi2 (DItype a, DItype b)
735 DIunion au, bu;
737 au.ll = a, bu.ll = b;
739 if (au.s.high < bu.s.high)
740 return 0;
741 else if (au.s.high > bu.s.high)
742 return 2;
743 if ((USItype) au.s.low < (USItype) bu.s.low)
744 return 0;
745 else if ((USItype) au.s.low > (USItype) bu.s.low)
746 return 2;
747 return 1;
749 #endif
751 #ifdef L_ucmpdi2
752 word_type
753 __ucmpdi2 (DItype a, DItype b)
755 DIunion au, bu;
757 au.ll = a, bu.ll = b;
759 if ((USItype) au.s.high < (USItype) bu.s.high)
760 return 0;
761 else if ((USItype) au.s.high > (USItype) bu.s.high)
762 return 2;
763 if ((USItype) au.s.low < (USItype) bu.s.low)
764 return 0;
765 else if ((USItype) au.s.low > (USItype) bu.s.low)
766 return 2;
767 return 1;
769 #endif
771 #if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
772 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
773 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
775 DItype
776 __fixunstfdi (TFtype a)
778 TFtype b;
779 UDItype v;
781 if (a < 0)
782 return 0;
784 /* Compute high word of result, as a flonum. */
785 b = (a / HIGH_WORD_COEFF);
786 /* Convert that to fixed (but not to DItype!),
787 and shift it into the high word. */
788 v = (USItype) b;
789 v <<= WORD_SIZE;
790 /* Remove high part from the TFtype, leaving the low part as flonum. */
791 a -= (TFtype)v;
792 /* Convert that to fixed (but not to DItype!) and add it in.
793 Sometimes A comes out negative. This is significant, since
794 A has more bits than a long int does. */
795 if (a < 0)
796 v -= (USItype) (- a);
797 else
798 v += (USItype) a;
799 return v;
801 #endif
803 #if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
804 DItype
805 __fixtfdi (TFtype a)
807 if (a < 0)
808 return - __fixunstfdi (-a);
809 return __fixunstfdi (a);
811 #endif
813 #if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
814 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
815 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
817 DItype
818 __fixunsxfdi (XFtype a)
820 XFtype b;
821 UDItype v;
823 if (a < 0)
824 return 0;
826 /* Compute high word of result, as a flonum. */
827 b = (a / HIGH_WORD_COEFF);
828 /* Convert that to fixed (but not to DItype!),
829 and shift it into the high word. */
830 v = (USItype) b;
831 v <<= WORD_SIZE;
832 /* Remove high part from the XFtype, leaving the low part as flonum. */
833 a -= (XFtype)v;
834 /* Convert that to fixed (but not to DItype!) and add it in.
835 Sometimes A comes out negative. This is significant, since
836 A has more bits than a long int does. */
837 if (a < 0)
838 v -= (USItype) (- a);
839 else
840 v += (USItype) a;
841 return v;
843 #endif
845 #if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
846 DItype
847 __fixxfdi (XFtype a)
849 if (a < 0)
850 return - __fixunsxfdi (-a);
851 return __fixunsxfdi (a);
853 #endif
855 #ifdef L_fixunsdfdi
856 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
857 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
859 DItype
860 __fixunsdfdi (DFtype a)
862 DFtype b;
863 UDItype v;
865 if (a < 0)
866 return 0;
868 /* Compute high word of result, as a flonum. */
869 b = (a / HIGH_WORD_COEFF);
870 /* Convert that to fixed (but not to DItype!),
871 and shift it into the high word. */
872 v = (USItype) b;
873 v <<= WORD_SIZE;
874 /* Remove high part from the DFtype, leaving the low part as flonum. */
875 a -= (DFtype)v;
876 /* Convert that to fixed (but not to DItype!) and add it in.
877 Sometimes A comes out negative. This is significant, since
878 A has more bits than a long int does. */
879 if (a < 0)
880 v -= (USItype) (- a);
881 else
882 v += (USItype) a;
883 return v;
885 #endif
887 #ifdef L_fixdfdi
888 DItype
889 __fixdfdi (DFtype a)
891 if (a < 0)
892 return - __fixunsdfdi (-a);
893 return __fixunsdfdi (a);
895 #endif
897 #ifdef L_fixunssfdi
898 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
899 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
901 DItype
902 __fixunssfdi (SFtype original_a)
904 /* Convert the SFtype to a DFtype, because that is surely not going
905 to lose any bits. Some day someone else can write a faster version
906 that avoids converting to DFtype, and verify it really works right. */
907 DFtype a = original_a;
908 DFtype b;
909 UDItype v;
911 if (a < 0)
912 return 0;
914 /* Compute high word of result, as a flonum. */
915 b = (a / HIGH_WORD_COEFF);
916 /* Convert that to fixed (but not to DItype!),
917 and shift it into the high word. */
918 v = (USItype) b;
919 v <<= WORD_SIZE;
920 /* Remove high part from the DFtype, leaving the low part as flonum. */
921 a -= (DFtype)v;
922 /* Convert that to fixed (but not to DItype!) and add it in.
923 Sometimes A comes out negative. This is significant, since
924 A has more bits than a long int does. */
925 if (a < 0)
926 v -= (USItype) (- a);
927 else
928 v += (USItype) a;
929 return v;
931 #endif
933 #ifdef L_fixsfdi
934 DItype
935 __fixsfdi (SFtype a)
937 if (a < 0)
938 return - __fixunssfdi (-a);
939 return __fixunssfdi (a);
941 #endif
943 #if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
944 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
945 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
946 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
948 XFtype
949 __floatdixf (DItype u)
951 XFtype d;
953 d = (SItype) (u >> WORD_SIZE);
954 d *= HIGH_HALFWORD_COEFF;
955 d *= HIGH_HALFWORD_COEFF;
956 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
958 return d;
960 #endif
962 #if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
963 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
964 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
965 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
967 TFtype
968 __floatditf (DItype u)
970 TFtype d;
972 d = (SItype) (u >> WORD_SIZE);
973 d *= HIGH_HALFWORD_COEFF;
974 d *= HIGH_HALFWORD_COEFF;
975 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
977 return d;
979 #endif
981 #ifdef L_floatdidf
982 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
983 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
984 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
986 DFtype
987 __floatdidf (DItype u)
989 DFtype d;
991 d = (SItype) (u >> WORD_SIZE);
992 d *= HIGH_HALFWORD_COEFF;
993 d *= HIGH_HALFWORD_COEFF;
994 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
996 return d;
998 #endif
1000 #ifdef L_floatdisf
1001 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
1002 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
1003 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
1004 #define DI_SIZE (sizeof (DItype) * BITS_PER_UNIT)
1006 /* Define codes for all the float formats that we know of. Note
1007 that this is copied from real.h. */
1009 #define UNKNOWN_FLOAT_FORMAT 0
1010 #define IEEE_FLOAT_FORMAT 1
1011 #define VAX_FLOAT_FORMAT 2
1012 #define IBM_FLOAT_FORMAT 3
1014 /* Default to IEEE float if not specified. Nearly all machines use it. */
1015 #ifndef HOST_FLOAT_FORMAT
1016 #define HOST_FLOAT_FORMAT IEEE_FLOAT_FORMAT
1017 #endif
1019 #if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1020 #define DF_SIZE 53
1021 #define SF_SIZE 24
1022 #endif
1024 #if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
1025 #define DF_SIZE 56
1026 #define SF_SIZE 24
1027 #endif
1029 #if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
1030 #define DF_SIZE 56
1031 #define SF_SIZE 24
1032 #endif
1034 SFtype
1035 __floatdisf (DItype u)
1037 /* Do the calculation in DFmode
1038 so that we don't lose any of the precision of the high word
1039 while multiplying it. */
1040 DFtype f;
1042 /* Protect against double-rounding error.
1043 Represent any low-order bits, that might be truncated in DFmode,
1044 by a bit that won't be lost. The bit can go in anywhere below the
1045 rounding position of the SFmode. A fixed mask and bit position
1046 handles all usual configurations. It doesn't handle the case
1047 of 128-bit DImode, however. */
1048 if (DF_SIZE < DI_SIZE
1049 && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1051 #define REP_BIT ((USItype) 1 << (DI_SIZE - DF_SIZE))
1052 if (! (- ((DItype) 1 << DF_SIZE) < u
1053 && u < ((DItype) 1 << DF_SIZE)))
1055 if ((USItype) u & (REP_BIT - 1))
1056 u |= REP_BIT;
1059 f = (SItype) (u >> WORD_SIZE);
1060 f *= HIGH_HALFWORD_COEFF;
1061 f *= HIGH_HALFWORD_COEFF;
1062 f += (USItype) (u & (HIGH_WORD_COEFF - 1));
1064 return (SFtype) f;
1066 #endif
1068 #if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
1069 /* Reenable the normal types, in case limits.h needs them. */
1070 #undef char
1071 #undef short
1072 #undef int
1073 #undef long
1074 #undef unsigned
1075 #undef float
1076 #undef double
1077 #undef MIN
1078 #undef MAX
1079 #include <limits.h>
1081 USItype
1082 __fixunsxfsi (XFtype a)
1084 if (a >= - (DFtype) LONG_MIN)
1085 return (SItype) (a + LONG_MIN) - LONG_MIN;
1086 return (SItype) a;
1088 #endif
1090 #ifdef L_fixunsdfsi
1091 /* Reenable the normal types, in case limits.h needs them. */
1092 #undef char
1093 #undef short
1094 #undef int
1095 #undef long
1096 #undef unsigned
1097 #undef float
1098 #undef double
1099 #undef MIN
1100 #undef MAX
1101 #include <limits.h>
1103 USItype
1104 __fixunsdfsi (DFtype a)
1106 if (a >= - (DFtype) LONG_MIN)
1107 return (SItype) (a + LONG_MIN) - LONG_MIN;
1108 return (SItype) a;
1110 #endif
1112 #ifdef L_fixunssfsi
1113 /* Reenable the normal types, in case limits.h needs them. */
1114 #undef char
1115 #undef short
1116 #undef int
1117 #undef long
1118 #undef unsigned
1119 #undef float
1120 #undef double
1121 #undef MIN
1122 #undef MAX
1123 #include <limits.h>
1125 USItype
1126 __fixunssfsi (SFtype a)
1128 if (a >= - (SFtype) LONG_MIN)
1129 return (SItype) (a + LONG_MIN) - LONG_MIN;
1130 return (SItype) a;
1132 #endif
1134 /* From here on down, the routines use normal data types. */
1136 #define SItype bogus_type
1137 #define USItype bogus_type
1138 #define DItype bogus_type
1139 #define UDItype bogus_type
1140 #define SFtype bogus_type
1141 #define DFtype bogus_type
1143 #undef char
1144 #undef short
1145 #undef int
1146 #undef long
1147 #undef unsigned
1148 #undef float
1149 #undef double
1151 #ifdef L__gcc_bcmp
1153 /* Like bcmp except the sign is meaningful.
1154 Result is negative if S1 is less than S2,
1155 positive if S1 is greater, 0 if S1 and S2 are equal. */
1158 __gcc_bcmp (unsigned char *s1, unsigned char *s2, size_t size)
1160 while (size > 0)
1162 unsigned char c1 = *s1++, c2 = *s2++;
1163 if (c1 != c2)
1164 return c1 - c2;
1165 size--;
1167 return 0;
1170 #endif
1171 \f\f
1172 #ifdef L__dummy
1173 void
1174 __dummy () {}
1175 #endif
1177 #ifdef L_varargs
1178 #ifdef __i860__
1179 #if defined(__svr4__) || defined(__alliant__)
1180 asm (" .text");
1181 asm (" .align 4");
1183 /* The Alliant needs the added underscore. */
1184 asm (".globl __builtin_saveregs");
1185 asm ("__builtin_saveregs:");
1186 asm (".globl ___builtin_saveregs");
1187 asm ("___builtin_saveregs:");
1189 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
1190 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
1191 area and also for a new va_list
1192 structure */
1193 /* Save all argument registers in the arg reg save area. The
1194 arg reg save area must have the following layout (according
1195 to the svr4 ABI):
1197 struct {
1198 union {
1199 float freg[8];
1200 double dreg[4];
1201 } float_regs;
1202 long ireg[12];
1206 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
1207 asm (" fst.q %f12,16(%sp)");
1209 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
1210 asm (" st.l %r17,36(%sp)");
1211 asm (" st.l %r18,40(%sp)");
1212 asm (" st.l %r19,44(%sp)");
1213 asm (" st.l %r20,48(%sp)");
1214 asm (" st.l %r21,52(%sp)");
1215 asm (" st.l %r22,56(%sp)");
1216 asm (" st.l %r23,60(%sp)");
1217 asm (" st.l %r24,64(%sp)");
1218 asm (" st.l %r25,68(%sp)");
1219 asm (" st.l %r26,72(%sp)");
1220 asm (" st.l %r27,76(%sp)");
1222 asm (" adds 80,%sp,%r16"); /* compute the address of the new
1223 va_list structure. Put in into
1224 r16 so that it will be returned
1225 to the caller. */
1227 /* Initialize all fields of the new va_list structure. This
1228 structure looks like:
1230 typedef struct {
1231 unsigned long ireg_used;
1232 unsigned long freg_used;
1233 long *reg_base;
1234 long *mem_ptr;
1235 } va_list;
1238 asm (" st.l %r0, 0(%r16)"); /* nfixed */
1239 asm (" st.l %r0, 4(%r16)"); /* nfloating */
1240 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
1241 asm (" bri %r1"); /* delayed return */
1242 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
1244 #else /* not __svr4__ */
1245 #if defined(__PARAGON__)
1247 * we'll use SVR4-ish varargs but need SVR3.2 assembler syntax,
1248 * and we stand a better chance of hooking into libraries
1249 * compiled by PGI. [andyp@ssd.intel.com]
1251 asm (" .text");
1252 asm (" .align 4");
1253 asm (".globl __builtin_saveregs");
1254 asm ("__builtin_saveregs:");
1255 asm (".globl ___builtin_saveregs");
1256 asm ("___builtin_saveregs:");
1258 asm (" andnot 0x0f,sp,sp"); /* round down to 16-byte boundary */
1259 asm (" adds -96,sp,sp"); /* allocate stack space for reg save
1260 area and also for a new va_list
1261 structure */
1262 /* Save all argument registers in the arg reg save area. The
1263 arg reg save area must have the following layout (according
1264 to the svr4 ABI):
1266 struct {
1267 union {
1268 float freg[8];
1269 double dreg[4];
1270 } float_regs;
1271 long ireg[12];
1275 asm (" fst.q f8, 0(sp)");
1276 asm (" fst.q f12,16(sp)");
1277 asm (" st.l r16,32(sp)");
1278 asm (" st.l r17,36(sp)");
1279 asm (" st.l r18,40(sp)");
1280 asm (" st.l r19,44(sp)");
1281 asm (" st.l r20,48(sp)");
1282 asm (" st.l r21,52(sp)");
1283 asm (" st.l r22,56(sp)");
1284 asm (" st.l r23,60(sp)");
1285 asm (" st.l r24,64(sp)");
1286 asm (" st.l r25,68(sp)");
1287 asm (" st.l r26,72(sp)");
1288 asm (" st.l r27,76(sp)");
1290 asm (" adds 80,sp,r16"); /* compute the address of the new
1291 va_list structure. Put in into
1292 r16 so that it will be returned
1293 to the caller. */
1295 /* Initialize all fields of the new va_list structure. This
1296 structure looks like:
1298 typedef struct {
1299 unsigned long ireg_used;
1300 unsigned long freg_used;
1301 long *reg_base;
1302 long *mem_ptr;
1303 } va_list;
1306 asm (" st.l r0, 0(r16)"); /* nfixed */
1307 asm (" st.l r0, 4(r16)"); /* nfloating */
1308 asm (" st.l sp, 8(r16)"); /* __va_ctl points to __va_struct. */
1309 asm (" bri r1"); /* delayed return */
1310 asm (" st.l r28,12(r16)"); /* pointer to overflow args */
1311 #else /* not __PARAGON__ */
1312 asm (" .text");
1313 asm (" .align 4");
1315 asm (".globl ___builtin_saveregs");
1316 asm ("___builtin_saveregs:");
1317 asm (" mov sp,r30");
1318 asm (" andnot 0x0f,sp,sp");
1319 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
1321 /* Fill in the __va_struct. */
1322 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
1323 asm (" st.l r17, 4(sp)"); /* int fixed[12] */
1324 asm (" st.l r18, 8(sp)");
1325 asm (" st.l r19,12(sp)");
1326 asm (" st.l r20,16(sp)");
1327 asm (" st.l r21,20(sp)");
1328 asm (" st.l r22,24(sp)");
1329 asm (" st.l r23,28(sp)");
1330 asm (" st.l r24,32(sp)");
1331 asm (" st.l r25,36(sp)");
1332 asm (" st.l r26,40(sp)");
1333 asm (" st.l r27,44(sp)");
1335 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
1336 asm (" fst.q f12,64(sp)"); /* int floating[8] */
1338 /* Fill in the __va_ctl. */
1339 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
1340 asm (" st.l r28,84(sp)"); /* pointer to more args */
1341 asm (" st.l r0, 88(sp)"); /* nfixed */
1342 asm (" st.l r0, 92(sp)"); /* nfloating */
1344 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
1345 asm (" bri r1");
1346 asm (" mov r30,sp");
1347 /* recover stack and pass address to start
1348 of data. */
1349 #endif /* not __PARAGON__ */
1350 #endif /* not __svr4__ */
1351 #else /* not __i860__ */
1352 #ifdef __sparc__
1353 asm (".global __builtin_saveregs");
1354 asm ("__builtin_saveregs:");
1355 asm (".global ___builtin_saveregs");
1356 asm ("___builtin_saveregs:");
1357 #ifdef NEED_PROC_COMMAND
1358 asm (".proc 020");
1359 #endif
1360 asm ("st %i0,[%fp+68]");
1361 asm ("st %i1,[%fp+72]");
1362 asm ("st %i2,[%fp+76]");
1363 asm ("st %i3,[%fp+80]");
1364 asm ("st %i4,[%fp+84]");
1365 asm ("retl");
1366 asm ("st %i5,[%fp+88]");
1367 #ifdef NEED_TYPE_COMMAND
1368 asm (".type __builtin_saveregs,#function");
1369 asm (".size __builtin_saveregs,.-__builtin_saveregs");
1370 #endif
1371 #else /* not __sparc__ */
1372 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1374 asm (" .text");
1375 #ifdef __mips16
1376 asm (" .set nomips16");
1377 #endif
1378 asm (" .ent __builtin_saveregs");
1379 asm (" .globl __builtin_saveregs");
1380 asm ("__builtin_saveregs:");
1381 asm (" sw $4,0($30)");
1382 asm (" sw $5,4($30)");
1383 asm (" sw $6,8($30)");
1384 asm (" sw $7,12($30)");
1385 asm (" j $31");
1386 asm (" .end __builtin_saveregs");
1387 #else /* not __mips__, etc. */
1389 void *
1390 __builtin_saveregs ()
1392 abort ();
1395 #endif /* not __mips__ */
1396 #endif /* not __sparc__ */
1397 #endif /* not __i860__ */
1398 #endif
1400 #ifdef L_eprintf
1401 #ifndef inhibit_libc
1403 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1404 #include <stdio.h>
1405 /* This is used by the `assert' macro. */
1406 extern void __eprintf (const char *, const char *, unsigned int, const char *)
1407 __attribute__ ((__noreturn__));
1409 void
1410 __eprintf (const char *string, const char *expression,
1411 unsigned int line, const char *filename)
1413 fprintf (stderr, string, expression, line, filename);
1414 fflush (stderr);
1415 abort ();
1418 #endif
1419 #endif
1421 #ifdef L_bb
1423 /* Structure emitted by -a */
1424 struct bb
1426 long zero_word;
1427 const char *filename;
1428 long *counts;
1429 long ncounts;
1430 struct bb *next;
1431 const unsigned long *addresses;
1433 /* Older GCC's did not emit these fields. */
1434 long nwords;
1435 const char **functions;
1436 const long *line_nums;
1437 const char **filenames;
1438 char *flags;
1441 #ifdef BLOCK_PROFILER_CODE
1442 BLOCK_PROFILER_CODE
1443 #else
1444 #ifndef inhibit_libc
1446 /* Simple minded basic block profiling output dumper for
1447 systems that don't provide tcov support. At present,
1448 it requires atexit and stdio. */
1450 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1451 #include <stdio.h>
1452 char *ctime ();
1454 #include "gbl-ctors.h"
1455 #include "gcov-io.h"
1456 #include <string.h>
1458 static struct bb *bb_head;
1460 /* Return the number of digits needed to print a value */
1461 /* __inline__ */ static int num_digits (long value, int base)
1463 int minus = (value < 0 && base != 16);
1464 unsigned long v = (minus) ? -value : value;
1465 int ret = minus;
1469 v /= base;
1470 ret++;
1472 while (v);
1474 return ret;
1477 void
1478 __bb_exit_func (void)
1480 FILE *da_file, *file;
1481 long time_value;
1482 int i;
1484 if (bb_head == 0)
1485 return;
1487 i = strlen (bb_head->filename) - 3;
1489 if (!strcmp (bb_head->filename+i, ".da"))
1491 /* Must be -fprofile-arcs not -a.
1492 Dump data in a form that gcov expects. */
1494 struct bb *ptr;
1496 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1498 /* If the file exists, and the number of counts in it is the same,
1499 then merge them in. */
1501 if ((da_file = fopen (ptr->filename, "r")) != 0)
1503 long n_counts = 0;
1505 if (__read_long (&n_counts, da_file, 8) != 0)
1507 fprintf (stderr, "arc profiling: Can't read output file %s.\n",
1508 ptr->filename);
1509 continue;
1512 if (n_counts == ptr->ncounts)
1514 int i;
1516 for (i = 0; i < n_counts; i++)
1518 long v = 0;
1520 if (__read_long (&v, da_file, 8) != 0)
1522 fprintf (stderr, "arc profiling: Can't read output file %s.\n",
1523 ptr->filename);
1524 break;
1526 ptr->counts[i] += v;
1530 if (fclose (da_file) == EOF)
1531 fprintf (stderr, "arc profiling: Error closing output file %s.\n",
1532 ptr->filename);
1534 if ((da_file = fopen (ptr->filename, "w")) == 0)
1536 fprintf (stderr, "arc profiling: Can't open output file %s.\n",
1537 ptr->filename);
1538 continue;
1541 /* ??? Should first write a header to the file. Preferably, a 4 byte
1542 magic number, 4 bytes containing the time the program was
1543 compiled, 4 bytes containing the last modification time of the
1544 source file, and 4 bytes indicating the compiler options used.
1546 That way we can easily verify that the proper source/executable/
1547 data file combination is being used from gcov. */
1549 if (__write_long (ptr->ncounts, da_file, 8) != 0)
1552 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1553 ptr->filename);
1555 else
1557 int j;
1558 long *count_ptr = ptr->counts;
1559 int ret = 0;
1560 for (j = ptr->ncounts; j > 0; j--)
1562 if (__write_long (*count_ptr, da_file, 8) != 0)
1564 ret=1;
1565 break;
1567 count_ptr++;
1569 if (ret)
1570 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1571 ptr->filename);
1574 if (fclose (da_file) == EOF)
1575 fprintf (stderr, "arc profiling: Error closing output file %s.\n",
1576 ptr->filename);
1579 return;
1582 /* Must be basic block profiling. Emit a human readable output file. */
1584 file = fopen ("bb.out", "a");
1586 if (!file)
1587 perror ("bb.out");
1589 else
1591 struct bb *ptr;
1593 /* This is somewhat type incorrect, but it avoids worrying about
1594 exactly where time.h is included from. It should be ok unless
1595 a void * differs from other pointer formats, or if sizeof (long)
1596 is < sizeof (time_t). It would be nice if we could assume the
1597 use of rationale standards here. */
1599 time ((void *) &time_value);
1600 fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value));
1602 /* We check the length field explicitly in order to allow compatibility
1603 with older GCC's which did not provide it. */
1605 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1607 int i;
1608 int func_p = (ptr->nwords >= sizeof (struct bb)
1609 && ptr->nwords <= 1000
1610 && ptr->functions);
1611 int line_p = (func_p && ptr->line_nums);
1612 int file_p = (func_p && ptr->filenames);
1613 int addr_p = (ptr->addresses != 0);
1614 long ncounts = ptr->ncounts;
1615 long cnt_max = 0;
1616 long line_max = 0;
1617 long addr_max = 0;
1618 int file_len = 0;
1619 int func_len = 0;
1620 int blk_len = num_digits (ncounts, 10);
1621 int cnt_len;
1622 int line_len;
1623 int addr_len;
1625 fprintf (file, "File %s, %ld basic blocks \n\n",
1626 ptr->filename, ncounts);
1628 /* Get max values for each field. */
1629 for (i = 0; i < ncounts; i++)
1631 const char *p;
1632 int len;
1634 if (cnt_max < ptr->counts[i])
1635 cnt_max = ptr->counts[i];
1637 if (addr_p && addr_max < ptr->addresses[i])
1638 addr_max = ptr->addresses[i];
1640 if (line_p && line_max < ptr->line_nums[i])
1641 line_max = ptr->line_nums[i];
1643 if (func_p)
1645 p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>";
1646 len = strlen (p);
1647 if (func_len < len)
1648 func_len = len;
1651 if (file_p)
1653 p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>";
1654 len = strlen (p);
1655 if (file_len < len)
1656 file_len = len;
1660 addr_len = num_digits (addr_max, 16);
1661 cnt_len = num_digits (cnt_max, 10);
1662 line_len = num_digits (line_max, 10);
1664 /* Now print out the basic block information. */
1665 for (i = 0; i < ncounts; i++)
1667 fprintf (file,
1668 " Block #%*d: executed %*ld time(s)",
1669 blk_len, i+1,
1670 cnt_len, ptr->counts[i]);
1672 if (addr_p)
1673 fprintf (file, " address= 0x%.*lx", addr_len,
1674 ptr->addresses[i]);
1676 if (func_p)
1677 fprintf (file, " function= %-*s", func_len,
1678 (ptr->functions[i]) ? ptr->functions[i] : "<none>");
1680 if (line_p)
1681 fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]);
1683 if (file_p)
1684 fprintf (file, " file= %s",
1685 (ptr->filenames[i]) ? ptr->filenames[i] : "<none>");
1687 fprintf (file, "\n");
1690 fprintf (file, "\n");
1691 fflush (file);
1694 fprintf (file, "\n\n");
1695 fclose (file);
1699 void
1700 __bb_init_func (struct bb *blocks)
1702 /* User is supposed to check whether the first word is non-0,
1703 but just in case.... */
1705 if (blocks->zero_word)
1706 return;
1708 /* Initialize destructor. */
1709 if (!bb_head)
1710 atexit (__bb_exit_func);
1712 /* Set up linked list. */
1713 blocks->zero_word = 1;
1714 blocks->next = bb_head;
1715 bb_head = blocks;
1718 #ifndef MACHINE_STATE_SAVE
1719 #define MACHINE_STATE_SAVE(ID)
1720 #endif
1721 #ifndef MACHINE_STATE_RESTORE
1722 #define MACHINE_STATE_RESTORE(ID)
1723 #endif
1725 /* Number of buckets in hashtable of basic block addresses. */
1727 #define BB_BUCKETS 311
1729 /* Maximum length of string in file bb.in. */
1731 #define BBINBUFSIZE 500
1733 /* BBINBUFSIZE-1 with double quotes. We could use #BBINBUFSIZE or
1734 "BBINBUFSIZE" but want to avoid trouble with preprocessors. */
1736 #define BBINBUFSIZESTR "499"
1738 struct bb_edge
1740 struct bb_edge *next;
1741 unsigned long src_addr;
1742 unsigned long dst_addr;
1743 unsigned long count;
1746 enum bb_func_mode
1748 TRACE_KEEP = 0, TRACE_ON = 1, TRACE_OFF = 2
1751 struct bb_func
1753 struct bb_func *next;
1754 char *funcname;
1755 char *filename;
1756 enum bb_func_mode mode;
1759 /* This is the connection to the outside world.
1760 The BLOCK_PROFILER macro must set __bb.blocks
1761 and __bb.blockno. */
1763 struct {
1764 unsigned long blockno;
1765 struct bb *blocks;
1766 } __bb;
1768 /* Vars to store addrs of source and destination basic blocks
1769 of a jump. */
1771 static unsigned long bb_src = 0;
1772 static unsigned long bb_dst = 0;
1774 static FILE *bb_tracefile = (FILE *) 0;
1775 static struct bb_edge **bb_hashbuckets = (struct bb_edge **) 0;
1776 static struct bb_func *bb_func_head = (struct bb_func *) 0;
1777 static unsigned long bb_callcount = 0;
1778 static int bb_mode = 0;
1780 static unsigned long *bb_stack = (unsigned long *) 0;
1781 static size_t bb_stacksize = 0;
1783 static int reported = 0;
1785 /* Trace modes:
1786 Always : Print execution frequencies of basic blocks
1787 to file bb.out.
1788 bb_mode & 1 != 0 : Dump trace of basic blocks to file bbtrace[.gz]
1789 bb_mode & 2 != 0 : Print jump frequencies to file bb.out.
1790 bb_mode & 4 != 0 : Cut call instructions from basic block flow.
1791 bb_mode & 8 != 0 : Insert return instructions in basic block flow.
1794 #ifdef HAVE_POPEN
1796 /*#include <sys/types.h>*/
1797 #include <sys/stat.h>
1798 /*#include <malloc.h>*/
1800 /* Commands executed by gopen. */
1802 #define GOPENDECOMPRESS "gzip -cd "
1803 #define GOPENCOMPRESS "gzip -c >"
1805 /* Like fopen but pipes through gzip. mode may only be "r" or "w".
1806 If it does not compile, simply replace gopen by fopen and delete
1807 '.gz' from any first parameter to gopen. */
1809 static FILE *
1810 gopen (char *fn, char *mode)
1812 int use_gzip;
1813 char *p;
1815 if (mode[1])
1816 return (FILE *) 0;
1818 if (mode[0] != 'r' && mode[0] != 'w')
1819 return (FILE *) 0;
1821 p = fn + strlen (fn)-1;
1822 use_gzip = ((p[-1] == '.' && (p[0] == 'Z' || p[0] == 'z'))
1823 || (p[-2] == '.' && p[-1] == 'g' && p[0] == 'z'));
1825 if (use_gzip)
1827 if (mode[0]=='r')
1829 FILE *f;
1830 char *s = (char *) malloc (sizeof (char) * strlen (fn)
1831 + sizeof (GOPENDECOMPRESS));
1832 strcpy (s, GOPENDECOMPRESS);
1833 strcpy (s + (sizeof (GOPENDECOMPRESS)-1), fn);
1834 f = popen (s, mode);
1835 free (s);
1836 return f;
1839 else
1841 FILE *f;
1842 char *s = (char *) malloc (sizeof (char) * strlen (fn)
1843 + sizeof (GOPENCOMPRESS));
1844 strcpy (s, GOPENCOMPRESS);
1845 strcpy (s + (sizeof (GOPENCOMPRESS)-1), fn);
1846 if (!(f = popen (s, mode)))
1847 f = fopen (s, mode);
1848 free (s);
1849 return f;
1853 else
1854 return fopen (fn, mode);
1857 static int
1858 gclose (FILE *f)
1860 struct stat buf;
1862 if (f != 0)
1864 if (!fstat (fileno (f), &buf) && S_ISFIFO (buf.st_mode))
1865 return pclose (f);
1867 return fclose (f);
1869 return 0;
1872 #endif /* HAVE_POPEN */
1874 /* Called once per program. */
1876 static void
1877 __bb_exit_trace_func ()
1879 FILE *file = fopen ("bb.out", "a");
1880 struct bb_func *f;
1881 struct bb *b;
1883 if (!file)
1884 perror ("bb.out");
1886 if (bb_mode & 1)
1888 if (!bb_tracefile)
1889 perror ("bbtrace");
1890 else
1891 #ifdef HAVE_POPEN
1892 gclose (bb_tracefile);
1893 #else
1894 fclose (bb_tracefile);
1895 #endif /* HAVE_POPEN */
1898 /* Check functions in `bb.in'. */
1900 if (file)
1902 long time_value;
1903 const struct bb_func *p;
1904 int printed_something = 0;
1905 struct bb *ptr;
1906 long blk;
1908 /* This is somewhat type incorrect. */
1909 time ((void *) &time_value);
1911 for (p = bb_func_head; p != (struct bb_func *) 0; p = p->next)
1913 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1915 if (!ptr->filename || (p->filename != (char *) 0 && strcmp (p->filename, ptr->filename)))
1916 continue;
1917 for (blk = 0; blk < ptr->ncounts; blk++)
1919 if (!strcmp (p->funcname, ptr->functions[blk]))
1920 goto found;
1924 if (!printed_something)
1926 fprintf (file, "Functions in `bb.in' not executed during basic block profiling on %s\n", ctime ((void *) &time_value));
1927 printed_something = 1;
1930 fprintf (file, "\tFunction %s", p->funcname);
1931 if (p->filename)
1932 fprintf (file, " of file %s", p->filename);
1933 fprintf (file, "\n" );
1935 found: ;
1938 if (printed_something)
1939 fprintf (file, "\n");
1943 if (bb_mode & 2)
1945 if (!bb_hashbuckets)
1947 if (!reported)
1949 fprintf (stderr, "Profiler: out of memory\n");
1950 reported = 1;
1952 return;
1955 else if (file)
1957 long time_value;
1958 int i;
1959 unsigned long addr_max = 0;
1960 unsigned long cnt_max = 0;
1961 int cnt_len;
1962 int addr_len;
1964 /* This is somewhat type incorrect, but it avoids worrying about
1965 exactly where time.h is included from. It should be ok unless
1966 a void * differs from other pointer formats, or if sizeof (long)
1967 is < sizeof (time_t). It would be nice if we could assume the
1968 use of rationale standards here. */
1970 time ((void *) &time_value);
1971 fprintf (file, "Basic block jump tracing");
1973 switch (bb_mode & 12)
1975 case 0:
1976 fprintf (file, " (with call)");
1977 break;
1979 case 4:
1980 /* Print nothing. */
1981 break;
1983 case 8:
1984 fprintf (file, " (with call & ret)");
1985 break;
1987 case 12:
1988 fprintf (file, " (with ret)");
1989 break;
1992 fprintf (file, " finished on %s\n", ctime ((void *) &time_value));
1994 for (i = 0; i < BB_BUCKETS; i++)
1996 struct bb_edge *bucket = bb_hashbuckets[i];
1997 for ( ; bucket; bucket = bucket->next )
1999 if (addr_max < bucket->src_addr)
2000 addr_max = bucket->src_addr;
2001 if (addr_max < bucket->dst_addr)
2002 addr_max = bucket->dst_addr;
2003 if (cnt_max < bucket->count)
2004 cnt_max = bucket->count;
2007 addr_len = num_digits (addr_max, 16);
2008 cnt_len = num_digits (cnt_max, 10);
2010 for ( i = 0; i < BB_BUCKETS; i++)
2012 struct bb_edge *bucket = bb_hashbuckets[i];
2013 for ( ; bucket; bucket = bucket->next )
2015 fprintf (file, "Jump from block 0x%.*lx to "
2016 "block 0x%.*lx executed %*lu time(s)\n",
2017 addr_len, bucket->src_addr,
2018 addr_len, bucket->dst_addr,
2019 cnt_len, bucket->count);
2023 fprintf (file, "\n");
2028 if (file)
2029 fclose (file);
2031 /* Free allocated memory. */
2033 f = bb_func_head;
2034 while (f)
2036 struct bb_func *old = f;
2038 f = f->next;
2039 if (old->funcname) free (old->funcname);
2040 if (old->filename) free (old->filename);
2041 free (old);
2044 if (bb_stack)
2045 free (bb_stack);
2047 if (bb_hashbuckets)
2049 int i;
2051 for (i = 0; i < BB_BUCKETS; i++)
2053 struct bb_edge *old, *bucket = bb_hashbuckets[i];
2055 while (bucket)
2057 old = bucket;
2058 bucket = bucket->next;
2059 free (old);
2062 free (bb_hashbuckets);
2065 for (b = bb_head; b; b = b->next)
2066 if (b->flags) free (b->flags);
2069 /* Called once per program. */
2071 static void
2072 __bb_init_prg ()
2074 FILE *file;
2075 char buf[BBINBUFSIZE];
2076 const char *p;
2077 const char *pos;
2078 enum bb_func_mode m;
2079 int i;
2081 /* Initialize destructor. */
2082 atexit (__bb_exit_func);
2084 if (!(file = fopen ("bb.in", "r")))
2085 return;
2087 while(fscanf (file, " %" BBINBUFSIZESTR "s ", buf) != EOF)
2089 p = buf;
2090 if (*p == '-')
2092 m = TRACE_OFF;
2093 p++;
2095 else
2097 m = TRACE_ON;
2099 if (!strcmp (p, "__bb_trace__"))
2100 bb_mode |= 1;
2101 else if (!strcmp (p, "__bb_jumps__"))
2102 bb_mode |= 2;
2103 else if (!strcmp (p, "__bb_hidecall__"))
2104 bb_mode |= 4;
2105 else if (!strcmp (p, "__bb_showret__"))
2106 bb_mode |= 8;
2107 else
2109 struct bb_func *f = (struct bb_func *) malloc (sizeof (struct bb_func));
2110 if (f)
2112 unsigned long l;
2113 f->next = bb_func_head;
2114 if ((pos = strchr (p, ':')))
2116 if (!(f->funcname = (char *) malloc (strlen (pos+1)+1)))
2117 continue;
2118 strcpy (f->funcname, pos+1);
2119 l = pos-p;
2120 if ((f->filename = (char *) malloc (l+1)))
2122 strncpy (f->filename, p, l);
2123 f->filename[l] = '\0';
2125 else
2126 f->filename = (char *) 0;
2128 else
2130 if (!(f->funcname = (char *) malloc (strlen (p)+1)))
2131 continue;
2132 strcpy (f->funcname, p);
2133 f->filename = (char *) 0;
2135 f->mode = m;
2136 bb_func_head = f;
2140 fclose (file);
2142 #ifdef HAVE_POPEN
2144 if (bb_mode & 1)
2145 bb_tracefile = gopen ("bbtrace.gz", "w");
2147 #else
2149 if (bb_mode & 1)
2150 bb_tracefile = fopen ("bbtrace", "w");
2152 #endif /* HAVE_POPEN */
2154 if (bb_mode & 2)
2156 bb_hashbuckets = (struct bb_edge **)
2157 malloc (BB_BUCKETS * sizeof (struct bb_edge *));
2158 if (bb_hashbuckets)
2159 /* Use a loop here rather than calling bzero to avoid having to
2160 conditionalize its existance. */
2161 for (i = 0; i < BB_BUCKETS; i++)
2162 bb_hashbuckets[i] = 0;
2165 if (bb_mode & 12)
2167 bb_stacksize = 10;
2168 bb_stack = (unsigned long *) malloc (bb_stacksize * sizeof (*bb_stack));
2171 /* Initialize destructor. */
2172 atexit (__bb_exit_trace_func);
2175 /* Called upon entering a basic block. */
2177 void
2178 __bb_trace_func ()
2180 struct bb_edge *bucket;
2182 MACHINE_STATE_SAVE("1")
2184 if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2185 goto skip;
2187 bb_dst = __bb.blocks->addresses[__bb.blockno];
2188 __bb.blocks->counts[__bb.blockno]++;
2190 if (bb_tracefile)
2192 fwrite (&bb_dst, sizeof (unsigned long), 1, bb_tracefile);
2195 if (bb_hashbuckets)
2197 struct bb_edge **startbucket, **oldnext;
2199 oldnext = startbucket
2200 = & bb_hashbuckets[ (((int) bb_src*8) ^ (int) bb_dst) % BB_BUCKETS ];
2201 bucket = *startbucket;
2203 for (bucket = *startbucket; bucket;
2204 oldnext = &(bucket->next), bucket = *oldnext)
2206 if (bucket->src_addr == bb_src
2207 && bucket->dst_addr == bb_dst)
2209 bucket->count++;
2210 *oldnext = bucket->next;
2211 bucket->next = *startbucket;
2212 *startbucket = bucket;
2213 goto ret;
2217 bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2219 if (!bucket)
2221 if (!reported)
2223 fprintf (stderr, "Profiler: out of memory\n");
2224 reported = 1;
2228 else
2230 bucket->src_addr = bb_src;
2231 bucket->dst_addr = bb_dst;
2232 bucket->next = *startbucket;
2233 *startbucket = bucket;
2234 bucket->count = 1;
2238 ret:
2239 bb_src = bb_dst;
2241 skip:
2244 MACHINE_STATE_RESTORE("1")
2248 /* Called when returning from a function and `__bb_showret__' is set. */
2250 static void
2251 __bb_trace_func_ret ()
2253 struct bb_edge *bucket;
2255 if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2256 goto skip;
2258 if (bb_hashbuckets)
2260 struct bb_edge **startbucket, **oldnext;
2262 oldnext = startbucket
2263 = & bb_hashbuckets[ (((int) bb_dst * 8) ^ (int) bb_src) % BB_BUCKETS ];
2264 bucket = *startbucket;
2266 for (bucket = *startbucket; bucket;
2267 oldnext = &(bucket->next), bucket = *oldnext)
2269 if (bucket->src_addr == bb_dst
2270 && bucket->dst_addr == bb_src)
2272 bucket->count++;
2273 *oldnext = bucket->next;
2274 bucket->next = *startbucket;
2275 *startbucket = bucket;
2276 goto ret;
2280 bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2282 if (!bucket)
2284 if (!reported)
2286 fprintf (stderr, "Profiler: out of memory\n");
2287 reported = 1;
2291 else
2293 bucket->src_addr = bb_dst;
2294 bucket->dst_addr = bb_src;
2295 bucket->next = *startbucket;
2296 *startbucket = bucket;
2297 bucket->count = 1;
2301 ret:
2302 bb_dst = bb_src;
2304 skip:
2309 /* Called upon entering the first function of a file. */
2311 static void
2312 __bb_init_file (struct bb *blocks)
2315 const struct bb_func *p;
2316 long blk, ncounts = blocks->ncounts;
2317 const char **functions = blocks->functions;
2319 /* Set up linked list. */
2320 blocks->zero_word = 1;
2321 blocks->next = bb_head;
2322 bb_head = blocks;
2324 blocks->flags = 0;
2325 if (!bb_func_head
2326 || !(blocks->flags = (char *) malloc (sizeof (char) * blocks->ncounts)))
2327 return;
2329 for (blk = 0; blk < ncounts; blk++)
2330 blocks->flags[blk] = 0;
2332 for (blk = 0; blk < ncounts; blk++)
2334 for (p = bb_func_head; p; p = p->next)
2336 if (!strcmp (p->funcname, functions[blk])
2337 && (!p->filename || !strcmp (p->filename, blocks->filename)))
2339 blocks->flags[blk] |= p->mode;
2346 /* Called when exiting from a function. */
2348 void
2349 __bb_trace_ret ()
2352 MACHINE_STATE_SAVE("2")
2354 if (bb_callcount)
2356 if ((bb_mode & 12) && bb_stacksize > bb_callcount)
2358 bb_src = bb_stack[bb_callcount];
2359 if (bb_mode & 8)
2360 __bb_trace_func_ret ();
2363 bb_callcount -= 1;
2366 MACHINE_STATE_RESTORE("2")
2370 /* Called when entering a function. */
2372 void
2373 __bb_init_trace_func (struct bb *blocks, unsigned long blockno)
2375 static int trace_init = 0;
2377 MACHINE_STATE_SAVE("3")
2379 if (!blocks->zero_word)
2381 if (!trace_init)
2383 trace_init = 1;
2384 __bb_init_prg ();
2386 __bb_init_file (blocks);
2389 if (bb_callcount)
2392 bb_callcount += 1;
2394 if (bb_mode & 12)
2396 if (bb_callcount >= bb_stacksize)
2398 size_t newsize = bb_callcount + 100;
2400 bb_stack = (unsigned long *) realloc (bb_stack, newsize);
2401 if (! bb_stack)
2403 if (!reported)
2405 fprintf (stderr, "Profiler: out of memory\n");
2406 reported = 1;
2408 bb_stacksize = 0;
2409 goto stack_overflow;
2411 bb_stacksize = newsize;
2413 bb_stack[bb_callcount] = bb_src;
2415 if (bb_mode & 4)
2416 bb_src = 0;
2420 stack_overflow:;
2424 else if (blocks->flags && (blocks->flags[blockno] & TRACE_ON))
2426 bb_callcount = 1;
2427 bb_src = 0;
2429 if (bb_stack)
2430 bb_stack[bb_callcount] = bb_src;
2433 MACHINE_STATE_RESTORE("3")
2436 #endif /* not inhibit_libc */
2437 #endif /* not BLOCK_PROFILER_CODE */
2438 #endif /* L_bb */
2440 #ifdef L_shtab
2441 unsigned int __shtab[] = {
2442 0x00000001, 0x00000002, 0x00000004, 0x00000008,
2443 0x00000010, 0x00000020, 0x00000040, 0x00000080,
2444 0x00000100, 0x00000200, 0x00000400, 0x00000800,
2445 0x00001000, 0x00002000, 0x00004000, 0x00008000,
2446 0x00010000, 0x00020000, 0x00040000, 0x00080000,
2447 0x00100000, 0x00200000, 0x00400000, 0x00800000,
2448 0x01000000, 0x02000000, 0x04000000, 0x08000000,
2449 0x10000000, 0x20000000, 0x40000000, 0x80000000
2451 #endif
2453 #ifdef L_clear_cache
2454 /* Clear part of an instruction cache. */
2456 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
2458 void
2459 __clear_cache (char *beg, char *end)
2461 #ifdef CLEAR_INSN_CACHE
2462 CLEAR_INSN_CACHE (beg, end);
2463 #else
2464 #ifdef INSN_CACHE_SIZE
2465 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
2466 static int initialized;
2467 int offset;
2468 void *start_addr
2469 void *end_addr;
2470 typedef (*function_ptr) ();
2472 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
2473 /* It's cheaper to clear the whole cache.
2474 Put in a series of jump instructions so that calling the beginning
2475 of the cache will clear the whole thing. */
2477 if (! initialized)
2479 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2480 & -INSN_CACHE_LINE_WIDTH);
2481 int end_ptr = ptr + INSN_CACHE_SIZE;
2483 while (ptr < end_ptr)
2485 *(INSTRUCTION_TYPE *)ptr
2486 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
2487 ptr += INSN_CACHE_LINE_WIDTH;
2489 *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
2491 initialized = 1;
2494 /* Call the beginning of the sequence. */
2495 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2496 & -INSN_CACHE_LINE_WIDTH))
2497 ());
2499 #else /* Cache is large. */
2501 if (! initialized)
2503 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2504 & -INSN_CACHE_LINE_WIDTH);
2506 while (ptr < (int) array + sizeof array)
2508 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
2509 ptr += INSN_CACHE_LINE_WIDTH;
2512 initialized = 1;
2515 /* Find the location in array that occupies the same cache line as BEG. */
2517 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
2518 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
2519 & -INSN_CACHE_PLANE_SIZE)
2520 + offset);
2522 /* Compute the cache alignment of the place to stop clearing. */
2523 #if 0 /* This is not needed for gcc's purposes. */
2524 /* If the block to clear is bigger than a cache plane,
2525 we clear the entire cache, and OFFSET is already correct. */
2526 if (end < beg + INSN_CACHE_PLANE_SIZE)
2527 #endif
2528 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
2529 & -INSN_CACHE_LINE_WIDTH)
2530 & (INSN_CACHE_PLANE_SIZE - 1));
2532 #if INSN_CACHE_DEPTH > 1
2533 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
2534 if (end_addr <= start_addr)
2535 end_addr += INSN_CACHE_PLANE_SIZE;
2537 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
2539 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
2540 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
2542 while (addr != stop)
2544 /* Call the return instruction at ADDR. */
2545 ((function_ptr) addr) ();
2547 addr += INSN_CACHE_LINE_WIDTH;
2550 #else /* just one plane */
2553 /* Call the return instruction at START_ADDR. */
2554 ((function_ptr) start_addr) ();
2556 start_addr += INSN_CACHE_LINE_WIDTH;
2558 while ((start_addr % INSN_CACHE_SIZE) != offset);
2559 #endif /* just one plane */
2560 #endif /* Cache is large */
2561 #endif /* Cache exists */
2562 #endif /* CLEAR_INSN_CACHE */
2565 #endif /* L_clear_cache */
2567 #ifdef L_trampoline
2569 /* Jump to a trampoline, loading the static chain address. */
2571 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
2573 long getpagesize()
2575 #ifdef _ALPHA_
2576 return 8192;
2577 #else
2578 return 4096;
2579 #endif
2582 #ifdef i386
2583 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
2584 #endif
2587 mprotect (char *addr, int len, int prot)
2589 int np, op;
2591 if (prot == 7)
2592 np = 0x40;
2593 else if (prot == 5)
2594 np = 0x20;
2595 else if (prot == 4)
2596 np = 0x10;
2597 else if (prot == 3)
2598 np = 0x04;
2599 else if (prot == 1)
2600 np = 0x02;
2601 else if (prot == 0)
2602 np = 0x01;
2604 if (VirtualProtect (addr, len, np, &op))
2605 return 0;
2606 else
2607 return -1;
2610 #endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
2612 #ifdef TRANSFER_FROM_TRAMPOLINE
2613 TRANSFER_FROM_TRAMPOLINE
2614 #endif
2616 #if defined (NeXT) && defined (__MACH__)
2618 /* Make stack executable so we can call trampolines on stack.
2619 This is called from INITIALIZE_TRAMPOLINE in next.h. */
2620 #ifdef NeXTStep21
2621 #include <mach.h>
2622 #else
2623 #include <mach/mach.h>
2624 #endif
2626 void
2627 __enable_execute_stack (char *addr)
2629 kern_return_t r;
2630 char *eaddr = addr + TRAMPOLINE_SIZE;
2631 vm_address_t a = (vm_address_t) addr;
2633 /* turn on execute access on stack */
2634 r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
2635 if (r != KERN_SUCCESS)
2637 mach_error("vm_protect VM_PROT_ALL", r);
2638 exit(1);
2641 /* We inline the i-cache invalidation for speed */
2643 #ifdef CLEAR_INSN_CACHE
2644 CLEAR_INSN_CACHE (addr, eaddr);
2645 #else
2646 __clear_cache ((int) addr, (int) eaddr);
2647 #endif
2650 #endif /* defined (NeXT) && defined (__MACH__) */
2652 #ifdef __convex__
2654 /* Make stack executable so we can call trampolines on stack.
2655 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
2657 #include <sys/mman.h>
2658 #include <sys/vmparam.h>
2659 #include <machine/machparam.h>
2661 void
2662 __enable_execute_stack ()
2664 int fp;
2665 static unsigned lowest = USRSTACK;
2666 unsigned current = (unsigned) &fp & -NBPG;
2668 if (lowest > current)
2670 unsigned len = lowest - current;
2671 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
2672 lowest = current;
2675 /* Clear instruction cache in case an old trampoline is in it. */
2676 asm ("pich");
2678 #endif /* __convex__ */
2680 #ifdef __sysV88__
2682 /* Modified from the convex -code above. */
2684 #include <sys/param.h>
2685 #include <errno.h>
2686 #include <sys/m88kbcs.h>
2688 void
2689 __enable_execute_stack ()
2691 int save_errno;
2692 static unsigned long lowest = USRSTACK;
2693 unsigned long current = (unsigned long) &save_errno & -NBPC;
2695 /* Ignore errno being set. memctl sets errno to EINVAL whenever the
2696 address is seen as 'negative'. That is the case with the stack. */
2698 save_errno=errno;
2699 if (lowest > current)
2701 unsigned len=lowest-current;
2702 memctl(current,len,MCT_TEXT);
2703 lowest = current;
2705 else
2706 memctl(current,NBPC,MCT_TEXT);
2707 errno=save_errno;
2710 #endif /* __sysV88__ */
2712 #ifdef __sysV68__
2714 #include <sys/signal.h>
2715 #include <errno.h>
2717 /* Motorola forgot to put memctl.o in the libp version of libc881.a,
2718 so define it here, because we need it in __clear_insn_cache below */
2719 /* On older versions of this OS, no memctl or MCT_TEXT are defined;
2720 hence we enable this stuff only if MCT_TEXT is #define'd. */
2722 #ifdef MCT_TEXT
2723 asm("\n\
2724 global memctl\n\
2725 memctl:\n\
2726 movq &75,%d0\n\
2727 trap &0\n\
2728 bcc.b noerror\n\
2729 jmp cerror%\n\
2730 noerror:\n\
2731 movq &0,%d0\n\
2732 rts");
2733 #endif
2735 /* Clear instruction cache so we can call trampolines on stack.
2736 This is called from FINALIZE_TRAMPOLINE in mot3300.h. */
2738 void
2739 __clear_insn_cache ()
2741 #ifdef MCT_TEXT
2742 int save_errno;
2744 /* Preserve errno, because users would be surprised to have
2745 errno changing without explicitly calling any system-call. */
2746 save_errno = errno;
2748 /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache.
2749 No need to use an address derived from _start or %sp, as 0 works also. */
2750 memctl(0, 4096, MCT_TEXT);
2751 errno = save_errno;
2752 #endif
2755 #endif /* __sysV68__ */
2757 #ifdef __pyr__
2759 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2760 #include <stdio.h>
2761 #include <sys/mman.h>
2762 #include <sys/types.h>
2763 #include <sys/param.h>
2764 #include <sys/vmmac.h>
2766 /* Modified from the convex -code above.
2767 mremap promises to clear the i-cache. */
2769 void
2770 __enable_execute_stack ()
2772 int fp;
2773 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
2774 PROT_READ|PROT_WRITE|PROT_EXEC))
2776 perror ("mprotect in __enable_execute_stack");
2777 fflush (stderr);
2778 abort ();
2781 #endif /* __pyr__ */
2783 #if defined (sony_news) && defined (SYSTYPE_BSD)
2785 #include <stdio.h>
2786 #include <sys/types.h>
2787 #include <sys/param.h>
2788 #include <syscall.h>
2789 #include <machine/sysnews.h>
2791 /* cacheflush function for NEWS-OS 4.2.
2792 This function is called from trampoline-initialize code
2793 defined in config/mips/mips.h. */
2795 void
2796 cacheflush (char *beg, int size, int flag)
2798 if (syscall (SYS_sysnews, NEWS_CACHEFLUSH, beg, size, FLUSH_BCACHE))
2800 perror ("cache_flush");
2801 fflush (stderr);
2802 abort ();
2806 #endif /* sony_news */
2807 #endif /* L_trampoline */
2809 #ifndef __CYGWIN__
2810 #ifdef L__main
2812 #include "gbl-ctors.h"
2813 /* Some systems use __main in a way incompatible with its use in gcc, in these
2814 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2815 give the same symbol without quotes for an alternative entry point. You
2816 must define both, or neither. */
2817 #ifndef NAME__MAIN
2818 #define NAME__MAIN "__main"
2819 #define SYMBOL__MAIN __main
2820 #endif
2822 #ifdef INIT_SECTION_ASM_OP
2823 #undef HAS_INIT_SECTION
2824 #define HAS_INIT_SECTION
2825 #endif
2827 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
2829 /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
2830 code to run constructors. In that case, we need to handle EH here, too. */
2832 #ifdef EH_FRAME_SECTION
2833 #include "frame.h"
2834 extern unsigned char __EH_FRAME_BEGIN__[];
2835 #endif
2837 /* Run all the global destructors on exit from the program. */
2839 void
2840 __do_global_dtors ()
2842 #ifdef DO_GLOBAL_DTORS_BODY
2843 DO_GLOBAL_DTORS_BODY;
2844 #else
2845 static func_ptr *p = __DTOR_LIST__ + 1;
2846 while (*p)
2848 p++;
2849 (*(p-1)) ();
2851 #endif
2852 #ifdef EH_FRAME_SECTION
2853 __deregister_frame_info (__EH_FRAME_BEGIN__);
2854 #endif
2856 #endif
2858 #ifndef HAS_INIT_SECTION
2859 /* Run all the global constructors on entry to the program. */
2861 void
2862 __do_global_ctors ()
2864 #ifdef EH_FRAME_SECTION
2866 static struct object object;
2867 __register_frame_info (__EH_FRAME_BEGIN__, &object);
2869 #endif
2870 DO_GLOBAL_CTORS_BODY;
2871 atexit (__do_global_dtors);
2873 #endif /* no HAS_INIT_SECTION */
2875 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
2876 /* Subroutine called automatically by `main'.
2877 Compiling a global function named `main'
2878 produces an automatic call to this function at the beginning.
2880 For many systems, this routine calls __do_global_ctors.
2881 For systems which support a .init section we use the .init section
2882 to run __do_global_ctors, so we need not do anything here. */
2884 void
2885 SYMBOL__MAIN ()
2887 /* Support recursive calls to `main': run initializers just once. */
2888 static int initialized;
2889 if (! initialized)
2891 initialized = 1;
2892 __do_global_ctors ();
2895 #endif /* no HAS_INIT_SECTION or INVOKE__main */
2897 #endif /* L__main */
2898 #endif /* __CYGWIN__ */
2900 #ifdef L_ctors
2902 #include "gbl-ctors.h"
2904 /* Provide default definitions for the lists of constructors and
2905 destructors, so that we don't get linker errors. These symbols are
2906 intentionally bss symbols, so that gld and/or collect will provide
2907 the right values. */
2909 /* We declare the lists here with two elements each,
2910 so that they are valid empty lists if no other definition is loaded.
2912 If we are using the old "set" extensions to have the gnu linker
2913 collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
2914 must be in the bss/common section.
2916 Long term no port should use those extensions. But many still do. */
2917 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
2918 #if defined (ASM_OUTPUT_CONSTRUCTOR) || defined (USE_COLLECT2)
2919 func_ptr __CTOR_LIST__[2] = {0, 0};
2920 func_ptr __DTOR_LIST__[2] = {0, 0};
2921 #else
2922 func_ptr __CTOR_LIST__[2];
2923 func_ptr __DTOR_LIST__[2];
2924 #endif
2925 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
2926 #endif /* L_ctors */
2928 #ifdef L_exit
2930 #include "gbl-ctors.h"
2932 #ifdef NEED_ATEXIT
2934 #ifndef ON_EXIT
2936 # include <errno.h>
2938 static func_ptr *atexit_chain = 0;
2939 static long atexit_chain_length = 0;
2940 static volatile long last_atexit_chain_slot = -1;
2943 atexit (func_ptr func)
2945 if (++last_atexit_chain_slot == atexit_chain_length)
2947 atexit_chain_length += 32;
2948 if (atexit_chain)
2949 atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
2950 * sizeof (func_ptr));
2951 else
2952 atexit_chain = (func_ptr *) malloc (atexit_chain_length
2953 * sizeof (func_ptr));
2954 if (! atexit_chain)
2956 atexit_chain_length = 0;
2957 last_atexit_chain_slot = -1;
2958 errno = ENOMEM;
2959 return (-1);
2962 atexit_chain[last_atexit_chain_slot] = func;
2963 return (0);
2966 extern void _cleanup ();
2967 extern void _exit () __attribute__ ((noreturn));
2969 void
2970 exit (int status)
2972 if (atexit_chain)
2974 for ( ; last_atexit_chain_slot-- >= 0; )
2976 (*atexit_chain[last_atexit_chain_slot + 1]) ();
2977 atexit_chain[last_atexit_chain_slot + 1] = 0;
2979 free (atexit_chain);
2980 atexit_chain = 0;
2982 #ifdef EXIT_BODY
2983 EXIT_BODY;
2984 #else
2985 _cleanup ();
2986 #endif
2987 _exit (status);
2990 #else /* ON_EXIT */
2992 /* Simple; we just need a wrapper for ON_EXIT. */
2994 atexit (func_ptr func)
2996 return ON_EXIT (func);
2999 #endif /* ON_EXIT */
3000 #endif /* NEED_ATEXIT */
3002 #endif /* L_exit */
3004 #ifdef L_eh
3006 #include "gthr.h"
3008 /* Shared exception handling support routines. */
3010 extern void __default_terminate (void) __attribute__ ((__noreturn__));
3012 void
3013 __default_terminate ()
3015 abort ();
3018 void (*__terminate_func)() = __default_terminate;
3020 void
3021 __terminate ()
3023 (*__terminate_func)();
3026 void *
3027 __throw_type_match (void *catch_type, void *throw_type, void *obj)
3029 #if 0
3030 printf ("__throw_type_match (): catch_type = %s, throw_type = %s\n",
3031 catch_type, throw_type);
3032 #endif
3033 if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)
3034 return obj;
3035 return 0;
3038 void
3039 __empty ()
3044 /* Include definitions of EH context and table layout */
3046 #include "eh-common.h"
3047 #ifndef inhibit_libc
3048 #include <stdio.h>
3049 #endif
3051 /* Allocate and return a new EH context structure. */
3053 extern void __throw ();
3055 static void *
3056 new_eh_context ()
3058 struct eh_full_context {
3059 struct eh_context c;
3060 void *top_elt[2];
3061 } *ehfc = (struct eh_full_context *) malloc (sizeof *ehfc);
3063 if (! ehfc)
3064 __terminate ();
3066 memset (ehfc, 0, sizeof *ehfc);
3068 ehfc->c.dynamic_handler_chain = (void **) ehfc->top_elt;
3070 /* This should optimize out entirely. This should always be true,
3071 but just in case it ever isn't, don't allow bogus code to be
3072 generated. */
3074 if ((void*)(&ehfc->c) != (void*)ehfc)
3075 __terminate ();
3077 return &ehfc->c;
3080 #if __GTHREADS
3081 static __gthread_key_t eh_context_key;
3083 /* Destructor for struct eh_context. */
3084 static void
3085 eh_context_free (void *ptr)
3087 __gthread_key_dtor (eh_context_key, ptr);
3088 if (ptr)
3089 free (ptr);
3091 #endif
3093 /* Pointer to function to return EH context. */
3095 static struct eh_context *eh_context_initialize ();
3096 static struct eh_context *eh_context_static ();
3097 #if __GTHREADS
3098 static struct eh_context *eh_context_specific ();
3099 #endif
3101 static struct eh_context *(*get_eh_context) () = &eh_context_initialize;
3103 /* Routine to get EH context.
3104 This one will simply call the function pointer. */
3106 void *
3107 __get_eh_context ()
3109 return (void *) (*get_eh_context) ();
3112 /* Get and set the language specific info pointer. */
3114 void **
3115 __get_eh_info ()
3117 struct eh_context *eh = (*get_eh_context) ();
3118 return &eh->info;
3121 #if __GTHREADS
3122 static void
3123 eh_threads_initialize ()
3125 /* Try to create the key. If it fails, revert to static method,
3126 otherwise start using thread specific EH contexts. */
3127 if (__gthread_key_create (&eh_context_key, &eh_context_free) == 0)
3128 get_eh_context = &eh_context_specific;
3129 else
3130 get_eh_context = &eh_context_static;
3132 #endif /* no __GTHREADS */
3134 /* Initialize EH context.
3135 This will be called only once, since we change GET_EH_CONTEXT
3136 pointer to another routine. */
3138 static struct eh_context *
3139 eh_context_initialize ()
3141 #if __GTHREADS
3143 static __gthread_once_t once = __GTHREAD_ONCE_INIT;
3144 /* Make sure that get_eh_context does not point to us anymore.
3145 Some systems have dummy thread routines in their libc that
3146 return a success (Solaris 2.6 for example). */
3147 if (__gthread_once (&once, eh_threads_initialize) != 0
3148 || get_eh_context == &eh_context_initialize)
3150 /* Use static version of EH context. */
3151 get_eh_context = &eh_context_static;
3154 #else /* no __GTHREADS */
3156 /* Use static version of EH context. */
3157 get_eh_context = &eh_context_static;
3159 #endif /* no __GTHREADS */
3161 return (*get_eh_context) ();
3164 /* Return a static EH context. */
3166 static struct eh_context *
3167 eh_context_static ()
3169 static struct eh_context eh;
3170 static int initialized;
3171 static void *top_elt[2];
3173 if (! initialized)
3175 initialized = 1;
3176 memset (&eh, 0, sizeof eh);
3177 eh.dynamic_handler_chain = top_elt;
3179 return &eh;
3182 #if __GTHREADS
3183 /* Return a thread specific EH context. */
3185 static struct eh_context *
3186 eh_context_specific ()
3188 struct eh_context *eh;
3189 eh = (struct eh_context *) __gthread_getspecific (eh_context_key);
3190 if (! eh)
3192 eh = new_eh_context ();
3193 if (__gthread_setspecific (eh_context_key, (void *) eh) != 0)
3194 __terminate ();
3197 return eh;
3199 #endif __GTHREADS
3201 /* Support routines for setjmp/longjmp exception handling. */
3203 /* Calls to __sjthrow are generated by the compiler when an exception
3204 is raised when using the setjmp/longjmp exception handling codegen
3205 method. */
3207 #ifdef DONT_USE_BUILTIN_SETJMP
3208 extern void longjmp (void *, int);
3209 #endif
3211 /* Routine to get the head of the current thread's dynamic handler chain
3212 use for exception handling. */
3214 void ***
3215 __get_dynamic_handler_chain ()
3217 struct eh_context *eh = (*get_eh_context) ();
3218 return &eh->dynamic_handler_chain;
3221 /* This is used to throw an exception when the setjmp/longjmp codegen
3222 method is used for exception handling.
3224 We call __terminate if there are no handlers left. Otherwise we run the
3225 cleanup actions off the dynamic cleanup stack, and pop the top of the
3226 dynamic handler chain, and use longjmp to transfer back to the associated
3227 handler. */
3229 extern void __sjthrow (void) __attribute__ ((__noreturn__));
3231 void
3232 __sjthrow ()
3234 struct eh_context *eh = (*get_eh_context) ();
3235 void ***dhc = &eh->dynamic_handler_chain;
3236 void *jmpbuf;
3237 void (*func)(void *, int);
3238 void *arg;
3239 void ***cleanup;
3241 /* The cleanup chain is one word into the buffer. Get the cleanup
3242 chain. */
3243 cleanup = (void***)&(*dhc)[1];
3245 /* If there are any cleanups in the chain, run them now. */
3246 if (cleanup[0])
3248 double store[200];
3249 void **buf = (void**)store;
3250 buf[1] = 0;
3251 buf[0] = (*dhc);
3253 /* try { */
3254 #ifdef DONT_USE_BUILTIN_SETJMP
3255 if (! setjmp (&buf[2]))
3256 #else
3257 if (! __builtin_setjmp (&buf[2]))
3258 #endif
3260 *dhc = buf;
3261 while (cleanup[0])
3263 func = (void(*)(void*, int))cleanup[0][1];
3264 arg = (void*)cleanup[0][2];
3266 /* Update this before running the cleanup. */
3267 cleanup[0] = (void **)cleanup[0][0];
3269 (*func)(arg, 2);
3271 *dhc = buf[0];
3273 /* catch (...) */
3274 else
3276 __terminate ();
3280 /* We must call terminate if we try and rethrow an exception, when
3281 there is no exception currently active and when there are no
3282 handlers left. */
3283 if (! eh->info || (*dhc)[0] == 0)
3284 __terminate ();
3286 /* Find the jmpbuf associated with the top element of the dynamic
3287 handler chain. The jumpbuf starts two words into the buffer. */
3288 jmpbuf = &(*dhc)[2];
3290 /* Then we pop the top element off the dynamic handler chain. */
3291 *dhc = (void**)(*dhc)[0];
3293 /* And then we jump to the handler. */
3295 #ifdef DONT_USE_BUILTIN_SETJMP
3296 longjmp (jmpbuf, 1);
3297 #else
3298 __builtin_longjmp (jmpbuf, 1);
3299 #endif
3302 /* Run cleanups on the dynamic cleanup stack for the current dynamic
3303 handler, then pop the handler off the dynamic handler stack, and
3304 then throw. This is used to skip the first handler, and transfer
3305 control to the next handler in the dynamic handler stack. */
3307 extern void __sjpopnthrow (void) __attribute__ ((__noreturn__));
3309 void
3310 __sjpopnthrow ()
3312 struct eh_context *eh = (*get_eh_context) ();
3313 void ***dhc = &eh->dynamic_handler_chain;
3314 void (*func)(void *, int);
3315 void *arg;
3316 void ***cleanup;
3318 /* The cleanup chain is one word into the buffer. Get the cleanup
3319 chain. */
3320 cleanup = (void***)&(*dhc)[1];
3322 /* If there are any cleanups in the chain, run them now. */
3323 if (cleanup[0])
3325 double store[200];
3326 void **buf = (void**)store;
3327 buf[1] = 0;
3328 buf[0] = (*dhc);
3330 /* try { */
3331 #ifdef DONT_USE_BUILTIN_SETJMP
3332 if (! setjmp (&buf[2]))
3333 #else
3334 if (! __builtin_setjmp (&buf[2]))
3335 #endif
3337 *dhc = buf;
3338 while (cleanup[0])
3340 func = (void(*)(void*, int))cleanup[0][1];
3341 arg = (void*)cleanup[0][2];
3343 /* Update this before running the cleanup. */
3344 cleanup[0] = (void **)cleanup[0][0];
3346 (*func)(arg, 2);
3348 *dhc = buf[0];
3350 /* catch (...) */
3351 else
3353 __terminate ();
3357 /* Then we pop the top element off the dynamic handler chain. */
3358 *dhc = (void**)(*dhc)[0];
3360 __sjthrow ();
3363 /* Support code for all exception region-based exception handling. */
3366 __eh_rtime_match (void *rtime)
3368 void *info;
3369 __eh_matcher matcher;
3370 void *ret;
3372 info = *(__get_eh_info ());
3373 matcher = ((__eh_info *)info)->match_function;
3374 if (! matcher)
3376 #ifndef inhibit_libc
3377 fprintf (stderr, "Internal Compiler Bug: No runtime type matcher.");
3378 #endif
3379 return 0;
3381 ret = (*matcher) (info, rtime, (void *)0);
3382 return (ret != NULL);
3385 /* This value identifies the place from which an exception is being
3386 thrown. */
3388 #ifdef EH_TABLE_LOOKUP
3390 EH_TABLE_LOOKUP
3392 #else
3394 #ifdef DWARF2_UNWIND_INFO
3397 /* Return the table version of an exception descriptor */
3399 short
3400 __get_eh_table_version (exception_descriptor *table)
3402 return table->lang.version;
3405 /* Return the originating table language of an exception descriptor */
3407 short
3408 __get_eh_table_language (exception_descriptor *table)
3410 return table->lang.language;
3413 /* This routine takes a PC and a pointer to the exception region TABLE for
3414 its translation unit, and returns the address of the exception handler
3415 associated with the closest exception table handler entry associated
3416 with that PC, or 0 if there are no table entries the PC fits in.
3418 In the advent of a tie, we have to give the last entry, as it represents
3419 an inner block. */
3421 static void *
3422 old_find_exception_handler (void *pc, old_exception_table *table)
3424 if (table)
3426 int pos;
3427 int best = -1;
3429 /* We can't do a binary search because the table isn't guaranteed
3430 to be sorted from function to function. */
3431 for (pos = 0; table[pos].start_region != (void *) -1; ++pos)
3433 if (table[pos].start_region <= pc && table[pos].end_region > pc)
3435 /* This can apply. Make sure it is at least as small as
3436 the previous best. */
3437 if (best == -1 || (table[pos].end_region <= table[best].end_region
3438 && table[pos].start_region >= table[best].start_region))
3439 best = pos;
3441 /* But it is sorted by starting PC within a function. */
3442 else if (best >= 0 && table[pos].start_region > pc)
3443 break;
3445 if (best != -1)
3446 return table[best].exception_handler;
3449 return (void *) 0;
3452 /* find_exception_handler finds the correct handler, if there is one, to
3453 handle an exception.
3454 returns a pointer to the handler which controlled should be transferred
3455 to, or NULL if there is nothing left.
3456 Parameters:
3457 PC - pc where the exception originates. If this is a rethrow,
3458 then this starts out as a pointer to the exception table
3459 entry we wish to rethrow out of.
3460 TABLE - exception table for the current module.
3461 EH_INFO - eh info pointer for this exception.
3462 RETHROW - 1 if this is a rethrow. (see incoming value of PC).
3463 CLEANUP - returned flag indicating whether this is a cleanup handler.
3465 static void *
3466 find_exception_handler (void *pc, exception_descriptor *table,
3467 __eh_info *eh_info, int rethrow, int *cleanup)
3470 void *retval = NULL;
3471 *cleanup = 1;
3472 if (table)
3474 int pos = 0;
3475 /* The new model assumed the table is sorted inner-most out so the
3476 first region we find which matches is the correct one */
3478 exception_table *tab = &(table->table[0]);
3480 /* Subtract 1 from the PC to avoid hitting the next region */
3481 if (rethrow)
3483 /* pc is actually the region table entry to rethrow out of */
3484 pos = ((exception_table *) pc) - tab;
3485 pc = ((exception_table *) pc)->end_region - 1;
3487 /* The label is always on the LAST handler entry for a region,
3488 so we know the next entry is a different region, even if the
3489 addresses are the same. Make sure its not end of table tho. */
3490 if (tab[pos].start_region != (void *) -1)
3491 pos++;
3493 else
3494 pc--;
3496 /* We can't do a binary search because the table is in inner-most
3497 to outermost address ranges within functions */
3498 for ( ; tab[pos].start_region != (void *) -1; pos++)
3500 if (tab[pos].start_region <= pc && tab[pos].end_region > pc)
3502 if (tab[pos].match_info)
3504 __eh_matcher matcher = eh_info->match_function;
3505 /* match info but no matcher is NOT a match */
3506 if (matcher)
3508 void *ret = (*matcher)((void *) eh_info,
3509 tab[pos].match_info, table);
3510 if (ret)
3512 if (retval == NULL)
3513 retval = tab[pos].exception_handler;
3514 *cleanup = 0;
3515 break;
3519 else
3521 if (retval == NULL)
3522 retval = tab[pos].exception_handler;
3527 return retval;
3529 #endif /* DWARF2_UNWIND_INFO */
3530 #endif /* EH_TABLE_LOOKUP */
3532 #ifdef DWARF2_UNWIND_INFO
3533 /* Support code for exception handling using static unwind information. */
3535 #include "frame.h"
3537 /* This type is used in get_reg and put_reg to deal with ABIs where a void*
3538 is smaller than a word, such as the Irix 6 n32 ABI. We cast twice to
3539 avoid a warning about casting between int and pointer of different
3540 sizes. */
3542 typedef int ptr_type __attribute__ ((mode (pointer)));
3544 #ifdef INCOMING_REGNO
3545 /* Is the saved value for register REG in frame UDATA stored in a register
3546 window in the previous frame? */
3548 /* ??? The Sparc INCOMING_REGNO references TARGET_FLAT. This allows us
3549 to use the macro here. One wonders, though, that perhaps TARGET_FLAT
3550 compiled functions won't work with the frame-unwind stuff here.
3551 Perhaps the entireity of in_reg_window should be conditional on having
3552 seen a DW_CFA_GNU_window_save? */
3553 #define target_flags 0
3555 static int
3556 in_reg_window (int reg, frame_state *udata)
3558 if (udata->saved[reg] == REG_SAVED_REG)
3559 return INCOMING_REGNO (reg) == reg;
3560 if (udata->saved[reg] != REG_SAVED_OFFSET)
3561 return 0;
3563 #ifdef STACK_GROWS_DOWNWARD
3564 return udata->reg_or_offset[reg] > 0;
3565 #else
3566 return udata->reg_or_offset[reg] < 0;
3567 #endif
3569 #else
3570 static inline int in_reg_window (int reg, frame_state *udata) { return 0; }
3571 #endif /* INCOMING_REGNO */
3573 /* Get the address of register REG as saved in UDATA, where SUB_UDATA is a
3574 frame called by UDATA or 0. */
3576 static word_type *
3577 get_reg_addr (unsigned reg, frame_state *udata, frame_state *sub_udata)
3579 while (udata->saved[reg] == REG_SAVED_REG)
3581 reg = udata->reg_or_offset[reg];
3582 if (in_reg_window (reg, udata))
3584 udata = sub_udata;
3585 sub_udata = NULL;
3588 if (udata->saved[reg] == REG_SAVED_OFFSET)
3589 return (word_type *)(udata->cfa + udata->reg_or_offset[reg]);
3590 else
3591 abort ();
3594 /* Get the value of register REG as saved in UDATA, where SUB_UDATA is a
3595 frame called by UDATA or 0. */
3597 static inline void *
3598 get_reg (unsigned reg, frame_state *udata, frame_state *sub_udata)
3600 return (void *)(ptr_type) *get_reg_addr (reg, udata, sub_udata);
3603 /* Overwrite the saved value for register REG in frame UDATA with VAL. */
3605 static inline void
3606 put_reg (unsigned reg, void *val, frame_state *udata)
3608 *get_reg_addr (reg, udata, NULL) = (word_type)(ptr_type) val;
3611 /* Copy the saved value for register REG from frame UDATA to frame
3612 TARGET_UDATA. Unlike the previous two functions, this can handle
3613 registers that are not one word large. */
3615 static void
3616 copy_reg (unsigned reg, frame_state *udata, frame_state *target_udata)
3618 word_type *preg = get_reg_addr (reg, udata, NULL);
3619 word_type *ptreg = get_reg_addr (reg, target_udata, NULL);
3621 memcpy (ptreg, preg, __builtin_dwarf_reg_size (reg));
3624 /* Retrieve the return address for frame UDATA. */
3626 static inline void *
3627 get_return_addr (frame_state *udata, frame_state *sub_udata)
3629 return __builtin_extract_return_addr
3630 (get_reg (udata->retaddr_column, udata, sub_udata));
3633 /* Overwrite the return address for frame UDATA with VAL. */
3635 static inline void
3636 put_return_addr (void *val, frame_state *udata)
3638 val = __builtin_frob_return_addr (val);
3639 put_reg (udata->retaddr_column, val, udata);
3642 /* Given the current frame UDATA and its return address PC, return the
3643 information about the calling frame in CALLER_UDATA. */
3645 static void *
3646 next_stack_level (void *pc, frame_state *udata, frame_state *caller_udata)
3648 caller_udata = __frame_state_for (pc, caller_udata);
3649 if (! caller_udata)
3650 return 0;
3652 /* Now go back to our caller's stack frame. If our caller's CFA register
3653 was saved in our stack frame, restore it; otherwise, assume the CFA
3654 register is SP and restore it to our CFA value. */
3655 if (udata->saved[caller_udata->cfa_reg])
3656 caller_udata->cfa = get_reg (caller_udata->cfa_reg, udata, 0);
3657 else
3658 caller_udata->cfa = udata->cfa;
3659 caller_udata->cfa += caller_udata->cfa_offset;
3661 return caller_udata;
3664 /* Hook to call before __terminate if only cleanup handlers remain. */
3665 void
3666 __unwinding_cleanup ()
3670 /* throw_helper performs some of the common grunt work for a throw. This
3671 routine is called by throw and rethrows. This is pretty much split
3672 out from the old __throw routine. An addition has been added which allows
3673 for a dummy call to a routine __unwinding_cleanup() when there are nothing
3674 but cleanups remaining. This allows a debugger to examine the state
3675 at which the throw was executed, before any cleanups, rather than
3676 at the terminate point after the stack has been unwound.
3678 EH is the current eh_context structure.
3679 PC is the address of the call to __throw.
3680 MY_UDATA is the unwind information for __throw.
3681 OFFSET_P is where we return the SP adjustment offset. */
3683 static void *
3684 throw_helper (eh, pc, my_udata, offset_p)
3685 struct eh_context *eh;
3686 void *pc;
3687 frame_state *my_udata;
3688 long *offset_p;
3690 frame_state ustruct2, *udata = &ustruct2;
3691 frame_state ustruct;
3692 frame_state *sub_udata = &ustruct;
3693 void *saved_pc = pc;
3694 void *handler;
3695 void *handler_p;
3696 void *pc_p;
3697 frame_state saved_ustruct;
3698 int new_eh_model;
3699 int cleanup = 0;
3700 int only_cleanup = 0;
3701 int rethrow = 0;
3702 int saved_state = 0;
3703 long args_size;
3704 __eh_info *eh_info = (__eh_info *)eh->info;
3706 /* Do we find a handler based on a re-throw PC? */
3707 if (eh->table_index != (void *) 0)
3708 rethrow = 1;
3710 memcpy (udata, my_udata, sizeof (*udata));
3712 handler = (void *) 0;
3713 for (;;)
3715 frame_state *p = udata;
3716 udata = next_stack_level (pc, udata, sub_udata);
3717 sub_udata = p;
3719 /* If we couldn't find the next frame, we lose. */
3720 if (! udata)
3721 break;
3723 if (udata->eh_ptr == NULL)
3724 new_eh_model = 0;
3725 else
3726 new_eh_model = (((exception_descriptor *)(udata->eh_ptr))->
3727 runtime_id_field == NEW_EH_RUNTIME);
3729 if (rethrow)
3731 rethrow = 0;
3732 handler = find_exception_handler (eh->table_index, udata->eh_ptr,
3733 eh_info, 1, &cleanup);
3734 eh->table_index = (void *)0;
3736 else
3737 if (new_eh_model)
3738 handler = find_exception_handler (pc, udata->eh_ptr, eh_info,
3739 0, &cleanup);
3740 else
3741 handler = old_find_exception_handler (pc, udata->eh_ptr);
3743 /* If we found one, we can stop searching, if its not a cleanup.
3744 for cleanups, we save the state, and keep looking. This allows
3745 us to call a debug hook if there are nothing but cleanups left. */
3746 if (handler)
3748 if (cleanup)
3750 if (!saved_state)
3752 saved_ustruct = *udata;
3753 handler_p = handler;
3754 pc_p = pc;
3755 saved_state = 1;
3756 only_cleanup = 1;
3759 else
3761 only_cleanup = 0;
3762 break;
3766 /* Otherwise, we continue searching. We subtract 1 from PC to avoid
3767 hitting the beginning of the next region. */
3768 pc = get_return_addr (udata, sub_udata) - 1;
3771 if (saved_state)
3773 udata = &saved_ustruct;
3774 handler = handler_p;
3775 pc = pc_p;
3776 if (only_cleanup)
3777 __unwinding_cleanup ();
3780 /* If we haven't found a handler by now, this is an unhandled
3781 exception. */
3782 if (! handler)
3783 __terminate();
3785 eh->handler_label = handler;
3787 args_size = udata->args_size;
3789 if (pc == saved_pc)
3790 /* We found a handler in the throw context, no need to unwind. */
3791 udata = my_udata;
3792 else
3794 int i;
3796 /* Unwind all the frames between this one and the handler by copying
3797 their saved register values into our register save slots. */
3799 /* Remember the PC where we found the handler. */
3800 void *handler_pc = pc;
3802 /* Start from the throw context again. */
3803 pc = saved_pc;
3804 memcpy (udata, my_udata, sizeof (*udata));
3806 while (pc != handler_pc)
3808 frame_state *p = udata;
3809 udata = next_stack_level (pc, udata, sub_udata);
3810 sub_udata = p;
3812 for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
3813 if (i != udata->retaddr_column && udata->saved[i])
3815 /* If you modify the saved value of the return address
3816 register on the SPARC, you modify the return address for
3817 your caller's frame. Don't do that here, as it will
3818 confuse get_return_addr. */
3819 if (in_reg_window (i, udata)
3820 && udata->saved[udata->retaddr_column] == REG_SAVED_REG
3821 && udata->reg_or_offset[udata->retaddr_column] == i)
3822 continue;
3823 copy_reg (i, udata, my_udata);
3826 pc = get_return_addr (udata, sub_udata) - 1;
3829 /* But we do need to update the saved return address register from
3830 the last frame we unwind, or the handler frame will have the wrong
3831 return address. */
3832 if (udata->saved[udata->retaddr_column] == REG_SAVED_REG)
3834 i = udata->reg_or_offset[udata->retaddr_column];
3835 if (in_reg_window (i, udata))
3836 copy_reg (i, udata, my_udata);
3839 /* udata now refers to the frame called by the handler frame. */
3841 /* We adjust SP by the difference between __throw's CFA and the CFA for
3842 the frame called by the handler frame, because those CFAs correspond
3843 to the SP values at the two call sites. We need to further adjust by
3844 the args_size of the handler frame itself to get the handler frame's
3845 SP from before the args were pushed for that call. */
3846 #ifdef STACK_GROWS_DOWNWARD
3847 *offset_p = udata->cfa - my_udata->cfa + args_size;
3848 #else
3849 *offset_p = my_udata->cfa - udata->cfa - args_size;
3850 #endif
3852 return handler;
3856 /* We first search for an exception handler, and if we don't find
3857 it, we call __terminate on the current stack frame so that we may
3858 use the debugger to walk the stack and understand why no handler
3859 was found.
3861 If we find one, then we unwind the frames down to the one that
3862 has the handler and transfer control into the handler. */
3864 /*extern void __throw(void) __attribute__ ((__noreturn__));*/
3866 void
3867 __throw ()
3869 struct eh_context *eh = (*get_eh_context) ();
3870 void *pc, *handler;
3871 long offset;
3873 /* XXX maybe make my_ustruct static so we don't have to look it up for
3874 each throw. */
3875 frame_state my_ustruct, *my_udata = &my_ustruct;
3877 /* This is required for C++ semantics. We must call terminate if we
3878 try and rethrow an exception, when there is no exception currently
3879 active. */
3880 if (! eh->info)
3881 __terminate ();
3883 /* Start at our stack frame. */
3884 label:
3885 my_udata = __frame_state_for (&&label, my_udata);
3886 if (! my_udata)
3887 __terminate ();
3889 /* We need to get the value from the CFA register. */
3890 my_udata->cfa = __builtin_dwarf_cfa ();
3892 /* Do any necessary initialization to access arbitrary stack frames.
3893 On the SPARC, this means flushing the register windows. */
3894 __builtin_unwind_init ();
3896 /* Now reset pc to the right throw point. */
3897 pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
3899 handler = throw_helper (eh, pc, my_udata, &offset);
3901 /* Now go! */
3903 __builtin_eh_return ((void *)eh, offset, handler);
3905 /* Epilogue: restore the handler frame's register values and return
3906 to the stub. */
3909 /*extern void __rethrow(void *) __attribute__ ((__noreturn__));*/
3911 void
3912 __rethrow (index)
3913 void *index;
3915 struct eh_context *eh = (*get_eh_context) ();
3916 void *pc, *handler;
3917 long offset;
3919 /* XXX maybe make my_ustruct static so we don't have to look it up for
3920 each throw. */
3921 frame_state my_ustruct, *my_udata = &my_ustruct;
3923 /* This is required for C++ semantics. We must call terminate if we
3924 try and rethrow an exception, when there is no exception currently
3925 active. */
3926 if (! eh->info)
3927 __terminate ();
3929 /* This is the table index we want to rethrow from. The value of
3930 the END_REGION label is used for the PC of the throw, and the
3931 search begins with the next table entry. */
3932 eh->table_index = index;
3934 /* Start at our stack frame. */
3935 label:
3936 my_udata = __frame_state_for (&&label, my_udata);
3937 if (! my_udata)
3938 __terminate ();
3940 /* We need to get the value from the CFA register. */
3941 my_udata->cfa = __builtin_dwarf_cfa ();
3943 /* Do any necessary initialization to access arbitrary stack frames.
3944 On the SPARC, this means flushing the register windows. */
3945 __builtin_unwind_init ();
3947 /* Now reset pc to the right throw point. */
3948 pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
3950 handler = throw_helper (eh, pc, my_udata, &offset);
3952 /* Now go! */
3954 __builtin_eh_return ((void *)eh, offset, handler);
3956 /* Epilogue: restore the handler frame's register values and return
3957 to the stub. */
3959 #endif /* DWARF2_UNWIND_INFO */
3961 #endif /* L_eh */
3963 #ifdef L_pure
3964 #ifndef inhibit_libc
3965 /* This gets us __GNU_LIBRARY__. */
3966 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
3967 #include <stdio.h>
3969 #ifdef __GNU_LIBRARY__
3970 /* Avoid forcing the library's meaning of `write' on the user program
3971 by using the "internal" name (for use within the library) */
3972 #define write(fd, buf, n) __write((fd), (buf), (n))
3973 #endif
3974 #endif /* inhibit_libc */
3976 #define MESSAGE "pure virtual method called\n"
3978 void
3979 __pure_virtual ()
3981 #ifndef inhibit_libc
3982 write (2, MESSAGE, sizeof (MESSAGE) - 1);
3983 #endif
3984 __terminate ();
3986 #endif