./:
[official-gcc.git] / gcc / libgcc2.c
blob7fec5cdd45edd924d3d718f056d1f8cd9b2891b9
1 /* More subroutines needed by GCC output code on some machines. */
2 /* Compile this one with gcc. */
3 /* Copyright (C) 1989, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
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"
34 #include "machmode.h"
35 #include "defaults.h"
36 #ifndef L_trampoline
37 #include <stddef.h>
38 #endif
40 /* Don't use `fancy_abort' here even if config.h says to use it. */
41 #ifdef abort
42 #undef abort
43 #endif
45 /* Permit the tm.h file to select the endianness to use just for this
46 file. This is used when the endianness is determined when the
47 compiler is run. */
49 #ifndef LIBGCC2_WORDS_BIG_ENDIAN
50 #define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
51 #endif
53 /* In the first part of this file, we are interfacing to calls generated
54 by the compiler itself. These calls pass values into these routines
55 which have very specific modes (rather than very specific types), and
56 these compiler-generated calls also expect any return values to have
57 very specific modes (rather than very specific types). Thus, we need
58 to avoid using regular C language type names in this part of the file
59 because the sizes for those types can be configured to be anything.
60 Instead we use the following special type names. */
62 typedef unsigned int UQItype __attribute__ ((mode (QI)));
63 typedef int SItype __attribute__ ((mode (SI)));
64 typedef unsigned int USItype __attribute__ ((mode (SI)));
65 typedef int DItype __attribute__ ((mode (DI)));
66 typedef unsigned int UDItype __attribute__ ((mode (DI)));
68 typedef float SFtype __attribute__ ((mode (SF)));
69 typedef float DFtype __attribute__ ((mode (DF)));
71 #if LONG_DOUBLE_TYPE_SIZE == 96
72 typedef float XFtype __attribute__ ((mode (XF)));
73 #endif
74 #if LONG_DOUBLE_TYPE_SIZE == 128
75 typedef float TFtype __attribute__ ((mode (TF)));
76 #endif
78 typedef int word_type __attribute__ ((mode (__word__)));
80 /* Make sure that we don't accidentally use any normal C language built-in
81 type names in the first part of this file. Instead we want to use *only*
82 the type names defined above. The following macro definitions insure
83 that if we *do* accidentally use some normal C language built-in type name,
84 we will get a syntax error. */
86 #define char bogus_type
87 #define short bogus_type
88 #define int bogus_type
89 #define long bogus_type
90 #define unsigned bogus_type
91 #define float bogus_type
92 #define double bogus_type
94 #define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
96 /* DIstructs are pairs of SItype values in the order determined by
97 LIBGCC2_WORDS_BIG_ENDIAN. */
99 #if LIBGCC2_WORDS_BIG_ENDIAN
100 struct DIstruct {SItype high, low;};
101 #else
102 struct DIstruct {SItype low, high;};
103 #endif
105 /* We need this union to unpack/pack DImode values, since we don't have
106 any arithmetic yet. Incoming DImode parameters are stored into the
107 `ll' field, and the unpacked result is read from the struct `s'. */
109 typedef union
111 struct DIstruct s;
112 DItype ll;
113 } DIunion;
115 #if (defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_w_sdiv)\
116 || defined (L_divdi3) || defined (L_udivdi3) \
117 || defined (L_moddi3) || defined (L_umoddi3))
119 #include "longlong.h"
121 #endif /* udiv or mul */
123 extern DItype __fixunssfdi (SFtype a);
124 extern DItype __fixunsdfdi (DFtype a);
125 #if LONG_DOUBLE_TYPE_SIZE == 96
126 extern DItype __fixunsxfdi (XFtype a);
127 #endif
128 #if LONG_DOUBLE_TYPE_SIZE == 128
129 extern DItype __fixunstfdi (TFtype a);
130 #endif
132 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
133 #if defined (L_divdi3) || defined (L_moddi3)
134 static inline
135 #endif
136 DItype
137 __negdi2 (DItype u)
139 DIunion w;
140 DIunion uu;
142 uu.ll = u;
144 w.s.low = -uu.s.low;
145 w.s.high = -uu.s.high - ((USItype) w.s.low > 0);
147 return w.ll;
149 #endif
151 /* Unless shift functions are defined whith full ANSI prototypes,
152 parameter b will be promoted to int if word_type is smaller than an int. */
153 #ifdef L_lshrdi3
154 DItype
155 __lshrdi3 (DItype u, word_type b)
157 DIunion w;
158 word_type bm;
159 DIunion uu;
161 if (b == 0)
162 return u;
164 uu.ll = u;
166 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
167 if (bm <= 0)
169 w.s.high = 0;
170 w.s.low = (USItype)uu.s.high >> -bm;
172 else
174 USItype carries = (USItype)uu.s.high << bm;
175 w.s.high = (USItype)uu.s.high >> b;
176 w.s.low = ((USItype)uu.s.low >> b) | carries;
179 return w.ll;
181 #endif
183 #ifdef L_ashldi3
184 DItype
185 __ashldi3 (DItype u, word_type b)
187 DIunion w;
188 word_type bm;
189 DIunion uu;
191 if (b == 0)
192 return u;
194 uu.ll = u;
196 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
197 if (bm <= 0)
199 w.s.low = 0;
200 w.s.high = (USItype)uu.s.low << -bm;
202 else
204 USItype carries = (USItype)uu.s.low >> bm;
205 w.s.low = (USItype)uu.s.low << b;
206 w.s.high = ((USItype)uu.s.high << b) | carries;
209 return w.ll;
211 #endif
213 #ifdef L_ashrdi3
214 DItype
215 __ashrdi3 (DItype u, word_type b)
217 DIunion w;
218 word_type bm;
219 DIunion uu;
221 if (b == 0)
222 return u;
224 uu.ll = u;
226 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
227 if (bm <= 0)
229 /* w.s.high = 1..1 or 0..0 */
230 w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
231 w.s.low = uu.s.high >> -bm;
233 else
235 USItype carries = (USItype)uu.s.high << bm;
236 w.s.high = uu.s.high >> b;
237 w.s.low = ((USItype)uu.s.low >> b) | carries;
240 return w.ll;
242 #endif
244 #ifdef L_ffsdi2
245 DItype
246 __ffsdi2 (DItype u)
248 DIunion uu, w;
249 uu.ll = u;
250 w.s.high = 0;
251 w.s.low = ffs (uu.s.low);
252 if (w.s.low != 0)
253 return w.ll;
254 w.s.low = ffs (uu.s.high);
255 if (w.s.low != 0)
257 w.s.low += BITS_PER_UNIT * sizeof (SItype);
258 return w.ll;
260 return w.ll;
262 #endif
264 #ifdef L_muldi3
265 DItype
266 __muldi3 (DItype u, DItype v)
268 DIunion w;
269 DIunion uu, vv;
271 uu.ll = u,
272 vv.ll = v;
274 w.ll = __umulsidi3 (uu.s.low, vv.s.low);
275 w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
276 + (USItype) uu.s.high * (USItype) vv.s.low);
278 return w.ll;
280 #endif
282 #ifdef L_udiv_w_sdiv
283 #if defined (sdiv_qrnnd)
284 USItype
285 __udiv_w_sdiv (USItype *rp, USItype a1, USItype a0, USItype d)
287 USItype q, r;
288 USItype c0, c1, b1;
290 if ((SItype) d >= 0)
292 if (a1 < d - a1 - (a0 >> (SI_TYPE_SIZE - 1)))
294 /* dividend, divisor, and quotient are nonnegative */
295 sdiv_qrnnd (q, r, a1, a0, d);
297 else
299 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
300 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (SI_TYPE_SIZE - 1));
301 /* Divide (c1*2^32 + c0) by d */
302 sdiv_qrnnd (q, r, c1, c0, d);
303 /* Add 2^31 to quotient */
304 q += (USItype) 1 << (SI_TYPE_SIZE - 1);
307 else
309 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
310 c1 = a1 >> 1; /* A/2 */
311 c0 = (a1 << (SI_TYPE_SIZE - 1)) + (a0 >> 1);
313 if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
315 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
317 r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
318 if ((d & 1) != 0)
320 if (r >= q)
321 r = r - q;
322 else if (q - r <= d)
324 r = r - q + d;
325 q--;
327 else
329 r = r - q + 2*d;
330 q -= 2;
334 else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
336 c1 = (b1 - 1) - c1;
337 c0 = ~c0; /* logical NOT */
339 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
341 q = ~q; /* (A/2)/b1 */
342 r = (b1 - 1) - r;
344 r = 2*r + (a0 & 1); /* A/(2*b1) */
346 if ((d & 1) != 0)
348 if (r >= q)
349 r = r - q;
350 else if (q - r <= d)
352 r = r - q + d;
353 q--;
355 else
357 r = r - q + 2*d;
358 q -= 2;
362 else /* Implies c1 = b1 */
363 { /* Hence a1 = d - 1 = 2*b1 - 1 */
364 if (a0 >= -d)
366 q = -1;
367 r = a0 + d;
369 else
371 q = -2;
372 r = a0 + 2*d;
377 *rp = r;
378 return q;
380 #else
381 /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */
382 USItype
383 __udiv_w_sdiv (USItype *rp, USItype a1, USItype a0, USItype d)
385 #endif
386 #endif
388 #if (defined (L_udivdi3) || defined (L_divdi3) || \
389 defined (L_umoddi3) || defined (L_moddi3))
390 #define L_udivmoddi4
391 #endif
393 #ifdef L_udivmoddi4
394 static const UQItype __clz_tab[] =
396 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,
397 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,
398 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,
399 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,
400 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,
401 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,
402 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,
403 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,
406 #if (defined (L_udivdi3) || defined (L_divdi3) || \
407 defined (L_umoddi3) || defined (L_moddi3))
408 static inline
409 #endif
410 UDItype
411 __udivmoddi4 (UDItype n, UDItype d, UDItype *rp)
413 DIunion ww;
414 DIunion nn, dd;
415 DIunion rr;
416 USItype d0, d1, n0, n1, n2;
417 USItype q0, q1;
418 USItype b, bm;
420 nn.ll = n;
421 dd.ll = d;
423 d0 = dd.s.low;
424 d1 = dd.s.high;
425 n0 = nn.s.low;
426 n1 = nn.s.high;
428 #if !UDIV_NEEDS_NORMALIZATION
429 if (d1 == 0)
431 if (d0 > n1)
433 /* 0q = nn / 0D */
435 udiv_qrnnd (q0, n0, n1, n0, d0);
436 q1 = 0;
438 /* Remainder in n0. */
440 else
442 /* qq = NN / 0d */
444 if (d0 == 0)
445 d0 = 1 / d0; /* Divide intentionally by zero. */
447 udiv_qrnnd (q1, n1, 0, n1, d0);
448 udiv_qrnnd (q0, n0, n1, n0, d0);
450 /* Remainder in n0. */
453 if (rp != 0)
455 rr.s.low = n0;
456 rr.s.high = 0;
457 *rp = rr.ll;
461 #else /* UDIV_NEEDS_NORMALIZATION */
463 if (d1 == 0)
465 if (d0 > n1)
467 /* 0q = nn / 0D */
469 count_leading_zeros (bm, d0);
471 if (bm != 0)
473 /* Normalize, i.e. make the most significant bit of the
474 denominator set. */
476 d0 = d0 << bm;
477 n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
478 n0 = n0 << bm;
481 udiv_qrnnd (q0, n0, n1, n0, d0);
482 q1 = 0;
484 /* Remainder in n0 >> bm. */
486 else
488 /* qq = NN / 0d */
490 if (d0 == 0)
491 d0 = 1 / d0; /* Divide intentionally by zero. */
493 count_leading_zeros (bm, d0);
495 if (bm == 0)
497 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
498 conclude (the most significant bit of n1 is set) /\ (the
499 leading quotient digit q1 = 1).
501 This special case is necessary, not an optimization.
502 (Shifts counts of SI_TYPE_SIZE are undefined.) */
504 n1 -= d0;
505 q1 = 1;
507 else
509 /* Normalize. */
511 b = SI_TYPE_SIZE - bm;
513 d0 = d0 << bm;
514 n2 = n1 >> b;
515 n1 = (n1 << bm) | (n0 >> b);
516 n0 = n0 << bm;
518 udiv_qrnnd (q1, n1, n2, n1, d0);
521 /* n1 != d0... */
523 udiv_qrnnd (q0, n0, n1, n0, d0);
525 /* Remainder in n0 >> bm. */
528 if (rp != 0)
530 rr.s.low = n0 >> bm;
531 rr.s.high = 0;
532 *rp = rr.ll;
535 #endif /* UDIV_NEEDS_NORMALIZATION */
537 else
539 if (d1 > n1)
541 /* 00 = nn / DD */
543 q0 = 0;
544 q1 = 0;
546 /* Remainder in n1n0. */
547 if (rp != 0)
549 rr.s.low = n0;
550 rr.s.high = n1;
551 *rp = rr.ll;
554 else
556 /* 0q = NN / dd */
558 count_leading_zeros (bm, d1);
559 if (bm == 0)
561 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
562 conclude (the most significant bit of n1 is set) /\ (the
563 quotient digit q0 = 0 or 1).
565 This special case is necessary, not an optimization. */
567 /* The condition on the next line takes advantage of that
568 n1 >= d1 (true due to program flow). */
569 if (n1 > d1 || n0 >= d0)
571 q0 = 1;
572 sub_ddmmss (n1, n0, n1, n0, d1, d0);
574 else
575 q0 = 0;
577 q1 = 0;
579 if (rp != 0)
581 rr.s.low = n0;
582 rr.s.high = n1;
583 *rp = rr.ll;
586 else
588 USItype m1, m0;
589 /* Normalize. */
591 b = SI_TYPE_SIZE - bm;
593 d1 = (d1 << bm) | (d0 >> b);
594 d0 = d0 << bm;
595 n2 = n1 >> b;
596 n1 = (n1 << bm) | (n0 >> b);
597 n0 = n0 << bm;
599 udiv_qrnnd (q0, n1, n2, n1, d1);
600 umul_ppmm (m1, m0, q0, d0);
602 if (m1 > n1 || (m1 == n1 && m0 > n0))
604 q0--;
605 sub_ddmmss (m1, m0, m1, m0, d1, d0);
608 q1 = 0;
610 /* Remainder in (n1n0 - m1m0) >> bm. */
611 if (rp != 0)
613 sub_ddmmss (n1, n0, n1, n0, m1, m0);
614 rr.s.low = (n1 << b) | (n0 >> bm);
615 rr.s.high = n1 >> bm;
616 *rp = rr.ll;
622 ww.s.low = q0;
623 ww.s.high = q1;
624 return ww.ll;
626 #endif
628 #ifdef L_divdi3
629 UDItype __udivmoddi4 ();
631 DItype
632 __divdi3 (DItype u, DItype v)
634 word_type c = 0;
635 DIunion uu, vv;
636 DItype w;
638 uu.ll = u;
639 vv.ll = v;
641 if (uu.s.high < 0)
642 c = ~c,
643 uu.ll = __negdi2 (uu.ll);
644 if (vv.s.high < 0)
645 c = ~c,
646 vv.ll = __negdi2 (vv.ll);
648 w = __udivmoddi4 (uu.ll, vv.ll, (UDItype *) 0);
649 if (c)
650 w = __negdi2 (w);
652 return w;
654 #endif
656 #ifdef L_moddi3
657 UDItype __udivmoddi4 ();
658 DItype
659 __moddi3 (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 vv.ll = __negdi2 (vv.ll);
674 (void) __udivmoddi4 (uu.ll, vv.ll, &w);
675 if (c)
676 w = __negdi2 (w);
678 return w;
680 #endif
682 #ifdef L_umoddi3
683 UDItype __udivmoddi4 ();
684 UDItype
685 __umoddi3 (UDItype u, UDItype v)
687 UDItype w;
689 (void) __udivmoddi4 (u, v, &w);
691 return w;
693 #endif
695 #ifdef L_udivdi3
696 UDItype __udivmoddi4 ();
697 UDItype
698 __udivdi3 (UDItype n, UDItype d)
700 return __udivmoddi4 (n, d, (UDItype *) 0);
702 #endif
704 #ifdef L_cmpdi2
705 word_type
706 __cmpdi2 (DItype a, DItype b)
708 DIunion au, bu;
710 au.ll = a, bu.ll = b;
712 if (au.s.high < bu.s.high)
713 return 0;
714 else if (au.s.high > bu.s.high)
715 return 2;
716 if ((USItype) au.s.low < (USItype) bu.s.low)
717 return 0;
718 else if ((USItype) au.s.low > (USItype) bu.s.low)
719 return 2;
720 return 1;
722 #endif
724 #ifdef L_ucmpdi2
725 word_type
726 __ucmpdi2 (DItype a, DItype b)
728 DIunion au, bu;
730 au.ll = a, bu.ll = b;
732 if ((USItype) au.s.high < (USItype) bu.s.high)
733 return 0;
734 else if ((USItype) au.s.high > (USItype) bu.s.high)
735 return 2;
736 if ((USItype) au.s.low < (USItype) bu.s.low)
737 return 0;
738 else if ((USItype) au.s.low > (USItype) bu.s.low)
739 return 2;
740 return 1;
742 #endif
744 #if defined(L_fixunstfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
745 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
746 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
748 DItype
749 __fixunstfdi (TFtype a)
751 TFtype b;
752 UDItype v;
754 if (a < 0)
755 return 0;
757 /* Compute high word of result, as a flonum. */
758 b = (a / HIGH_WORD_COEFF);
759 /* Convert that to fixed (but not to DItype!),
760 and shift it into the high word. */
761 v = (USItype) b;
762 v <<= WORD_SIZE;
763 /* Remove high part from the TFtype, leaving the low part as flonum. */
764 a -= (TFtype)v;
765 /* Convert that to fixed (but not to DItype!) and add it in.
766 Sometimes A comes out negative. This is significant, since
767 A has more bits than a long int does. */
768 if (a < 0)
769 v -= (USItype) (- a);
770 else
771 v += (USItype) a;
772 return v;
774 #endif
776 #if defined(L_fixtfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
777 DItype
778 __fixtfdi (TFtype a)
780 if (a < 0)
781 return - __fixunstfdi (-a);
782 return __fixunstfdi (a);
784 #endif
786 #if defined(L_fixunsxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
787 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
788 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
790 DItype
791 __fixunsxfdi (XFtype a)
793 XFtype b;
794 UDItype v;
796 if (a < 0)
797 return 0;
799 /* Compute high word of result, as a flonum. */
800 b = (a / HIGH_WORD_COEFF);
801 /* Convert that to fixed (but not to DItype!),
802 and shift it into the high word. */
803 v = (USItype) b;
804 v <<= WORD_SIZE;
805 /* Remove high part from the XFtype, leaving the low part as flonum. */
806 a -= (XFtype)v;
807 /* Convert that to fixed (but not to DItype!) and add it in.
808 Sometimes A comes out negative. This is significant, since
809 A has more bits than a long int does. */
810 if (a < 0)
811 v -= (USItype) (- a);
812 else
813 v += (USItype) a;
814 return v;
816 #endif
818 #if defined(L_fixxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
819 DItype
820 __fixxfdi (XFtype a)
822 if (a < 0)
823 return - __fixunsxfdi (-a);
824 return __fixunsxfdi (a);
826 #endif
828 #ifdef L_fixunsdfdi
829 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
830 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
832 DItype
833 __fixunsdfdi (DFtype a)
835 DFtype b;
836 UDItype v;
838 if (a < 0)
839 return 0;
841 /* Compute high word of result, as a flonum. */
842 b = (a / HIGH_WORD_COEFF);
843 /* Convert that to fixed (but not to DItype!),
844 and shift it into the high word. */
845 v = (USItype) b;
846 v <<= WORD_SIZE;
847 /* Remove high part from the DFtype, leaving the low part as flonum. */
848 a -= (DFtype)v;
849 /* Convert that to fixed (but not to DItype!) and add it in.
850 Sometimes A comes out negative. This is significant, since
851 A has more bits than a long int does. */
852 if (a < 0)
853 v -= (USItype) (- a);
854 else
855 v += (USItype) a;
856 return v;
858 #endif
860 #ifdef L_fixdfdi
861 DItype
862 __fixdfdi (DFtype a)
864 if (a < 0)
865 return - __fixunsdfdi (-a);
866 return __fixunsdfdi (a);
868 #endif
870 #ifdef L_fixunssfdi
871 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
872 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
874 DItype
875 __fixunssfdi (SFtype original_a)
877 /* Convert the SFtype to a DFtype, because that is surely not going
878 to lose any bits. Some day someone else can write a faster version
879 that avoids converting to DFtype, and verify it really works right. */
880 DFtype a = original_a;
881 DFtype b;
882 UDItype v;
884 if (a < 0)
885 return 0;
887 /* Compute high word of result, as a flonum. */
888 b = (a / HIGH_WORD_COEFF);
889 /* Convert that to fixed (but not to DItype!),
890 and shift it into the high word. */
891 v = (USItype) b;
892 v <<= WORD_SIZE;
893 /* Remove high part from the DFtype, leaving the low part as flonum. */
894 a -= (DFtype)v;
895 /* Convert that to fixed (but not to DItype!) and add it in.
896 Sometimes A comes out negative. This is significant, since
897 A has more bits than a long int does. */
898 if (a < 0)
899 v -= (USItype) (- a);
900 else
901 v += (USItype) a;
902 return v;
904 #endif
906 #ifdef L_fixsfdi
907 DItype
908 __fixsfdi (SFtype a)
910 if (a < 0)
911 return - __fixunssfdi (-a);
912 return __fixunssfdi (a);
914 #endif
916 #if defined(L_floatdixf) && (LONG_DOUBLE_TYPE_SIZE == 96)
917 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
918 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
919 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
921 XFtype
922 __floatdixf (DItype u)
924 XFtype d;
925 SItype negate = 0;
927 if (u < 0)
928 u = -u, negate = 1;
930 d = (USItype) (u >> WORD_SIZE);
931 d *= HIGH_HALFWORD_COEFF;
932 d *= HIGH_HALFWORD_COEFF;
933 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
935 return (negate ? -d : d);
937 #endif
939 #if defined(L_floatditf) && (LONG_DOUBLE_TYPE_SIZE == 128)
940 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
941 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
942 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
944 TFtype
945 __floatditf (DItype u)
947 TFtype d;
948 SItype negate = 0;
950 if (u < 0)
951 u = -u, negate = 1;
953 d = (USItype) (u >> WORD_SIZE);
954 d *= HIGH_HALFWORD_COEFF;
955 d *= HIGH_HALFWORD_COEFF;
956 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
958 return (negate ? -d : d);
960 #endif
962 #ifdef L_floatdidf
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 DFtype
968 __floatdidf (DItype u)
970 DFtype d;
971 SItype negate = 0;
973 if (u < 0)
974 u = -u, negate = 1;
976 d = (USItype) (u >> WORD_SIZE);
977 d *= HIGH_HALFWORD_COEFF;
978 d *= HIGH_HALFWORD_COEFF;
979 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
981 return (negate ? -d : d);
983 #endif
985 #ifdef L_floatdisf
986 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
987 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
988 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
989 #define DI_SIZE (sizeof (DItype) * BITS_PER_UNIT)
991 /* Define codes for all the float formats that we know of. Note
992 that this is copied from real.h. */
994 #define UNKNOWN_FLOAT_FORMAT 0
995 #define IEEE_FLOAT_FORMAT 1
996 #define VAX_FLOAT_FORMAT 2
997 #define IBM_FLOAT_FORMAT 3
999 /* Default to IEEE float if not specified. Nearly all machines use it. */
1000 #ifndef HOST_FLOAT_FORMAT
1001 #define HOST_FLOAT_FORMAT IEEE_FLOAT_FORMAT
1002 #endif
1004 #if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1005 #define DF_SIZE 53
1006 #define SF_SIZE 24
1007 #endif
1009 #if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
1010 #define DF_SIZE 56
1011 #define SF_SIZE 24
1012 #endif
1014 #if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
1015 #define DF_SIZE 56
1016 #define SF_SIZE 24
1017 #endif
1019 SFtype
1020 __floatdisf (DItype u)
1022 /* Do the calculation in DFmode
1023 so that we don't lose any of the precision of the high word
1024 while multiplying it. */
1025 DFtype f;
1026 SItype negate = 0;
1028 if (u < 0)
1029 u = -u, negate = 1;
1031 /* Protect against double-rounding error.
1032 Represent any low-order bits, that might be truncated in DFmode,
1033 by a bit that won't be lost. The bit can go in anywhere below the
1034 rounding position of the SFmode. A fixed mask and bit position
1035 handles all usual configurations. It doesn't handle the case
1036 of 128-bit DImode, however. */
1037 if (DF_SIZE < DI_SIZE
1038 && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1040 #define REP_BIT ((USItype) 1 << (DI_SIZE - DF_SIZE))
1041 if (u >= ((UDItype) 1 << DF_SIZE))
1043 if ((USItype) u & (REP_BIT - 1))
1044 u |= REP_BIT;
1047 f = (USItype) (u >> WORD_SIZE);
1048 f *= HIGH_HALFWORD_COEFF;
1049 f *= HIGH_HALFWORD_COEFF;
1050 f += (USItype) (u & (HIGH_WORD_COEFF - 1));
1052 return (SFtype) (negate ? -f : f);
1054 #endif
1056 #if defined(L_fixunsxfsi) && LONG_DOUBLE_TYPE_SIZE == 96
1057 /* Reenable the normal types, in case limits.h needs them. */
1058 #undef char
1059 #undef short
1060 #undef int
1061 #undef long
1062 #undef unsigned
1063 #undef float
1064 #undef double
1065 #undef MIN
1066 #undef MAX
1067 #include <limits.h>
1069 USItype
1070 __fixunsxfsi (XFtype a)
1072 if (a >= - (DFtype) LONG_MIN)
1073 return (SItype) (a + LONG_MIN) - LONG_MIN;
1074 return (SItype) a;
1076 #endif
1078 #ifdef L_fixunsdfsi
1079 /* Reenable the normal types, in case limits.h needs them. */
1080 #undef char
1081 #undef short
1082 #undef int
1083 #undef long
1084 #undef unsigned
1085 #undef float
1086 #undef double
1087 #undef MIN
1088 #undef MAX
1089 #include <limits.h>
1091 USItype
1092 __fixunsdfsi (DFtype a)
1094 if (a >= - (DFtype) LONG_MIN)
1095 return (SItype) (a + LONG_MIN) - LONG_MIN;
1096 return (SItype) a;
1098 #endif
1100 #ifdef L_fixunssfsi
1101 /* Reenable the normal types, in case limits.h needs them. */
1102 #undef char
1103 #undef short
1104 #undef int
1105 #undef long
1106 #undef unsigned
1107 #undef float
1108 #undef double
1109 #undef MIN
1110 #undef MAX
1111 #include <limits.h>
1113 USItype
1114 __fixunssfsi (SFtype a)
1116 if (a >= - (SFtype) LONG_MIN)
1117 return (SItype) (a + LONG_MIN) - LONG_MIN;
1118 return (SItype) a;
1120 #endif
1122 /* From here on down, the routines use normal data types. */
1124 #define SItype bogus_type
1125 #define USItype bogus_type
1126 #define DItype bogus_type
1127 #define UDItype bogus_type
1128 #define SFtype bogus_type
1129 #define DFtype bogus_type
1131 #undef char
1132 #undef short
1133 #undef int
1134 #undef long
1135 #undef unsigned
1136 #undef float
1137 #undef double
1139 #ifdef L__gcc_bcmp
1141 /* Like bcmp except the sign is meaningful.
1142 Result is negative if S1 is less than S2,
1143 positive if S1 is greater, 0 if S1 and S2 are equal. */
1146 __gcc_bcmp (unsigned char *s1, unsigned char *s2, size_t size)
1148 while (size > 0)
1150 unsigned char c1 = *s1++, c2 = *s2++;
1151 if (c1 != c2)
1152 return c1 - c2;
1153 size--;
1155 return 0;
1158 #endif
1159 \f\f
1160 #ifdef L__dummy
1161 void
1162 __dummy () {}
1163 #endif
1165 #ifdef L_varargs
1166 #ifdef __i860__
1167 #if defined(__svr4__) || defined(__alliant__)
1168 asm (" .text");
1169 asm (" .align 4");
1171 /* The Alliant needs the added underscore. */
1172 asm (".globl __builtin_saveregs");
1173 asm ("__builtin_saveregs:");
1174 asm (".globl ___builtin_saveregs");
1175 asm ("___builtin_saveregs:");
1177 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
1178 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
1179 area and also for a new va_list
1180 structure */
1181 /* Save all argument registers in the arg reg save area. The
1182 arg reg save area must have the following layout (according
1183 to the svr4 ABI):
1185 struct {
1186 union {
1187 float freg[8];
1188 double dreg[4];
1189 } float_regs;
1190 long ireg[12];
1194 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
1195 asm (" fst.q %f12,16(%sp)");
1197 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
1198 asm (" st.l %r17,36(%sp)");
1199 asm (" st.l %r18,40(%sp)");
1200 asm (" st.l %r19,44(%sp)");
1201 asm (" st.l %r20,48(%sp)");
1202 asm (" st.l %r21,52(%sp)");
1203 asm (" st.l %r22,56(%sp)");
1204 asm (" st.l %r23,60(%sp)");
1205 asm (" st.l %r24,64(%sp)");
1206 asm (" st.l %r25,68(%sp)");
1207 asm (" st.l %r26,72(%sp)");
1208 asm (" st.l %r27,76(%sp)");
1210 asm (" adds 80,%sp,%r16"); /* compute the address of the new
1211 va_list structure. Put in into
1212 r16 so that it will be returned
1213 to the caller. */
1215 /* Initialize all fields of the new va_list structure. This
1216 structure looks like:
1218 typedef struct {
1219 unsigned long ireg_used;
1220 unsigned long freg_used;
1221 long *reg_base;
1222 long *mem_ptr;
1223 } va_list;
1226 asm (" st.l %r0, 0(%r16)"); /* nfixed */
1227 asm (" st.l %r0, 4(%r16)"); /* nfloating */
1228 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
1229 asm (" bri %r1"); /* delayed return */
1230 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
1232 #else /* not __svr4__ */
1233 #if defined(__PARAGON__)
1235 * we'll use SVR4-ish varargs but need SVR3.2 assembler syntax,
1236 * and we stand a better chance of hooking into libraries
1237 * compiled by PGI. [andyp@ssd.intel.com]
1239 asm (" .text");
1240 asm (" .align 4");
1241 asm (".globl __builtin_saveregs");
1242 asm ("__builtin_saveregs:");
1243 asm (".globl ___builtin_saveregs");
1244 asm ("___builtin_saveregs:");
1246 asm (" andnot 0x0f,sp,sp"); /* round down to 16-byte boundary */
1247 asm (" adds -96,sp,sp"); /* allocate stack space for reg save
1248 area and also for a new va_list
1249 structure */
1250 /* Save all argument registers in the arg reg save area. The
1251 arg reg save area must have the following layout (according
1252 to the svr4 ABI):
1254 struct {
1255 union {
1256 float freg[8];
1257 double dreg[4];
1258 } float_regs;
1259 long ireg[12];
1263 asm (" fst.q f8, 0(sp)");
1264 asm (" fst.q f12,16(sp)");
1265 asm (" st.l r16,32(sp)");
1266 asm (" st.l r17,36(sp)");
1267 asm (" st.l r18,40(sp)");
1268 asm (" st.l r19,44(sp)");
1269 asm (" st.l r20,48(sp)");
1270 asm (" st.l r21,52(sp)");
1271 asm (" st.l r22,56(sp)");
1272 asm (" st.l r23,60(sp)");
1273 asm (" st.l r24,64(sp)");
1274 asm (" st.l r25,68(sp)");
1275 asm (" st.l r26,72(sp)");
1276 asm (" st.l r27,76(sp)");
1278 asm (" adds 80,sp,r16"); /* compute the address of the new
1279 va_list structure. Put in into
1280 r16 so that it will be returned
1281 to the caller. */
1283 /* Initialize all fields of the new va_list structure. This
1284 structure looks like:
1286 typedef struct {
1287 unsigned long ireg_used;
1288 unsigned long freg_used;
1289 long *reg_base;
1290 long *mem_ptr;
1291 } va_list;
1294 asm (" st.l r0, 0(r16)"); /* nfixed */
1295 asm (" st.l r0, 4(r16)"); /* nfloating */
1296 asm (" st.l sp, 8(r16)"); /* __va_ctl points to __va_struct. */
1297 asm (" bri r1"); /* delayed return */
1298 asm (" st.l r28,12(r16)"); /* pointer to overflow args */
1299 #else /* not __PARAGON__ */
1300 asm (" .text");
1301 asm (" .align 4");
1303 asm (".globl ___builtin_saveregs");
1304 asm ("___builtin_saveregs:");
1305 asm (" mov sp,r30");
1306 asm (" andnot 0x0f,sp,sp");
1307 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
1309 /* Fill in the __va_struct. */
1310 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
1311 asm (" st.l r17, 4(sp)"); /* int fixed[12] */
1312 asm (" st.l r18, 8(sp)");
1313 asm (" st.l r19,12(sp)");
1314 asm (" st.l r20,16(sp)");
1315 asm (" st.l r21,20(sp)");
1316 asm (" st.l r22,24(sp)");
1317 asm (" st.l r23,28(sp)");
1318 asm (" st.l r24,32(sp)");
1319 asm (" st.l r25,36(sp)");
1320 asm (" st.l r26,40(sp)");
1321 asm (" st.l r27,44(sp)");
1323 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
1324 asm (" fst.q f12,64(sp)"); /* int floating[8] */
1326 /* Fill in the __va_ctl. */
1327 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
1328 asm (" st.l r28,84(sp)"); /* pointer to more args */
1329 asm (" st.l r0, 88(sp)"); /* nfixed */
1330 asm (" st.l r0, 92(sp)"); /* nfloating */
1332 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
1333 asm (" bri r1");
1334 asm (" mov r30,sp");
1335 /* recover stack and pass address to start
1336 of data. */
1337 #endif /* not __PARAGON__ */
1338 #endif /* not __svr4__ */
1339 #else /* not __i860__ */
1340 #ifdef __sparc__
1341 asm (".global __builtin_saveregs");
1342 asm ("__builtin_saveregs:");
1343 asm (".global ___builtin_saveregs");
1344 asm ("___builtin_saveregs:");
1345 #ifdef NEED_PROC_COMMAND
1346 asm (".proc 020");
1347 #endif
1348 asm ("st %i0,[%fp+68]");
1349 asm ("st %i1,[%fp+72]");
1350 asm ("st %i2,[%fp+76]");
1351 asm ("st %i3,[%fp+80]");
1352 asm ("st %i4,[%fp+84]");
1353 asm ("retl");
1354 asm ("st %i5,[%fp+88]");
1355 #ifdef NEED_TYPE_COMMAND
1356 asm (".type __builtin_saveregs,#function");
1357 asm (".size __builtin_saveregs,.-__builtin_saveregs");
1358 #endif
1359 #else /* not __sparc__ */
1360 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1362 asm (" .text");
1363 asm (" .ent __builtin_saveregs");
1364 asm (" .globl __builtin_saveregs");
1365 asm ("__builtin_saveregs:");
1366 asm (" sw $4,0($30)");
1367 asm (" sw $5,4($30)");
1368 asm (" sw $6,8($30)");
1369 asm (" sw $7,12($30)");
1370 asm (" j $31");
1371 asm (" .end __builtin_saveregs");
1372 #else /* not __mips__, etc. */
1374 void *
1375 __builtin_saveregs ()
1377 abort ();
1380 #endif /* not __mips__ */
1381 #endif /* not __sparc__ */
1382 #endif /* not __i860__ */
1383 #endif
1385 #ifdef L_eprintf
1386 #ifndef inhibit_libc
1388 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1389 #include <stdio.h>
1390 /* This is used by the `assert' macro. */
1391 void
1392 __eprintf (const char *string, const char *expression,
1393 int line, const char *filename)
1395 fprintf (stderr, string, expression, line, filename);
1396 fflush (stderr);
1397 abort ();
1400 #endif
1401 #endif
1403 #ifdef L_bb
1405 /* Structure emitted by -a */
1406 struct bb
1408 long zero_word;
1409 const char *filename;
1410 long *counts;
1411 long ncounts;
1412 struct bb *next;
1413 const unsigned long *addresses;
1415 /* Older GCC's did not emit these fields. */
1416 long nwords;
1417 const char **functions;
1418 const long *line_nums;
1419 const char **filenames;
1420 char *flags;
1423 #ifdef BLOCK_PROFILER_CODE
1424 BLOCK_PROFILER_CODE
1425 #else
1426 #ifndef inhibit_libc
1428 /* Simple minded basic block profiling output dumper for
1429 systems that don't provide tcov support. At present,
1430 it requires atexit and stdio. */
1432 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1433 #include <stdio.h>
1434 char *ctime ();
1436 #include "gbl-ctors.h"
1437 #include "gcov-io.h"
1439 static struct bb *bb_head;
1441 /* Return the number of digits needed to print a value */
1442 /* __inline__ */ static int num_digits (long value, int base)
1444 int minus = (value < 0 && base != 16);
1445 unsigned long v = (minus) ? -value : value;
1446 int ret = minus;
1450 v /= base;
1451 ret++;
1453 while (v);
1455 return ret;
1458 void
1459 __bb_exit_func (void)
1461 FILE *da_file, *file;
1462 long time_value;
1463 int i;
1465 if (bb_head == 0)
1466 return;
1468 i = strlen (bb_head->filename) - 3;
1470 if (!strcmp (bb_head->filename+i, ".da"))
1472 /* Must be -fprofile-arcs not -a.
1473 Dump data in a form that gcov expects. */
1475 struct bb *ptr;
1477 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1479 /* If the file exists, and the number of counts in it is the same,
1480 then merge them in. */
1482 if ((da_file = fopen (ptr->filename, "r")) != 0)
1484 long n_counts = 0;
1485 unsigned char tmp;
1486 int i;
1487 int ret = 0;
1490 if (__read_long (&n_counts, da_file, 8) != 0)
1492 fprintf (stderr, "arc profiling: Can't read output file %s.\n",
1493 ptr->filename);
1494 continue;
1497 if (n_counts == ptr->ncounts)
1499 int i;
1501 for (i = 0; i < n_counts; i++)
1503 long v = 0;
1504 unsigned char tmp;
1505 int j;
1506 int ret = 0;
1508 if (__read_long (&v, da_file, 8) != 0)
1510 fprintf (stderr, "arc profiling: Can't read output file %s.\n",
1511 ptr->filename);
1512 break;
1514 ptr->counts[i] += v;
1518 if (fclose (da_file) == EOF)
1519 fprintf (stderr, "arc profiling: Error closing output file %s.\n",
1520 ptr->filename);
1522 if ((da_file = fopen (ptr->filename, "w")) < 0)
1524 fprintf (stderr, "arc profiling: Can't open output file %s.\n",
1525 ptr->filename);
1526 continue;
1529 /* ??? Should first write a header to the file. Perferably, a 4 byte
1530 magic number, 4 bytes containing the time the program was
1531 compiled, 4 bytes containing the last modification time of the
1532 source file, and 4 bytes indicating the compiler options used.
1534 That way we can easily verify that the proper source/executable/
1535 data file combination is being used from gcov. */
1537 if (__write_long (ptr->ncounts, da_file, 8) != 0)
1540 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1541 ptr->filename);
1543 else
1545 int j;
1546 long *count_ptr = ptr->counts;
1547 int ret = 0;
1548 for (j = ptr->ncounts; j > 0; j--)
1550 if (__write_long (*count_ptr, da_file, 8) != 0)
1552 ret=1;
1553 break;
1555 count_ptr++;
1557 if (ret)
1558 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1559 ptr->filename);
1562 if (fclose (da_file) == EOF)
1563 fprintf (stderr, "arc profiling: Error closing output file %s.\n",
1564 ptr->filename);
1567 return;
1570 /* Must be basic block profiling. Emit a human readable output file. */
1572 file = fopen ("bb.out", "a");
1574 if (!file)
1575 perror ("bb.out");
1577 else
1579 struct bb *ptr;
1581 /* This is somewhat type incorrect, but it avoids worrying about
1582 exactly where time.h is included from. It should be ok unless
1583 a void * differs from other pointer formats, or if sizeof (long)
1584 is < sizeof (time_t). It would be nice if we could assume the
1585 use of rationale standards here. */
1587 time ((void *) &time_value);
1588 fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value));
1590 /* We check the length field explicitly in order to allow compatibility
1591 with older GCC's which did not provide it. */
1593 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1595 int i;
1596 int func_p = (ptr->nwords >= sizeof (struct bb)
1597 && ptr->nwords <= 1000
1598 && ptr->functions);
1599 int line_p = (func_p && ptr->line_nums);
1600 int file_p = (func_p && ptr->filenames);
1601 int addr_p = (ptr->addresses != 0);
1602 long ncounts = ptr->ncounts;
1603 long cnt_max = 0;
1604 long line_max = 0;
1605 long addr_max = 0;
1606 int file_len = 0;
1607 int func_len = 0;
1608 int blk_len = num_digits (ncounts, 10);
1609 int cnt_len;
1610 int line_len;
1611 int addr_len;
1613 fprintf (file, "File %s, %ld basic blocks \n\n",
1614 ptr->filename, ncounts);
1616 /* Get max values for each field. */
1617 for (i = 0; i < ncounts; i++)
1619 const char *p;
1620 int len;
1622 if (cnt_max < ptr->counts[i])
1623 cnt_max = ptr->counts[i];
1625 if (addr_p && addr_max < ptr->addresses[i])
1626 addr_max = ptr->addresses[i];
1628 if (line_p && line_max < ptr->line_nums[i])
1629 line_max = ptr->line_nums[i];
1631 if (func_p)
1633 p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>";
1634 len = strlen (p);
1635 if (func_len < len)
1636 func_len = len;
1639 if (file_p)
1641 p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>";
1642 len = strlen (p);
1643 if (file_len < len)
1644 file_len = len;
1648 addr_len = num_digits (addr_max, 16);
1649 cnt_len = num_digits (cnt_max, 10);
1650 line_len = num_digits (line_max, 10);
1652 /* Now print out the basic block information. */
1653 for (i = 0; i < ncounts; i++)
1655 fprintf (file,
1656 " Block #%*d: executed %*ld time(s)",
1657 blk_len, i+1,
1658 cnt_len, ptr->counts[i]);
1660 if (addr_p)
1661 fprintf (file, " address= 0x%.*lx", addr_len,
1662 ptr->addresses[i]);
1664 if (func_p)
1665 fprintf (file, " function= %-*s", func_len,
1666 (ptr->functions[i]) ? ptr->functions[i] : "<none>");
1668 if (line_p)
1669 fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]);
1671 if (file_p)
1672 fprintf (file, " file= %s",
1673 (ptr->filenames[i]) ? ptr->filenames[i] : "<none>");
1675 fprintf (file, "\n");
1678 fprintf (file, "\n");
1679 fflush (file);
1682 fprintf (file, "\n\n");
1683 fclose (file);
1687 void
1688 __bb_init_func (struct bb *blocks)
1690 /* User is supposed to check whether the first word is non-0,
1691 but just in case.... */
1693 if (blocks->zero_word)
1694 return;
1696 #ifdef ON_EXIT
1697 /* Initialize destructor. */
1698 if (!bb_head)
1699 ON_EXIT (__bb_exit_func, 0);
1700 #endif
1702 /* Set up linked list. */
1703 blocks->zero_word = 1;
1704 blocks->next = bb_head;
1705 bb_head = blocks;
1708 #ifndef MACHINE_STATE_SAVE
1709 #define MACHINE_STATE_SAVE(ID)
1710 #endif
1711 #ifndef MACHINE_STATE_RESTORE
1712 #define MACHINE_STATE_RESTORE(ID)
1713 #endif
1715 #include <string.h>
1717 /* Number of buckets in hashtable of basic block addresses. */
1719 #define BB_BUCKETS 311
1721 /* Maximum length of string in file bb.in. */
1723 #define BBINBUFSIZE 500
1725 /* BBINBUFSIZE-1 with double quotes. We could use #BBINBUFSIZE or
1726 "BBINBUFSIZE" but want to avoid trouble with preprocessors. */
1728 #define BBINBUFSIZESTR "499"
1730 struct bb_edge
1732 struct bb_edge *next;
1733 unsigned long src_addr;
1734 unsigned long dst_addr;
1735 unsigned long count;
1738 enum bb_func_mode
1740 TRACE_KEEP = 0, TRACE_ON = 1, TRACE_OFF = 2
1743 struct bb_func
1745 struct bb_func *next;
1746 char *funcname;
1747 char *filename;
1748 enum bb_func_mode mode;
1751 /* This is the connection to the outside world.
1752 The BLOCK_PROFILER macro must set __bb.blocks
1753 and __bb.blockno. */
1755 struct {
1756 unsigned long blockno;
1757 struct bb *blocks;
1758 } __bb;
1760 /* Vars to store addrs of source and destination basic blocks
1761 of a jump. */
1763 static unsigned long bb_src = 0;
1764 static unsigned long bb_dst = 0;
1766 static FILE *bb_tracefile = (FILE *) 0;
1767 static struct bb_edge **bb_hashbuckets = (struct bb_edge **) 0;
1768 static struct bb_func *bb_func_head = (struct bb_func *) 0;
1769 static unsigned long bb_callcount = 0;
1770 static int bb_mode = 0;
1772 static unsigned long *bb_stack = (unsigned long *) 0;
1773 static size_t bb_stacksize = 0;
1775 static int reported = 0;
1777 /* Trace modes:
1778 Always : Print execution frequencies of basic blocks
1779 to file bb.out.
1780 bb_mode & 1 != 0 : Dump trace of basic blocks to file bbtrace[.gz]
1781 bb_mode & 2 != 0 : Print jump frequencies to file bb.out.
1782 bb_mode & 4 != 0 : Cut call instructions from basic block flow.
1783 bb_mode & 8 != 0 : Insert return instructions in basic block flow.
1786 #ifdef HAVE_POPEN
1788 /*#include <sys/types.h>*/
1789 #include <sys/stat.h>
1790 /*#include <malloc.h>*/
1792 /* Commands executed by gopen. */
1794 #define GOPENDECOMPRESS "gzip -cd "
1795 #define GOPENCOMPRESS "gzip -c >"
1797 /* Like fopen but pipes through gzip. mode may only be "r" or "w".
1798 If it does not compile, simply replace gopen by fopen and delete
1799 '.gz' from any first parameter to gopen. */
1801 static FILE *
1802 gopen (char *fn, char *mode)
1804 int use_gzip;
1805 char *p;
1807 if (mode[1])
1808 return (FILE *) 0;
1810 if (mode[0] != 'r' && mode[0] != 'w')
1811 return (FILE *) 0;
1813 p = fn + strlen (fn)-1;
1814 use_gzip = ((p[-1] == '.' && (p[0] == 'Z' || p[0] == 'z'))
1815 || (p[-2] == '.' && p[-1] == 'g' && p[0] == 'z'));
1817 if (use_gzip)
1819 if (mode[0]=='r')
1821 FILE *f;
1822 char *s = (char *) malloc (sizeof (char) * strlen (fn)
1823 + sizeof (GOPENDECOMPRESS));
1824 strcpy (s, GOPENDECOMPRESS);
1825 strcpy (s + (sizeof (GOPENDECOMPRESS)-1), fn);
1826 f = popen (s, mode);
1827 free (s);
1828 return f;
1831 else
1833 FILE *f;
1834 char *s = (char *) malloc (sizeof (char) * strlen (fn)
1835 + sizeof (GOPENCOMPRESS));
1836 strcpy (s, GOPENCOMPRESS);
1837 strcpy (s + (sizeof (GOPENCOMPRESS)-1), fn);
1838 if (!(f = popen (s, mode)))
1839 f = fopen (s, mode);
1840 free (s);
1841 return f;
1845 else
1846 return fopen (fn, mode);
1849 static int
1850 gclose (FILE *f)
1852 struct stat buf;
1854 if (f != 0)
1856 if (!fstat (fileno (f), &buf) && S_ISFIFO (buf.st_mode))
1857 return pclose (f);
1859 return fclose (f);
1861 return 0;
1864 #endif /* HAVE_POPEN */
1866 /* Called once per program. */
1868 static void
1869 __bb_exit_trace_func ()
1871 FILE *file = fopen ("bb.out", "a");
1872 struct bb_func *f;
1873 struct bb_edge *e;
1874 struct bb *b;
1876 if (!file)
1877 perror ("bb.out");
1879 if (bb_mode & 1)
1881 if (!bb_tracefile)
1882 perror ("bbtrace");
1883 else
1884 #ifdef HAVE_POPEN
1885 gclose (bb_tracefile);
1886 #else
1887 fclose (bb_tracefile);
1888 #endif /* HAVE_POPEN */
1891 /* Check functions in `bb.in'. */
1893 if (file)
1895 long time_value;
1896 const struct bb_func *p;
1897 int printed_something = 0;
1898 struct bb *ptr;
1899 long blk;
1901 /* This is somewhat type incorrect. */
1902 time ((void *) &time_value);
1904 for (p = bb_func_head; p != (struct bb_func *) 0; p = p->next)
1906 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1908 if (!ptr->filename || p->filename != (char *) 0 && strcmp (p->filename, ptr->filename))
1909 continue;
1910 for (blk = 0; blk < ptr->ncounts; blk++)
1912 if (!strcmp (p->funcname, ptr->functions[blk]))
1913 goto found;
1917 if (!printed_something)
1919 fprintf (file, "Functions in `bb.in' not executed during basic block profiling on %s\n", ctime ((void *) &time_value));
1920 printed_something = 1;
1923 fprintf (file, "\tFunction %s", p->funcname);
1924 if (p->filename)
1925 fprintf (file, " of file %s", p->filename);
1926 fprintf (file, "\n" );
1928 found: ;
1931 if (printed_something)
1932 fprintf (file, "\n");
1936 if (bb_mode & 2)
1938 if (!bb_hashbuckets)
1940 if (!reported)
1942 fprintf (stderr, "Profiler: out of memory\n");
1943 reported = 1;
1945 return;
1948 else if (file)
1950 long time_value;
1951 int i;
1952 unsigned long addr_max = 0;
1953 unsigned long cnt_max = 0;
1954 int cnt_len;
1955 int addr_len;
1957 /* This is somewhat type incorrect, but it avoids worrying about
1958 exactly where time.h is included from. It should be ok unless
1959 a void * differs from other pointer formats, or if sizeof (long)
1960 is < sizeof (time_t). It would be nice if we could assume the
1961 use of rationale standards here. */
1963 time ((void *) &time_value);
1964 fprintf (file, "Basic block jump tracing");
1966 switch (bb_mode & 12)
1968 case 0:
1969 fprintf (file, " (with call)");
1970 break;
1972 case 4:
1973 /* Print nothing. */
1974 break;
1976 case 8:
1977 fprintf (file, " (with call & ret)");
1978 break;
1980 case 12:
1981 fprintf (file, " (with ret)");
1982 break;
1985 fprintf (file, " finished on %s\n", ctime ((void *) &time_value));
1987 for (i = 0; i < BB_BUCKETS; i++)
1989 struct bb_edge *bucket = bb_hashbuckets[i];
1990 for ( ; bucket; bucket = bucket->next )
1992 if (addr_max < bucket->src_addr)
1993 addr_max = bucket->src_addr;
1994 if (addr_max < bucket->dst_addr)
1995 addr_max = bucket->dst_addr;
1996 if (cnt_max < bucket->count)
1997 cnt_max = bucket->count;
2000 addr_len = num_digits (addr_max, 16);
2001 cnt_len = num_digits (cnt_max, 10);
2003 for ( i = 0; i < BB_BUCKETS; i++)
2005 struct bb_edge *bucket = bb_hashbuckets[i];
2006 for ( ; bucket; bucket = bucket->next )
2008 fprintf (file, "Jump from block 0x%.*lx to "
2009 "block 0x%.*lx executed %*d time(s)\n",
2010 addr_len, bucket->src_addr,
2011 addr_len, bucket->dst_addr,
2012 cnt_len, bucket->count);
2016 fprintf (file, "\n");
2021 if (file)
2022 fclose (file);
2024 /* Free allocated memory. */
2026 f = bb_func_head;
2027 while (f)
2029 struct bb_func *old = f;
2031 f = f->next;
2032 if (old->funcname) free (old->funcname);
2033 if (old->filename) free (old->filename);
2034 free (old);
2037 if (bb_stack)
2038 free (bb_stack);
2040 if (bb_hashbuckets)
2042 int i;
2044 for (i = 0; i < BB_BUCKETS; i++)
2046 struct bb_edge *old, *bucket = bb_hashbuckets[i];
2048 while (bucket)
2050 old = bucket;
2051 bucket = bucket->next;
2052 free (old);
2055 free (bb_hashbuckets);
2058 for (b = bb_head; b; b = b->next)
2059 if (b->flags) free (b->flags);
2062 /* Called once per program. */
2064 static void
2065 __bb_init_prg ()
2068 FILE *file;
2069 char buf[BBINBUFSIZE];
2070 const char *p;
2071 const char *pos;
2072 enum bb_func_mode m;
2074 #ifdef ON_EXIT
2075 /* Initialize destructor. */
2076 ON_EXIT (__bb_exit_func, 0);
2077 #endif
2079 if (!(file = fopen ("bb.in", "r")))
2080 return;
2082 while(fscanf (file, " %" BBINBUFSIZESTR "s ", buf) != EOF)
2084 p = buf;
2085 if (*p == '-')
2087 m = TRACE_OFF;
2088 p++;
2090 else
2092 m = TRACE_ON;
2094 if (!strcmp (p, "__bb_trace__"))
2095 bb_mode |= 1;
2096 else if (!strcmp (p, "__bb_jumps__"))
2097 bb_mode |= 2;
2098 else if (!strcmp (p, "__bb_hidecall__"))
2099 bb_mode |= 4;
2100 else if (!strcmp (p, "__bb_showret__"))
2101 bb_mode |= 8;
2102 else
2104 struct bb_func *f = (struct bb_func *) malloc (sizeof (struct bb_func));
2105 if (f)
2107 unsigned long l;
2108 f->next = bb_func_head;
2109 if (pos = strchr (p, ':'))
2111 if (!(f->funcname = (char *) malloc (strlen (pos+1)+1)))
2112 continue;
2113 strcpy (f->funcname, pos+1);
2114 l = pos-p;
2115 if ((f->filename = (char *) malloc (l+1)))
2117 strncpy (f->filename, p, l);
2118 f->filename[l] = '\0';
2120 else
2121 f->filename = (char *) 0;
2123 else
2125 if (!(f->funcname = (char *) malloc (strlen (p)+1)))
2126 continue;
2127 strcpy (f->funcname, p);
2128 f->filename = (char *) 0;
2130 f->mode = m;
2131 bb_func_head = f;
2135 fclose (file);
2137 #ifdef HAVE_POPEN
2139 if (bb_mode & 1)
2140 bb_tracefile = gopen ("bbtrace.gz", "w");
2142 #else
2144 if (bb_mode & 1)
2145 bb_tracefile = fopen ("bbtrace", "w");
2147 #endif /* HAVE_POPEN */
2149 if (bb_mode & 2)
2151 bb_hashbuckets = (struct bb_edge **)
2152 malloc (BB_BUCKETS * sizeof (struct bb_edge *));
2153 if (bb_hashbuckets)
2154 bzero ((char *) bb_hashbuckets, BB_BUCKETS);
2157 if (bb_mode & 12)
2159 bb_stacksize = 10;
2160 bb_stack = (unsigned long *) malloc (bb_stacksize * sizeof (*bb_stack));
2163 #ifdef ON_EXIT
2164 /* Initialize destructor. */
2165 ON_EXIT (__bb_exit_trace_func, 0);
2166 #endif
2170 /* Called upon entering a basic block. */
2172 void
2173 __bb_trace_func ()
2175 struct bb_edge *bucket;
2177 MACHINE_STATE_SAVE("1")
2179 if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2180 goto skip;
2182 bb_dst = __bb.blocks->addresses[__bb.blockno];
2183 __bb.blocks->counts[__bb.blockno]++;
2185 if (bb_tracefile)
2187 fwrite (&bb_dst, sizeof (unsigned long), 1, bb_tracefile);
2190 if (bb_hashbuckets)
2192 struct bb_edge **startbucket, **oldnext;
2194 oldnext = startbucket
2195 = & bb_hashbuckets[ (((int) bb_src*8) ^ (int) bb_dst) % BB_BUCKETS ];
2196 bucket = *startbucket;
2198 for (bucket = *startbucket; bucket;
2199 oldnext = &(bucket->next), bucket = *oldnext)
2201 if (bucket->src_addr == bb_src
2202 && bucket->dst_addr == bb_dst)
2204 bucket->count++;
2205 *oldnext = bucket->next;
2206 bucket->next = *startbucket;
2207 *startbucket = bucket;
2208 goto ret;
2212 bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2214 if (!bucket)
2216 if (!reported)
2218 fprintf (stderr, "Profiler: out of memory\n");
2219 reported = 1;
2223 else
2225 bucket->src_addr = bb_src;
2226 bucket->dst_addr = bb_dst;
2227 bucket->next = *startbucket;
2228 *startbucket = bucket;
2229 bucket->count = 1;
2233 ret:
2234 bb_src = bb_dst;
2236 skip:
2239 MACHINE_STATE_RESTORE("1")
2243 /* Called when returning from a function and `__bb_showret__' is set. */
2245 static void
2246 __bb_trace_func_ret ()
2248 struct bb_edge *bucket;
2250 if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2251 goto skip;
2253 if (bb_hashbuckets)
2255 struct bb_edge **startbucket, **oldnext;
2257 oldnext = startbucket
2258 = & bb_hashbuckets[ (((int) bb_dst * 8) ^ (int) bb_src) % BB_BUCKETS ];
2259 bucket = *startbucket;
2261 for (bucket = *startbucket; bucket;
2262 oldnext = &(bucket->next), bucket = *oldnext)
2264 if (bucket->src_addr == bb_dst
2265 && bucket->dst_addr == bb_src)
2267 bucket->count++;
2268 *oldnext = bucket->next;
2269 bucket->next = *startbucket;
2270 *startbucket = bucket;
2271 goto ret;
2275 bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2277 if (!bucket)
2279 if (!reported)
2281 fprintf (stderr, "Profiler: out of memory\n");
2282 reported = 1;
2286 else
2288 bucket->src_addr = bb_dst;
2289 bucket->dst_addr = bb_src;
2290 bucket->next = *startbucket;
2291 *startbucket = bucket;
2292 bucket->count = 1;
2296 ret:
2297 bb_dst = bb_src;
2299 skip:
2304 /* Called upon entering the first function of a file. */
2306 static void
2307 __bb_init_file (struct bb *blocks)
2310 const struct bb_func *p;
2311 long blk, ncounts = blocks->ncounts;
2312 const char **functions = blocks->functions;
2314 /* Set up linked list. */
2315 blocks->zero_word = 1;
2316 blocks->next = bb_head;
2317 bb_head = blocks;
2319 blocks->flags = 0;
2320 if (!bb_func_head
2321 || !(blocks->flags = (char *) malloc (sizeof (char) * blocks->ncounts)))
2322 return;
2324 for (blk = 0; blk < ncounts; blk++)
2325 blocks->flags[blk] = 0;
2327 for (blk = 0; blk < ncounts; blk++)
2329 for (p = bb_func_head; p; p = p->next)
2331 if (!strcmp (p->funcname, functions[blk])
2332 && (!p->filename || !strcmp (p->filename, blocks->filename)))
2334 blocks->flags[blk] |= p->mode;
2341 /* Called when exiting from a function. */
2343 void
2344 __bb_trace_ret ()
2347 MACHINE_STATE_SAVE("2")
2349 if (bb_callcount)
2351 if ((bb_mode & 12) && bb_stacksize > bb_callcount)
2353 bb_src = bb_stack[bb_callcount];
2354 if (bb_mode & 8)
2355 __bb_trace_func_ret ();
2358 bb_callcount -= 1;
2361 MACHINE_STATE_RESTORE("2")
2365 /* Called when entering a function. */
2367 void
2368 __bb_init_trace_func (struct bb *blocks, unsigned long blockno)
2370 static int trace_init = 0;
2372 MACHINE_STATE_SAVE("3")
2374 if (!blocks->zero_word)
2376 if (!trace_init)
2378 trace_init = 1;
2379 __bb_init_prg ();
2381 __bb_init_file (blocks);
2384 if (bb_callcount)
2387 bb_callcount += 1;
2389 if (bb_mode & 12)
2391 if (bb_callcount >= bb_stacksize)
2393 size_t newsize = bb_callcount + 100;
2395 bb_stack = (unsigned long *) realloc (bb_stack, newsize);
2396 if (! bb_stack)
2398 if (!reported)
2400 fprintf (stderr, "Profiler: out of memory\n");
2401 reported = 1;
2403 bb_stacksize = 0;
2404 goto stack_overflow;
2406 bb_stacksize = newsize;
2408 bb_stack[bb_callcount] = bb_src;
2410 if (bb_mode & 4)
2411 bb_src = 0;
2415 stack_overflow:;
2419 else if (blocks->flags && (blocks->flags[blockno] & TRACE_ON))
2421 bb_callcount = 1;
2422 bb_src = 0;
2424 if (bb_stack)
2425 bb_stack[bb_callcount] = bb_src;
2428 MACHINE_STATE_RESTORE("3")
2431 #endif /* not inhibit_libc */
2432 #endif /* not BLOCK_PROFILER_CODE */
2433 #endif /* L_bb */
2435 #ifdef L_shtab
2436 unsigned int __shtab[] = {
2437 0x00000001, 0x00000002, 0x00000004, 0x00000008,
2438 0x00000010, 0x00000020, 0x00000040, 0x00000080,
2439 0x00000100, 0x00000200, 0x00000400, 0x00000800,
2440 0x00001000, 0x00002000, 0x00004000, 0x00008000,
2441 0x00010000, 0x00020000, 0x00040000, 0x00080000,
2442 0x00100000, 0x00200000, 0x00400000, 0x00800000,
2443 0x01000000, 0x02000000, 0x04000000, 0x08000000,
2444 0x10000000, 0x20000000, 0x40000000, 0x80000000
2446 #endif
2448 #ifdef L_clear_cache
2449 /* Clear part of an instruction cache. */
2451 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
2453 void
2454 __clear_cache (char *beg, char *end)
2456 #ifdef CLEAR_INSN_CACHE
2457 CLEAR_INSN_CACHE (beg, end);
2458 #else
2459 #ifdef INSN_CACHE_SIZE
2460 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
2461 static int initialized;
2462 int offset;
2463 void *start_addr
2464 void *end_addr;
2465 typedef (*function_ptr) ();
2467 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
2468 /* It's cheaper to clear the whole cache.
2469 Put in a series of jump instructions so that calling the beginning
2470 of the cache will clear the whole thing. */
2472 if (! initialized)
2474 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2475 & -INSN_CACHE_LINE_WIDTH);
2476 int end_ptr = ptr + INSN_CACHE_SIZE;
2478 while (ptr < end_ptr)
2480 *(INSTRUCTION_TYPE *)ptr
2481 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
2482 ptr += INSN_CACHE_LINE_WIDTH;
2484 *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
2486 initialized = 1;
2489 /* Call the beginning of the sequence. */
2490 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2491 & -INSN_CACHE_LINE_WIDTH))
2492 ());
2494 #else /* Cache is large. */
2496 if (! initialized)
2498 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2499 & -INSN_CACHE_LINE_WIDTH);
2501 while (ptr < (int) array + sizeof array)
2503 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
2504 ptr += INSN_CACHE_LINE_WIDTH;
2507 initialized = 1;
2510 /* Find the location in array that occupies the same cache line as BEG. */
2512 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
2513 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
2514 & -INSN_CACHE_PLANE_SIZE)
2515 + offset);
2517 /* Compute the cache alignment of the place to stop clearing. */
2518 #if 0 /* This is not needed for gcc's purposes. */
2519 /* If the block to clear is bigger than a cache plane,
2520 we clear the entire cache, and OFFSET is already correct. */
2521 if (end < beg + INSN_CACHE_PLANE_SIZE)
2522 #endif
2523 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
2524 & -INSN_CACHE_LINE_WIDTH)
2525 & (INSN_CACHE_PLANE_SIZE - 1));
2527 #if INSN_CACHE_DEPTH > 1
2528 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
2529 if (end_addr <= start_addr)
2530 end_addr += INSN_CACHE_PLANE_SIZE;
2532 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
2534 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
2535 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
2537 while (addr != stop)
2539 /* Call the return instruction at ADDR. */
2540 ((function_ptr) addr) ();
2542 addr += INSN_CACHE_LINE_WIDTH;
2545 #else /* just one plane */
2548 /* Call the return instruction at START_ADDR. */
2549 ((function_ptr) start_addr) ();
2551 start_addr += INSN_CACHE_LINE_WIDTH;
2553 while ((start_addr % INSN_CACHE_SIZE) != offset);
2554 #endif /* just one plane */
2555 #endif /* Cache is large */
2556 #endif /* Cache exists */
2557 #endif /* CLEAR_INSN_CACHE */
2560 #endif /* L_clear_cache */
2562 #ifdef L_trampoline
2564 /* Jump to a trampoline, loading the static chain address. */
2566 #if defined(WINNT) && ! defined(__CYGWIN32__)
2568 long getpagesize()
2570 #ifdef _ALPHA_
2571 return 8192;
2572 #else
2573 return 4096;
2574 #endif
2577 #ifdef i386
2578 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
2579 #endif
2582 mprotect (char *addr, int len, int prot)
2584 int np, op;
2586 if (prot == 7)
2587 np = 0x40;
2588 else if (prot == 5)
2589 np = 0x20;
2590 else if (prot == 4)
2591 np = 0x10;
2592 else if (prot == 3)
2593 np = 0x04;
2594 else if (prot == 1)
2595 np = 0x02;
2596 else if (prot == 0)
2597 np = 0x01;
2599 if (VirtualProtect (addr, len, np, &op))
2600 return 0;
2601 else
2602 return -1;
2605 #endif
2607 #ifdef TRANSFER_FROM_TRAMPOLINE
2608 TRANSFER_FROM_TRAMPOLINE
2609 #endif
2611 #if defined (NeXT) && defined (__MACH__)
2613 /* Make stack executable so we can call trampolines on stack.
2614 This is called from INITIALIZE_TRAMPOLINE in next.h. */
2615 #ifdef NeXTStep21
2616 #include <mach.h>
2617 #else
2618 #include <mach/mach.h>
2619 #endif
2621 void
2622 __enable_execute_stack (char *addr)
2624 kern_return_t r;
2625 char *eaddr = addr + TRAMPOLINE_SIZE;
2626 vm_address_t a = (vm_address_t) addr;
2628 /* turn on execute access on stack */
2629 r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
2630 if (r != KERN_SUCCESS)
2632 mach_error("vm_protect VM_PROT_ALL", r);
2633 exit(1);
2636 /* We inline the i-cache invalidation for speed */
2638 #ifdef CLEAR_INSN_CACHE
2639 CLEAR_INSN_CACHE (addr, eaddr);
2640 #else
2641 __clear_cache ((int) addr, (int) eaddr);
2642 #endif
2645 #endif /* defined (NeXT) && defined (__MACH__) */
2647 #ifdef __convex__
2649 /* Make stack executable so we can call trampolines on stack.
2650 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
2652 #include <sys/mman.h>
2653 #include <sys/vmparam.h>
2654 #include <machine/machparam.h>
2656 void
2657 __enable_execute_stack ()
2659 int fp;
2660 static unsigned lowest = USRSTACK;
2661 unsigned current = (unsigned) &fp & -NBPG;
2663 if (lowest > current)
2665 unsigned len = lowest - current;
2666 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
2667 lowest = current;
2670 /* Clear instruction cache in case an old trampoline is in it. */
2671 asm ("pich");
2673 #endif /* __convex__ */
2675 #ifdef __sysV88__
2677 /* Modified from the convex -code above. */
2679 #include <sys/param.h>
2680 #include <errno.h>
2681 #include <sys/m88kbcs.h>
2683 void
2684 __enable_execute_stack ()
2686 int save_errno;
2687 static unsigned long lowest = USRSTACK;
2688 unsigned long current = (unsigned long) &save_errno & -NBPC;
2690 /* Ignore errno being set. memctl sets errno to EINVAL whenever the
2691 address is seen as 'negative'. That is the case with the stack. */
2693 save_errno=errno;
2694 if (lowest > current)
2696 unsigned len=lowest-current;
2697 memctl(current,len,MCT_TEXT);
2698 lowest = current;
2700 else
2701 memctl(current,NBPC,MCT_TEXT);
2702 errno=save_errno;
2705 #endif /* __sysV88__ */
2707 #ifdef __pyr__
2709 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2710 #include <stdio.h>
2711 #include <sys/mman.h>
2712 #include <sys/types.h>
2713 #include <sys/param.h>
2714 #include <sys/vmmac.h>
2716 /* Modified from the convex -code above.
2717 mremap promises to clear the i-cache. */
2719 void
2720 __enable_execute_stack ()
2722 int fp;
2723 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
2724 PROT_READ|PROT_WRITE|PROT_EXEC))
2726 perror ("mprotect in __enable_execute_stack");
2727 fflush (stderr);
2728 abort ();
2731 #endif /* __pyr__ */
2733 #if defined (sony_news) && defined (SYSTYPE_BSD)
2735 #include <stdio.h>
2736 #include <sys/types.h>
2737 #include <sys/param.h>
2738 #include <syscall.h>
2739 #include <machine/sysnews.h>
2741 /* cacheflush function for NEWS-OS 4.2.
2742 This function is called from trampoline-initialize code
2743 defined in config/mips/mips.h. */
2745 void
2746 cacheflush (char *beg, int size, int flag)
2748 if (syscall (SYS_sysnews, NEWS_CACHEFLUSH, beg, size, FLUSH_BCACHE))
2750 perror ("cache_flush");
2751 fflush (stderr);
2752 abort ();
2756 #endif /* sony_news */
2757 #endif /* L_trampoline */
2759 #ifdef L__main
2761 #include "gbl-ctors.h"
2762 /* Some systems use __main in a way incompatible with its use in gcc, in these
2763 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2764 give the same symbol without quotes for an alternative entry point. You
2765 must define both, or neither. */
2766 #ifndef NAME__MAIN
2767 #define NAME__MAIN "__main"
2768 #define SYMBOL__MAIN __main
2769 #endif
2771 #ifdef INIT_SECTION_ASM_OP
2772 #undef HAS_INIT_SECTION
2773 #define HAS_INIT_SECTION
2774 #endif
2776 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
2777 /* Run all the global destructors on exit from the program. */
2779 void
2780 __do_global_dtors ()
2782 #ifdef DO_GLOBAL_DTORS_BODY
2783 DO_GLOBAL_DTORS_BODY;
2784 #else
2785 static func_ptr *p = __DTOR_LIST__ + 1;
2786 while (*p)
2788 p++;
2789 (*(p-1)) ();
2791 #endif
2793 #endif
2795 #ifndef HAS_INIT_SECTION
2796 /* Run all the global constructors on entry to the program. */
2798 #ifndef ON_EXIT
2799 #define ON_EXIT(a, b)
2800 #else
2801 /* Make sure the exit routine is pulled in to define the globals as
2802 bss symbols, just in case the linker does not automatically pull
2803 bss definitions from the library. */
2805 extern int _exit_dummy_decl;
2806 int *_exit_dummy_ref = &_exit_dummy_decl;
2807 #endif /* ON_EXIT */
2809 void
2810 __do_global_ctors ()
2812 DO_GLOBAL_CTORS_BODY;
2813 ON_EXIT (__do_global_dtors, 0);
2815 #endif /* no HAS_INIT_SECTION */
2817 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
2818 /* Subroutine called automatically by `main'.
2819 Compiling a global function named `main'
2820 produces an automatic call to this function at the beginning.
2822 For many systems, this routine calls __do_global_ctors.
2823 For systems which support a .init section we use the .init section
2824 to run __do_global_ctors, so we need not do anything here. */
2826 void
2827 SYMBOL__MAIN ()
2829 /* Support recursive calls to `main': run initializers just once. */
2830 static int initialized;
2831 if (! initialized)
2833 initialized = 1;
2834 __do_global_ctors ();
2837 #endif /* no HAS_INIT_SECTION or INVOKE__main */
2839 #endif /* L__main */
2841 #ifdef L_ctors
2843 #include "gbl-ctors.h"
2845 /* Provide default definitions for the lists of constructors and
2846 destructors, so that we don't get linker errors. These symbols are
2847 intentionally bss symbols, so that gld and/or collect will provide
2848 the right values. */
2850 /* We declare the lists here with two elements each,
2851 so that they are valid empty lists if no other definition is loaded. */
2852 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
2853 #if defined(__NeXT__) || defined(_AIX)
2854 /* After 2.3, try this definition on all systems. */
2855 func_ptr __CTOR_LIST__[2] = {0, 0};
2856 func_ptr __DTOR_LIST__[2] = {0, 0};
2857 #else
2858 func_ptr __CTOR_LIST__[2];
2859 func_ptr __DTOR_LIST__[2];
2860 #endif
2861 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
2862 #endif /* L_ctors */
2864 #ifdef L_exit
2866 #include "gbl-ctors.h"
2868 #ifdef NEED_ATEXIT
2869 # ifdef ON_EXIT
2870 # undef ON_EXIT
2871 # endif
2872 int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */
2873 #endif
2875 #ifndef ON_EXIT
2877 #ifdef NEED_ATEXIT
2878 # include <errno.h>
2880 static func_ptr *atexit_chain = 0;
2881 static long atexit_chain_length = 0;
2882 static volatile long last_atexit_chain_slot = -1;
2884 int atexit (func_ptr func)
2886 if (++last_atexit_chain_slot == atexit_chain_length)
2888 atexit_chain_length += 32;
2889 if (atexit_chain)
2890 atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
2891 * sizeof (func_ptr));
2892 else
2893 atexit_chain = (func_ptr *) malloc (atexit_chain_length
2894 * sizeof (func_ptr));
2895 if (! atexit_chain)
2897 atexit_chain_length = 0;
2898 last_atexit_chain_slot = -1;
2899 errno = ENOMEM;
2900 return (-1);
2903 atexit_chain[last_atexit_chain_slot] = func;
2904 return (0);
2906 #endif /* NEED_ATEXIT */
2908 /* If we have no known way of registering our own __do_global_dtors
2909 routine so that it will be invoked at program exit time, then we
2910 have to define our own exit routine which will get this to happen. */
2912 extern void __do_global_dtors ();
2913 extern void __bb_exit_func ();
2914 extern void _cleanup ();
2915 extern void _exit () __attribute__ ((noreturn));
2917 void
2918 exit (int status)
2920 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2921 #ifdef NEED_ATEXIT
2922 if (atexit_chain)
2924 for ( ; last_atexit_chain_slot-- >= 0; )
2926 (*atexit_chain[last_atexit_chain_slot + 1]) ();
2927 atexit_chain[last_atexit_chain_slot + 1] = 0;
2929 free (atexit_chain);
2930 atexit_chain = 0;
2932 #else /* No NEED_ATEXIT */
2933 __do_global_dtors ();
2934 #endif /* No NEED_ATEXIT */
2935 #endif
2936 #ifndef inhibit_libc
2937 __bb_exit_func ();
2938 #endif
2939 #ifdef EXIT_BODY
2940 EXIT_BODY;
2941 #else
2942 _cleanup ();
2943 #endif
2944 _exit (status);
2947 #else
2948 int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */
2949 #endif
2951 #endif /* L_exit */
2953 #ifdef L_eh
2955 /* Shared exception handling support routines. */
2957 /* Language-specific information about the active exception(s). If there
2958 are no active exceptions, it is set to 0. */
2959 void *__eh_info;
2961 void
2962 __default_terminate ()
2964 abort ();
2967 void (*__terminate_func)() = __default_terminate;
2969 void
2970 __terminate ()
2972 (*__terminate_func)();
2975 void *
2976 __throw_type_match (void *catch_type, void *throw_type, void *obj)
2978 #if 0
2979 printf ("__throw_type_match (): catch_type = %s, throw_type = %s\n",
2980 catch_type, throw_type);
2981 #endif
2982 if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)
2983 return obj;
2984 return 0;
2987 void
2988 __empty ()
2992 /* Support routines for setjmp/longjmp exception handling. */
2994 /* Calls to __sjthrow are generated by the compiler when an exception
2995 is raised when using the setjmp/longjmp exception handling codegen
2996 method. */
2998 extern void longjmp (void *, int);
3000 static void *top_elt[2];
3001 void **__dynamic_handler_chain = top_elt;
3003 /* Routine to get the head of the current thread's dynamic handler chain
3004 use for exception handling.
3006 TODO: make thread safe. */
3008 void ***
3009 __get_dynamic_handler_chain ()
3011 return &__dynamic_handler_chain;
3014 /* This is used to throw an exception when the setjmp/longjmp codegen
3015 method is used for exception handling.
3017 We call __terminate if there are no handlers left (we know this
3018 when the dynamic handler chain is top_elt). Otherwise we run the
3019 cleanup actions off the dynamic cleanup stack, and pop the top of
3020 the dynamic handler chain, and use longjmp to transfer back to the
3021 associated handler. */
3023 void
3024 __sjthrow ()
3026 void ***dhc = __get_dynamic_handler_chain ();
3027 void *jmpbuf;
3028 void (*func)(void *, int);
3029 void *arg;
3030 void ***cleanup;
3032 /* The cleanup chain is one word into the buffer. Get the cleanup
3033 chain. */
3034 cleanup = (void***)&(*dhc)[1];
3036 /* If there are any cleanups in the chain, run them now. */
3037 if (cleanup[0])
3039 double store[200];
3040 void **buf = (void**)store;
3041 buf[1] = 0;
3042 buf[0] = (*dhc);
3044 /* try { */
3045 #ifdef DONT_USE_BUILTIN_SETJMP
3046 if (! setjmp (&buf[2]))
3047 #else
3048 if (! __builtin_setjmp (&buf[2]))
3049 #endif
3051 *dhc = buf;
3052 while (cleanup[0])
3054 func = (void(*)(void*, int))cleanup[0][1];
3055 arg = (void*)cleanup[0][2];
3057 /* Update this before running the cleanup. */
3058 cleanup[0] = (void **)cleanup[0][0];
3060 (*func)(arg, 2);
3062 *dhc = buf[0];
3064 /* catch (...) */
3065 else
3067 __terminate ();
3071 /* We must call terminate if we try and rethrow an exception, when
3072 there is no exception currently active and when there are no
3073 handlers left. */
3074 if (! __eh_info || (*dhc) == top_elt)
3075 __terminate ();
3077 /* Find the jmpbuf associated with the top element of the dynamic
3078 handler chain. The jumpbuf starts two words into the buffer. */
3079 jmpbuf = &(*dhc)[2];
3081 /* Then we pop the top element off the dynamic handler chain. */
3082 *dhc = (void**)(*dhc)[0];
3084 /* And then we jump to the handler. */
3086 #ifdef DONT_USE_BUILTIN_SETJMP
3087 longjmp (jmpbuf, 1);
3088 #else
3089 __builtin_longjmp (jmpbuf, 1);
3090 #endif
3093 /* Run cleanups on the dynamic cleanup stack for the current dynamic
3094 handler, then pop the handler off the dynamic handler stack, and
3095 then throw. This is used to skip the first handler, and transfer
3096 control to the next handler in the dynamic handler stack. */
3098 void
3099 __sjpopnthrow ()
3101 void ***dhc = __get_dynamic_handler_chain ();
3102 void *jmpbuf;
3103 void (*func)(void *, int);
3104 void *arg;
3105 void ***cleanup;
3107 /* The cleanup chain is one word into the buffer. Get the cleanup
3108 chain. */
3109 cleanup = (void***)&(*dhc)[1];
3111 /* If there are any cleanups in the chain, run them now. */
3112 if (cleanup[0])
3114 double store[200];
3115 void **buf = (void**)store;
3116 buf[1] = 0;
3117 buf[0] = (*dhc);
3119 /* try { */
3120 #ifdef DONT_USE_BUILTIN_SETJMP
3121 if (! setjmp (&buf[2]))
3122 #else
3123 if (! __builtin_setjmp (&buf[2]))
3124 #endif
3126 *dhc = buf;
3127 while (cleanup[0])
3129 func = (void(*)(void*, int))cleanup[0][1];
3130 arg = (void*)cleanup[0][2];
3132 /* Update this before running the cleanup. */
3133 cleanup[0] = (void **)cleanup[0][0];
3135 (*func)(arg, 2);
3137 *dhc = buf[0];
3139 /* catch (...) */
3140 else
3142 __terminate ();
3146 /* Then we pop the top element off the dynamic handler chain. */
3147 *dhc = (void**)(*dhc)[0];
3149 __sjthrow ();
3152 /* Support code for all exception region-based exception handling. */
3154 /* This value identifies the place from which an exception is being
3155 thrown. */
3157 void *__eh_pc;
3159 #ifdef EH_TABLE_LOOKUP
3161 EH_TABLE_LOOKUP
3163 #else
3165 typedef struct exception_table {
3166 void *start;
3167 void *end;
3168 void *exception_handler;
3169 } exception_table;
3171 /* This routine takes a PC and a pointer to the exception region TABLE for
3172 its translation unit, and returns the address of the exception handler
3173 associated with the closest exception table handler entry associated
3174 with that PC, or 0 if there are no table entries the PC fits in.
3176 In the advent of a tie, we have to give the last entry, as it represents
3177 an inner block. */
3179 static void *
3180 find_exception_handler (void *pc, exception_table *table)
3182 if (table)
3184 int pos;
3185 int best = -1;
3187 /* We can't do a binary search because the table isn't guaranteed
3188 to be sorted from function to function. */
3189 for (pos = 0; table[pos].exception_handler != (void *) -1; ++pos)
3191 if (table[pos].start <= pc && table[pos].end > pc)
3193 /* This can apply. Make sure it is at least as small as
3194 the previous best. */
3195 if (best == -1 || (table[pos].end <= table[best].end
3196 && table[pos].start >= table[best].start))
3197 best = pos;
3199 /* But it is sorted by starting PC within a function. */
3200 else if (best >= 0 && table[pos].start > pc)
3201 break;
3203 if (best != -1)
3204 return table[best].exception_handler;
3207 return (void *) 0;
3209 #endif /* EH_TABLE_LOOKUP */
3211 #ifndef DWARF2_UNWIND_INFO
3212 /* Support code for exception handling using inline unwinders or
3213 __unwind_function. */
3215 #ifndef EH_TABLE_LOOKUP
3216 typedef struct exception_table_node {
3217 exception_table *table;
3218 void *start;
3219 void *end;
3220 struct exception_table_node *next;
3221 } exception_table_node;
3223 static struct exception_table_node *exception_table_list;
3225 void *
3226 __find_first_exception_table_match (void *pc)
3228 register exception_table_node *tnp;
3230 for (tnp = exception_table_list; tnp != 0; tnp = tnp->next)
3232 if (tnp->start <= pc && tnp->end >= pc)
3233 return find_exception_handler (pc, tnp->table);
3236 return (void *) 0;
3239 void
3240 __register_exceptions (exception_table *table)
3242 exception_table_node *node;
3243 exception_table *range = table + 1;
3245 if (range->start == (void *) -1)
3246 return;
3248 node = (exception_table_node *) malloc (sizeof (exception_table_node));
3249 node->table = table;
3251 /* This look can be optimized away either if the table
3252 is sorted, or if we pass in extra parameters. */
3253 node->start = range->start;
3254 node->end = range->end;
3255 for (range++ ; range->start != (void *) (-1); range++)
3257 if (range->start < node->start)
3258 node->start = range->start;
3259 if (range->end > node->end)
3260 node->end = range->end;
3263 node->next = exception_table_list;
3264 exception_table_list = node;
3266 #endif /* !EH_TABLE_LOOKUP */
3268 /* Throw stub routine.
3270 This is work in progress, but not completed yet. */
3272 void
3273 __throw ()
3275 abort ();
3278 /* See expand_builtin_throw for details. */
3280 void **__eh_pcnthrow () {
3281 static void *buf[2] = {
3282 &__eh_pc,
3283 &__throw
3285 return buf;
3288 #if #machine(i386)
3289 void
3290 __unwind_function(void *ptr)
3292 asm("movl 8(%esp),%ecx");
3293 /* Undo current frame */
3294 asm("movl %ebp,%esp");
3295 asm("popl %ebp");
3296 /* like ret, but stay here */
3297 asm("addl $4,%esp");
3299 /* Now, undo previous frame. */
3300 /* This is a test routine, as we have to dynamically probe to find out
3301 what to pop for certain, this is just a guess. */
3302 asm("leal -16(%ebp),%esp");
3303 asm("pop %ebx");
3304 asm("pop %esi");
3305 asm("pop %edi");
3306 asm("movl %ebp,%esp");
3307 asm("popl %ebp");
3309 asm("movl %ecx,0(%esp)");
3310 asm("ret");
3312 #elif #machine(rs6000) && !defined _ARCH_PPC
3313 __unwind_function(void *ptr)
3315 asm("mr 31,1");
3316 asm("l 1,0(1)");
3317 asm("l 31,-4(1)");
3318 asm("# br");
3320 asm("mr 31,1");
3321 asm("l 1,0(1)");
3322 /* use 31 as a scratch register to restore the link register. */
3323 asm("l 31, 8(1);mtlr 31 # l lr,8(1)");
3324 asm("l 31,-4(1)");
3325 asm("# br");
3326 asm("mtctr 3;bctr # b 3");
3328 #elif (#machine(rs6000) || #machine(powerpc)) && defined _ARCH_PPC
3329 __unwind_function(void *ptr)
3331 asm("mr 31,1");
3332 asm("lwz 1,0(1)");
3333 asm("lwz 31,-4(1)");
3334 asm("# br");
3336 asm("mr 31,1");
3337 asm("lwz 1,0(1)");
3338 /* use 31 as a scratch register to restore the link register. */
3339 asm("lwz 31, 8(1);mtlr 31 # l lr,8(1)");
3340 asm("lwz 31,-4(1)");
3341 asm("# br");
3342 asm("mtctr 3;bctr # b 3");
3344 #elif #machine(vax)
3345 __unwind_function(void *ptr)
3347 __label__ return_again;
3349 /* Replace our frame's return address with the label below.
3350 During execution, we will first return here instead of to
3351 caller, then second return takes caller's frame off the stack.
3352 Two returns matches two actual calls, so is less likely to
3353 confuse debuggers. `16' corresponds to RETURN_ADDRESS_OFFSET. */
3354 __asm ("movl %0,16(fp)" : : "p" (&& return_again));
3355 return;
3357 return_again:
3358 return;
3360 #else
3361 __unwind_function(void *ptr)
3363 abort ();
3365 #endif /* powerpc */
3367 #else /* DWARF2_UNWIND_INFO */
3368 /* Support code for exception handling using static unwind information. */
3370 #include "frame.h"
3372 /* This type is used in get_reg and put_reg to deal with ABIs where a void*
3373 is smaller than a word, such as the Irix 6 n32 ABI. We cast twice to
3374 avoid a warning about casting between int and pointer of different
3375 sizes. */
3377 typedef int ptr_type __attribute__ ((mode (pointer)));
3379 /* Get the value of register REG as saved in UDATA, where SUB_UDATA is a
3380 frame called by UDATA or 0. */
3382 static void*
3383 get_reg (unsigned reg, frame_state *udata, frame_state *sub_udata)
3385 if (udata->saved[reg] == REG_SAVED_OFFSET)
3386 return (void *)(ptr_type)
3387 *(word_type *)(udata->cfa + udata->reg_or_offset[reg]);
3388 else if (udata->saved[reg] == REG_SAVED_REG && sub_udata)
3389 return get_reg (udata->reg_or_offset[reg], sub_udata, 0);
3390 else
3391 abort ();
3394 /* Overwrite the saved value for register REG in frame UDATA with VAL. */
3396 static void
3397 put_reg (unsigned reg, void *val, frame_state *udata)
3399 if (udata->saved[reg] == REG_SAVED_OFFSET)
3400 *(word_type *)(udata->cfa + udata->reg_or_offset[reg])
3401 = (word_type)(ptr_type) val;
3402 else
3403 abort ();
3406 /* Copy the saved value for register REG from frame UDATA to frame
3407 TARGET_UDATA. Unlike the previous two functions, this can handle
3408 registers that are not one word large. */
3410 static void
3411 copy_reg (unsigned reg, frame_state *udata, frame_state *target_udata)
3413 if (udata->saved[reg] == REG_SAVED_OFFSET
3414 && target_udata->saved[reg] == REG_SAVED_OFFSET)
3415 memcpy (target_udata->cfa + target_udata->reg_or_offset[reg],
3416 udata->cfa + udata->reg_or_offset[reg],
3417 __builtin_dwarf_reg_size (reg));
3418 else
3419 abort ();
3422 /* Retrieve the return address for frame UDATA, where SUB_UDATA is a
3423 frame called by UDATA or 0. */
3425 static inline void *
3426 get_return_addr (frame_state *udata, frame_state *sub_udata)
3428 return __builtin_extract_return_addr
3429 (get_reg (udata->retaddr_column, udata, sub_udata));
3432 /* Overwrite the return address for frame UDATA with VAL. */
3434 static inline void
3435 put_return_addr (void *val, frame_state *udata)
3437 val = __builtin_frob_return_addr (val);
3438 put_reg (udata->retaddr_column, val, udata);
3441 /* Given the current frame UDATA and its return address PC, return the
3442 information about the calling frame in CALLER_UDATA. */
3444 static void *
3445 next_stack_level (void *pc, frame_state *udata, frame_state *caller_udata)
3447 caller_udata = __frame_state_for (pc, caller_udata);
3448 if (! caller_udata)
3449 return 0;
3451 /* Now go back to our caller's stack frame. If our caller's CFA register
3452 was saved in our stack frame, restore it; otherwise, assume the CFA
3453 register is SP and restore it to our CFA value. */
3454 if (udata->saved[caller_udata->cfa_reg])
3455 caller_udata->cfa = get_reg (caller_udata->cfa_reg, udata, 0);
3456 else
3457 caller_udata->cfa = udata->cfa;
3458 caller_udata->cfa += caller_udata->cfa_offset;
3460 return caller_udata;
3463 #ifdef INCOMING_REGNO
3464 /* Is the saved value for register REG in frame UDATA stored in a register
3465 window in the previous frame? */
3467 static int
3468 in_reg_window (int reg, frame_state *udata)
3470 if (udata->saved[reg] != REG_SAVED_OFFSET)
3471 return 0;
3473 #ifdef STACK_GROWS_DOWNWARD
3474 return udata->reg_or_offset[reg] > 0;
3475 #else
3476 return udata->reg_or_offset[reg] < 0;
3477 #endif
3479 #endif /* INCOMING_REGNO */
3481 /* We first search for an exception handler, and if we don't find
3482 it, we call __terminate on the current stack frame so that we may
3483 use the debugger to walk the stack and understand why no handler
3484 was found.
3486 If we find one, then we unwind the frames down to the one that
3487 has the handler and transfer control into the handler. */
3489 void
3490 __throw ()
3492 void *pc, *handler, *retaddr;
3493 frame_state ustruct, ustruct2;
3494 frame_state *udata = &ustruct;
3495 frame_state *sub_udata = &ustruct2;
3496 frame_state my_ustruct, *my_udata = &my_ustruct;
3497 long args_size;
3499 /* This is required for C++ semantics. We must call terminate if we
3500 try and rethrow an exception, when there is no exception currently
3501 active. */
3502 if (! __eh_info)
3503 __terminate ();
3505 /* Start at our stack frame. */
3506 label:
3507 udata = __frame_state_for (&&label, udata);
3508 if (! udata)
3509 __terminate ();
3511 /* We need to get the value from the CFA register. At this point in
3512 compiling __throw we don't know whether or not we will use the frame
3513 pointer register for the CFA, so we check our unwind info. */
3514 if (udata->cfa_reg == __builtin_dwarf_fp_regnum ())
3515 udata->cfa = __builtin_fp ();
3516 else
3517 udata->cfa = __builtin_sp ();
3518 udata->cfa += udata->cfa_offset;
3520 memcpy (my_udata, udata, sizeof (*udata));
3522 /* Do any necessary initialization to access arbitrary stack frames.
3523 On the SPARC, this means flushing the register windows. */
3524 __builtin_unwind_init ();
3526 /* Now reset pc to the right throw point. */
3527 pc = __eh_pc;
3529 for (;;)
3531 frame_state *p = udata;
3532 udata = next_stack_level (pc, udata, sub_udata);
3533 sub_udata = p;
3535 /* If we couldn't find the next frame, we lose. */
3536 if (! udata)
3537 break;
3539 handler = find_exception_handler (pc, udata->eh_ptr);
3541 /* If we found one, we can stop searching. */
3542 if (handler)
3544 args_size = udata->args_size;
3545 break;
3548 /* Otherwise, we continue searching. We subtract 1 from PC to avoid
3549 hitting the beginning of the next region. */
3550 pc = get_return_addr (udata, sub_udata) - 1;
3553 /* If we haven't found a handler by now, this is an unhandled
3554 exception. */
3555 if (! handler)
3556 __terminate ();
3558 if (pc == __eh_pc)
3559 /* We found a handler in the throw context, no need to unwind. */
3560 udata = my_udata;
3561 else
3563 int i;
3564 void *val;
3566 /* Unwind all the frames between this one and the handler by copying
3567 their saved register values into our register save slots. */
3569 /* Remember the PC where we found the handler. */
3570 void *handler_pc = pc;
3572 /* Start from the throw context again. */
3573 pc = __eh_pc;
3574 memcpy (udata, my_udata, sizeof (*udata));
3576 while (pc != handler_pc)
3578 frame_state *p = udata;
3579 udata = next_stack_level (pc, udata, sub_udata);
3580 sub_udata = p;
3582 for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
3583 if (i != udata->retaddr_column && udata->saved[i])
3585 #ifdef INCOMING_REGNO
3586 /* If you modify the saved value of the return address
3587 register on the SPARC, you modify the return address for
3588 your caller's frame. Don't do that here, as it will
3589 confuse get_return_addr. */
3590 if (in_reg_window (i, udata)
3591 && udata->saved[udata->retaddr_column] == REG_SAVED_REG
3592 && udata->reg_or_offset[udata->retaddr_column] == i)
3593 continue;
3594 #endif
3595 copy_reg (i, udata, my_udata);
3598 pc = get_return_addr (udata, sub_udata) - 1;
3601 #ifdef INCOMING_REGNO
3602 /* But we do need to update the saved return address register from
3603 the last frame we unwind, or the handler frame will have the wrong
3604 return address. */
3605 if (udata->saved[udata->retaddr_column] == REG_SAVED_REG)
3607 i = udata->reg_or_offset[udata->retaddr_column];
3608 if (in_reg_window (i, udata))
3609 copy_reg (i, udata, my_udata);
3611 #endif
3613 /* udata now refers to the frame called by the handler frame. */
3615 /* Emit the stub to adjust sp and jump to the handler. */
3616 retaddr = __builtin_eh_stub ();
3618 /* And then set our return address to point to the stub. */
3619 if (my_udata->saved[my_udata->retaddr_column] == REG_SAVED_OFFSET)
3620 put_return_addr (retaddr, my_udata);
3621 else
3622 __builtin_set_return_addr_reg (retaddr);
3624 /* Set up the registers we use to communicate with the stub.
3625 We check STACK_GROWS_DOWNWARD so the stub can use adjust_stack. */
3626 __builtin_set_eh_regs (handler,
3627 #ifdef STACK_GROWS_DOWNWARD
3628 udata->cfa - my_udata->cfa
3629 #else
3630 my_udata->cfa - udata->cfa
3631 #endif
3632 + args_size
3635 /* Epilogue: restore the handler frame's register values and return
3636 to the stub. */
3638 #endif /* !DWARF2_UNWIND_INFO */
3640 #endif /* L_eh */
3642 #ifdef L_pure
3643 #ifndef inhibit_libc
3644 /* This gets us __GNU_LIBRARY__. */
3645 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
3646 #include <stdio.h>
3648 #ifdef __GNU_LIBRARY__
3649 /* Avoid forcing the library's meaning of `write' on the user program
3650 by using the "internal" name (for use within the library) */
3651 #define write(fd, buf, n) __write((fd), (buf), (n))
3652 #endif
3653 #endif /* inhibit_libc */
3655 #define MESSAGE "pure virtual method called\n"
3657 void
3658 __pure_virtual ()
3660 #ifndef inhibit_libc
3661 write (2, MESSAGE, sizeof (MESSAGE) - 1);
3662 #endif
3663 _exit (-1);
3665 #endif