(*zeroextract[qs]i_compare0_scratch): Use const_int_operand
[official-gcc.git] / gcc / libgcc2.c
blobc05f97aa535226ed7444f27bf1291d016ca60ebf
1 /* More subroutines needed by GCC output code on some machines. */
2 /* Compile this one with gcc. */
3 /* Copyright (C) 1989, 1992, 1993, 1994, 1995 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 #if (SUPPORTS_WEAK == 1) && defined (ASM_OUTPUT_DEF)
46 #define WEAK_ALIAS
47 #endif
49 /* Permit the tm.h file to select the endianness to use just for this
50 file. This is used when the endianness is determined when the
51 compiler is run. */
53 #ifndef LIBGCC2_WORDS_BIG_ENDIAN
54 #define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
55 #endif
57 /* In the first part of this file, we are interfacing to calls generated
58 by the compiler itself. These calls pass values into these routines
59 which have very specific modes (rather than very specific types), and
60 these compiler-generated calls also expect any return values to have
61 very specific modes (rather than very specific types). Thus, we need
62 to avoid using regular C language type names in this part of the file
63 because the sizes for those types can be configured to be anything.
64 Instead we use the following special type names. */
66 typedef unsigned int UQItype __attribute__ ((mode (QI)));
67 typedef int SItype __attribute__ ((mode (SI)));
68 typedef unsigned int USItype __attribute__ ((mode (SI)));
69 typedef int DItype __attribute__ ((mode (DI)));
70 typedef unsigned int UDItype __attribute__ ((mode (DI)));
72 typedef float SFtype __attribute__ ((mode (SF)));
73 typedef float DFtype __attribute__ ((mode (DF)));
75 #if LONG_DOUBLE_TYPE_SIZE == 96
76 typedef float XFtype __attribute__ ((mode (XF)));
77 #endif
78 #if LONG_DOUBLE_TYPE_SIZE == 128
79 typedef float TFtype __attribute__ ((mode (TF)));
80 #endif
82 typedef int word_type __attribute__ ((mode (__word__)));
84 /* Make sure that we don't accidentally use any normal C language built-in
85 type names in the first part of this file. Instead we want to use *only*
86 the type names defined above. The following macro definitions insure
87 that if we *do* accidentally use some normal C language built-in type name,
88 we will get a syntax error. */
90 #define char bogus_type
91 #define short bogus_type
92 #define int bogus_type
93 #define long bogus_type
94 #define unsigned bogus_type
95 #define float bogus_type
96 #define double bogus_type
98 #define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
100 /* DIstructs are pairs of SItype values in the order determined by
101 LIBGCC2_WORDS_BIG_ENDIAN. */
103 #if LIBGCC2_WORDS_BIG_ENDIAN
104 struct DIstruct {SItype high, low;};
105 #else
106 struct DIstruct {SItype low, high;};
107 #endif
109 /* We need this union to unpack/pack DImode values, since we don't have
110 any arithmetic yet. Incoming DImode parameters are stored into the
111 `ll' field, and the unpacked result is read from the struct `s'. */
113 typedef union
115 struct DIstruct s;
116 DItype ll;
117 } DIunion;
119 #if (defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_w_sdiv)\
120 || defined (L_divdi3) || defined (L_udivdi3) \
121 || defined (L_moddi3) || defined (L_umoddi3))
123 #include "longlong.h"
125 #endif /* udiv or mul */
127 extern DItype __fixunssfdi (SFtype a);
128 extern DItype __fixunsdfdi (DFtype a);
129 #if LONG_DOUBLE_TYPE_SIZE == 96
130 extern DItype __fixunsxfdi (XFtype a);
131 #endif
132 #if LONG_DOUBLE_TYPE_SIZE == 128
133 extern DItype __fixunstfdi (TFtype a);
134 #endif
136 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
137 #if defined (L_divdi3) || defined (L_moddi3)
138 static inline
139 #endif
140 DItype
141 __negdi2 (u)
142 DItype u;
144 DIunion w;
145 DIunion uu;
147 uu.ll = u;
149 w.s.low = -uu.s.low;
150 w.s.high = -uu.s.high - ((USItype) w.s.low > 0);
152 return w.ll;
154 #endif
156 #ifdef L_lshrdi3
157 DItype
158 __lshrdi3 (u, b)
159 DItype u;
160 word_type b;
162 DIunion w;
163 word_type bm;
164 DIunion uu;
166 if (b == 0)
167 return u;
169 uu.ll = u;
171 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
172 if (bm <= 0)
174 w.s.high = 0;
175 w.s.low = (USItype)uu.s.high >> -bm;
177 else
179 USItype carries = (USItype)uu.s.high << bm;
180 w.s.high = (USItype)uu.s.high >> b;
181 w.s.low = ((USItype)uu.s.low >> b) | carries;
184 return w.ll;
186 #endif
188 #ifdef L_ashldi3
189 DItype
190 __ashldi3 (u, b)
191 DItype u;
192 word_type b;
194 DIunion w;
195 word_type bm;
196 DIunion uu;
198 if (b == 0)
199 return u;
201 uu.ll = u;
203 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
204 if (bm <= 0)
206 w.s.low = 0;
207 w.s.high = (USItype)uu.s.low << -bm;
209 else
211 USItype carries = (USItype)uu.s.low >> bm;
212 w.s.low = (USItype)uu.s.low << b;
213 w.s.high = ((USItype)uu.s.high << b) | carries;
216 return w.ll;
218 #endif
220 #ifdef L_ashrdi3
221 DItype
222 __ashrdi3 (u, b)
223 DItype u;
224 word_type b;
226 DIunion w;
227 word_type bm;
228 DIunion uu;
230 if (b == 0)
231 return u;
233 uu.ll = u;
235 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
236 if (bm <= 0)
238 /* w.s.high = 1..1 or 0..0 */
239 w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
240 w.s.low = uu.s.high >> -bm;
242 else
244 USItype carries = (USItype)uu.s.high << bm;
245 w.s.high = uu.s.high >> b;
246 w.s.low = ((USItype)uu.s.low >> b) | carries;
249 return w.ll;
251 #endif
253 #ifdef L_ffsdi2
254 DItype
255 __ffsdi2 (u)
256 DItype u;
258 DIunion uu, w;
259 uu.ll = u;
260 w.s.high = 0;
261 w.s.low = ffs (uu.s.low);
262 if (w.s.low != 0)
263 return w.ll;
264 w.s.low = ffs (uu.s.high);
265 if (w.s.low != 0)
267 w.s.low += BITS_PER_UNIT * sizeof (SItype);
268 return w.ll;
270 return w.ll;
272 #endif
274 #ifdef L_muldi3
275 DItype
276 __muldi3 (u, v)
277 DItype u, v;
279 DIunion w;
280 DIunion uu, vv;
282 uu.ll = u,
283 vv.ll = v;
285 w.ll = __umulsidi3 (uu.s.low, vv.s.low);
286 w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
287 + (USItype) uu.s.high * (USItype) vv.s.low);
289 return w.ll;
291 #endif
293 #ifdef L_udiv_w_sdiv
294 #if defined (sdiv_qrnnd)
295 USItype
296 __udiv_w_sdiv (rp, a1, a0, d)
297 USItype *rp, a1, a0, d;
299 USItype q, r;
300 USItype c0, c1, b1;
302 if ((SItype) d >= 0)
304 if (a1 < d - a1 - (a0 >> (SI_TYPE_SIZE - 1)))
306 /* dividend, divisor, and quotient are nonnegative */
307 sdiv_qrnnd (q, r, a1, a0, d);
309 else
311 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
312 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (SI_TYPE_SIZE - 1));
313 /* Divide (c1*2^32 + c0) by d */
314 sdiv_qrnnd (q, r, c1, c0, d);
315 /* Add 2^31 to quotient */
316 q += (USItype) 1 << (SI_TYPE_SIZE - 1);
319 else
321 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
322 c1 = a1 >> 1; /* A/2 */
323 c0 = (a1 << (SI_TYPE_SIZE - 1)) + (a0 >> 1);
325 if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
327 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
329 r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
330 if ((d & 1) != 0)
332 if (r >= q)
333 r = r - q;
334 else if (q - r <= d)
336 r = r - q + d;
337 q--;
339 else
341 r = r - q + 2*d;
342 q -= 2;
346 else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
348 c1 = (b1 - 1) - c1;
349 c0 = ~c0; /* logical NOT */
351 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
353 q = ~q; /* (A/2)/b1 */
354 r = (b1 - 1) - r;
356 r = 2*r + (a0 & 1); /* A/(2*b1) */
358 if ((d & 1) != 0)
360 if (r >= q)
361 r = r - q;
362 else if (q - r <= d)
364 r = r - q + d;
365 q--;
367 else
369 r = r - q + 2*d;
370 q -= 2;
374 else /* Implies c1 = b1 */
375 { /* Hence a1 = d - 1 = 2*b1 - 1 */
376 if (a0 >= -d)
378 q = -1;
379 r = a0 + d;
381 else
383 q = -2;
384 r = a0 + 2*d;
389 *rp = r;
390 return q;
392 #else
393 /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */
394 USItype
395 __udiv_w_sdiv (rp, a1, a0, d)
396 USItype *rp, a1, a0, d;
398 #endif
399 #endif
401 #if (defined (L_udivdi3) || defined (L_divdi3) || \
402 defined (L_umoddi3) || defined (L_moddi3))
403 #define L_udivmoddi4
404 #endif
406 #ifdef L_udivmoddi4
407 static const UQItype __clz_tab[] =
409 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,
410 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,
411 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,
412 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,
413 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
414 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
415 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,
416 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,
419 #if (defined (L_udivdi3) || defined (L_divdi3) || \
420 defined (L_umoddi3) || defined (L_moddi3))
421 static inline
422 #endif
423 UDItype
424 __udivmoddi4 (n, d, rp)
425 UDItype n, d;
426 UDItype *rp;
428 DIunion ww;
429 DIunion nn, dd;
430 DIunion rr;
431 USItype d0, d1, n0, n1, n2;
432 USItype q0, q1;
433 USItype b, bm;
435 nn.ll = n;
436 dd.ll = d;
438 d0 = dd.s.low;
439 d1 = dd.s.high;
440 n0 = nn.s.low;
441 n1 = nn.s.high;
443 #if !UDIV_NEEDS_NORMALIZATION
444 if (d1 == 0)
446 if (d0 > n1)
448 /* 0q = nn / 0D */
450 udiv_qrnnd (q0, n0, n1, n0, d0);
451 q1 = 0;
453 /* Remainder in n0. */
455 else
457 /* qq = NN / 0d */
459 if (d0 == 0)
460 d0 = 1 / d0; /* Divide intentionally by zero. */
462 udiv_qrnnd (q1, n1, 0, n1, d0);
463 udiv_qrnnd (q0, n0, n1, n0, d0);
465 /* Remainder in n0. */
468 if (rp != 0)
470 rr.s.low = n0;
471 rr.s.high = 0;
472 *rp = rr.ll;
476 #else /* UDIV_NEEDS_NORMALIZATION */
478 if (d1 == 0)
480 if (d0 > n1)
482 /* 0q = nn / 0D */
484 count_leading_zeros (bm, d0);
486 if (bm != 0)
488 /* Normalize, i.e. make the most significant bit of the
489 denominator set. */
491 d0 = d0 << bm;
492 n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
493 n0 = n0 << bm;
496 udiv_qrnnd (q0, n0, n1, n0, d0);
497 q1 = 0;
499 /* Remainder in n0 >> bm. */
501 else
503 /* qq = NN / 0d */
505 if (d0 == 0)
506 d0 = 1 / d0; /* Divide intentionally by zero. */
508 count_leading_zeros (bm, d0);
510 if (bm == 0)
512 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
513 conclude (the most significant bit of n1 is set) /\ (the
514 leading quotient digit q1 = 1).
516 This special case is necessary, not an optimization.
517 (Shifts counts of SI_TYPE_SIZE are undefined.) */
519 n1 -= d0;
520 q1 = 1;
522 else
524 /* Normalize. */
526 b = SI_TYPE_SIZE - bm;
528 d0 = d0 << bm;
529 n2 = n1 >> b;
530 n1 = (n1 << bm) | (n0 >> b);
531 n0 = n0 << bm;
533 udiv_qrnnd (q1, n1, n2, n1, d0);
536 /* n1 != d0... */
538 udiv_qrnnd (q0, n0, n1, n0, d0);
540 /* Remainder in n0 >> bm. */
543 if (rp != 0)
545 rr.s.low = n0 >> bm;
546 rr.s.high = 0;
547 *rp = rr.ll;
550 #endif /* UDIV_NEEDS_NORMALIZATION */
552 else
554 if (d1 > n1)
556 /* 00 = nn / DD */
558 q0 = 0;
559 q1 = 0;
561 /* Remainder in n1n0. */
562 if (rp != 0)
564 rr.s.low = n0;
565 rr.s.high = n1;
566 *rp = rr.ll;
569 else
571 /* 0q = NN / dd */
573 count_leading_zeros (bm, d1);
574 if (bm == 0)
576 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
577 conclude (the most significant bit of n1 is set) /\ (the
578 quotient digit q0 = 0 or 1).
580 This special case is necessary, not an optimization. */
582 /* The condition on the next line takes advantage of that
583 n1 >= d1 (true due to program flow). */
584 if (n1 > d1 || n0 >= d0)
586 q0 = 1;
587 sub_ddmmss (n1, n0, n1, n0, d1, d0);
589 else
590 q0 = 0;
592 q1 = 0;
594 if (rp != 0)
596 rr.s.low = n0;
597 rr.s.high = n1;
598 *rp = rr.ll;
601 else
603 USItype m1, m0;
604 /* Normalize. */
606 b = SI_TYPE_SIZE - bm;
608 d1 = (d1 << bm) | (d0 >> b);
609 d0 = d0 << bm;
610 n2 = n1 >> b;
611 n1 = (n1 << bm) | (n0 >> b);
612 n0 = n0 << bm;
614 udiv_qrnnd (q0, n1, n2, n1, d1);
615 umul_ppmm (m1, m0, q0, d0);
617 if (m1 > n1 || (m1 == n1 && m0 > n0))
619 q0--;
620 sub_ddmmss (m1, m0, m1, m0, d1, d0);
623 q1 = 0;
625 /* Remainder in (n1n0 - m1m0) >> bm. */
626 if (rp != 0)
628 sub_ddmmss (n1, n0, n1, n0, m1, m0);
629 rr.s.low = (n1 << b) | (n0 >> bm);
630 rr.s.high = n1 >> bm;
631 *rp = rr.ll;
637 ww.s.low = q0;
638 ww.s.high = q1;
639 return ww.ll;
641 #endif
643 #ifdef L_divdi3
644 UDItype __udivmoddi4 ();
646 DItype
647 __divdi3 (u, v)
648 DItype u, v;
650 word_type c = 0;
651 DIunion uu, vv;
652 DItype w;
654 uu.ll = u;
655 vv.ll = v;
657 if (uu.s.high < 0)
658 c = ~c,
659 uu.ll = __negdi2 (uu.ll);
660 if (vv.s.high < 0)
661 c = ~c,
662 vv.ll = __negdi2 (vv.ll);
664 w = __udivmoddi4 (uu.ll, vv.ll, (UDItype *) 0);
665 if (c)
666 w = __negdi2 (w);
668 return w;
670 #endif
672 #ifdef L_moddi3
673 UDItype __udivmoddi4 ();
674 DItype
675 __moddi3 (u, v)
676 DItype u, v;
678 word_type c = 0;
679 DIunion uu, vv;
680 DItype w;
682 uu.ll = u;
683 vv.ll = v;
685 if (uu.s.high < 0)
686 c = ~c,
687 uu.ll = __negdi2 (uu.ll);
688 if (vv.s.high < 0)
689 vv.ll = __negdi2 (vv.ll);
691 (void) __udivmoddi4 (uu.ll, vv.ll, &w);
692 if (c)
693 w = __negdi2 (w);
695 return w;
697 #endif
699 #ifdef L_umoddi3
700 UDItype __udivmoddi4 ();
701 UDItype
702 __umoddi3 (u, v)
703 UDItype u, v;
705 UDItype w;
707 (void) __udivmoddi4 (u, v, &w);
709 return w;
711 #endif
713 #ifdef L_udivdi3
714 UDItype __udivmoddi4 ();
715 UDItype
716 __udivdi3 (n, d)
717 UDItype n, d;
719 return __udivmoddi4 (n, d, (UDItype *) 0);
721 #endif
723 #ifdef L_cmpdi2
724 word_type
725 __cmpdi2 (a, b)
726 DItype a, b;
728 DIunion au, bu;
730 au.ll = a, bu.ll = b;
732 if (au.s.high < bu.s.high)
733 return 0;
734 else if (au.s.high > 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 #ifdef L_ucmpdi2
745 word_type
746 __ucmpdi2 (a, b)
747 DItype a, b;
749 DIunion au, bu;
751 au.ll = a, bu.ll = b;
753 if ((USItype) au.s.high < (USItype) bu.s.high)
754 return 0;
755 else if ((USItype) au.s.high > (USItype) bu.s.high)
756 return 2;
757 if ((USItype) au.s.low < (USItype) bu.s.low)
758 return 0;
759 else if ((USItype) au.s.low > (USItype) bu.s.low)
760 return 2;
761 return 1;
763 #endif
765 #if defined(L_fixunstfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
766 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
767 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
769 DItype
770 __fixunstfdi (a)
771 TFtype a;
773 TFtype b;
774 UDItype v;
776 if (a < 0)
777 return 0;
779 /* Compute high word of result, as a flonum. */
780 b = (a / HIGH_WORD_COEFF);
781 /* Convert that to fixed (but not to DItype!),
782 and shift it into the high word. */
783 v = (USItype) b;
784 v <<= WORD_SIZE;
785 /* Remove high part from the TFtype, leaving the low part as flonum. */
786 a -= (TFtype)v;
787 /* Convert that to fixed (but not to DItype!) and add it in.
788 Sometimes A comes out negative. This is significant, since
789 A has more bits than a long int does. */
790 if (a < 0)
791 v -= (USItype) (- a);
792 else
793 v += (USItype) a;
794 return v;
796 #endif
798 #if defined(L_fixtfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
799 DItype
800 __fixtfdi (a)
801 TFtype a;
803 if (a < 0)
804 return - __fixunstfdi (-a);
805 return __fixunstfdi (a);
807 #endif
809 #if defined(L_fixunsxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
810 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
811 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
813 DItype
814 __fixunsxfdi (a)
815 XFtype a;
817 XFtype b;
818 UDItype v;
820 if (a < 0)
821 return 0;
823 /* Compute high word of result, as a flonum. */
824 b = (a / HIGH_WORD_COEFF);
825 /* Convert that to fixed (but not to DItype!),
826 and shift it into the high word. */
827 v = (USItype) b;
828 v <<= WORD_SIZE;
829 /* Remove high part from the XFtype, leaving the low part as flonum. */
830 a -= (XFtype)v;
831 /* Convert that to fixed (but not to DItype!) and add it in.
832 Sometimes A comes out negative. This is significant, since
833 A has more bits than a long int does. */
834 if (a < 0)
835 v -= (USItype) (- a);
836 else
837 v += (USItype) a;
838 return v;
840 #endif
842 #if defined(L_fixxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
843 DItype
844 __fixxfdi (a)
845 XFtype a;
847 if (a < 0)
848 return - __fixunsxfdi (-a);
849 return __fixunsxfdi (a);
851 #endif
853 #ifdef L_fixunsdfdi
854 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
855 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
857 DItype
858 __fixunsdfdi (a)
859 DFtype a;
861 DFtype b;
862 UDItype v;
864 if (a < 0)
865 return 0;
867 /* Compute high word of result, as a flonum. */
868 b = (a / HIGH_WORD_COEFF);
869 /* Convert that to fixed (but not to DItype!),
870 and shift it into the high word. */
871 v = (USItype) b;
872 v <<= WORD_SIZE;
873 /* Remove high part from the DFtype, leaving the low part as flonum. */
874 a -= (DFtype)v;
875 /* Convert that to fixed (but not to DItype!) and add it in.
876 Sometimes A comes out negative. This is significant, since
877 A has more bits than a long int does. */
878 if (a < 0)
879 v -= (USItype) (- a);
880 else
881 v += (USItype) a;
882 return v;
884 #endif
886 #ifdef L_fixdfdi
887 DItype
888 __fixdfdi (a)
889 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) && (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 (u)
950 DItype u;
952 XFtype d;
953 SItype negate = 0;
955 if (u < 0)
956 u = -u, negate = 1;
958 d = (USItype) (u >> WORD_SIZE);
959 d *= HIGH_HALFWORD_COEFF;
960 d *= HIGH_HALFWORD_COEFF;
961 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
963 return (negate ? -d : d);
965 #endif
967 #if defined(L_floatditf) && (LONG_DOUBLE_TYPE_SIZE == 128)
968 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
969 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
970 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
972 TFtype
973 __floatditf (u)
974 DItype u;
976 TFtype d;
977 SItype negate = 0;
979 if (u < 0)
980 u = -u, negate = 1;
982 d = (USItype) (u >> WORD_SIZE);
983 d *= HIGH_HALFWORD_COEFF;
984 d *= HIGH_HALFWORD_COEFF;
985 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
987 return (negate ? -d : d);
989 #endif
991 #ifdef L_floatdidf
992 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
993 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
994 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
996 DFtype
997 __floatdidf (u)
998 DItype u;
1000 DFtype d;
1001 SItype negate = 0;
1003 if (u < 0)
1004 u = -u, negate = 1;
1006 d = (USItype) (u >> WORD_SIZE);
1007 d *= HIGH_HALFWORD_COEFF;
1008 d *= HIGH_HALFWORD_COEFF;
1009 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
1011 return (negate ? -d : d);
1013 #endif
1015 #ifdef L_floatdisf
1016 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
1017 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
1018 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
1019 #define DI_SIZE (sizeof (DItype) * BITS_PER_UNIT)
1021 /* Define codes for all the float formats that we know of. Note
1022 that this is copied from real.h. */
1024 #define UNKNOWN_FLOAT_FORMAT 0
1025 #define IEEE_FLOAT_FORMAT 1
1026 #define VAX_FLOAT_FORMAT 2
1027 #define IBM_FLOAT_FORMAT 3
1029 /* Default to IEEE float if not specified. Nearly all machines use it. */
1030 #ifndef HOST_FLOAT_FORMAT
1031 #define HOST_FLOAT_FORMAT IEEE_FLOAT_FORMAT
1032 #endif
1034 #if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1035 #define DF_SIZE 53
1036 #define SF_SIZE 24
1037 #endif
1039 #if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
1040 #define DF_SIZE 56
1041 #define SF_SIZE 24
1042 #endif
1044 #if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
1045 #define DF_SIZE 56
1046 #define SF_SIZE 24
1047 #endif
1049 SFtype
1050 __floatdisf (u)
1051 DItype u;
1053 /* Do the calculation in DFmode
1054 so that we don't lose any of the precision of the high word
1055 while multiplying it. */
1056 DFtype f;
1057 SItype negate = 0;
1059 if (u < 0)
1060 u = -u, negate = 1;
1062 /* Protect against double-rounding error.
1063 Represent any low-order bits, that might be truncated in DFmode,
1064 by a bit that won't be lost. The bit can go in anywhere below the
1065 rounding position of the SFmode. A fixed mask and bit position
1066 handles all usual configurations. It doesn't handle the case
1067 of 128-bit DImode, however. */
1068 if (DF_SIZE < DI_SIZE
1069 && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1071 #define REP_BIT ((USItype) 1 << (DI_SIZE - DF_SIZE))
1072 if (u >= ((UDItype) 1 << DF_SIZE))
1074 if ((USItype) u & (REP_BIT - 1))
1075 u |= REP_BIT;
1078 f = (USItype) (u >> WORD_SIZE);
1079 f *= HIGH_HALFWORD_COEFF;
1080 f *= HIGH_HALFWORD_COEFF;
1081 f += (USItype) (u & (HIGH_WORD_COEFF - 1));
1083 return (SFtype) (negate ? -f : f);
1085 #endif
1087 #if defined(L_fixunsxfsi) && LONG_DOUBLE_TYPE_SIZE == 96
1088 /* Reenable the normal types, in case limits.h needs them. */
1089 #undef char
1090 #undef short
1091 #undef int
1092 #undef long
1093 #undef unsigned
1094 #undef float
1095 #undef double
1096 #undef MIN
1097 #undef MAX
1098 #include <limits.h>
1100 USItype
1101 __fixunsxfsi (a)
1102 XFtype a;
1104 if (a >= - (DFtype) LONG_MIN)
1105 return (SItype) (a + LONG_MIN) - LONG_MIN;
1106 return (SItype) a;
1108 #endif
1110 #ifdef L_fixunsdfsi
1111 /* Reenable the normal types, in case limits.h needs them. */
1112 #undef char
1113 #undef short
1114 #undef int
1115 #undef long
1116 #undef unsigned
1117 #undef float
1118 #undef double
1119 #undef MIN
1120 #undef MAX
1121 #include <limits.h>
1123 USItype
1124 __fixunsdfsi (a)
1125 DFtype a;
1127 if (a >= - (DFtype) LONG_MIN)
1128 return (SItype) (a + LONG_MIN) - LONG_MIN;
1129 return (SItype) a;
1131 #endif
1133 #ifdef L_fixunssfsi
1134 /* Reenable the normal types, in case limits.h needs them. */
1135 #undef char
1136 #undef short
1137 #undef int
1138 #undef long
1139 #undef unsigned
1140 #undef float
1141 #undef double
1142 #undef MIN
1143 #undef MAX
1144 #include <limits.h>
1146 USItype
1147 __fixunssfsi (SFtype a)
1149 if (a >= - (SFtype) LONG_MIN)
1150 return (SItype) (a + LONG_MIN) - LONG_MIN;
1151 return (SItype) a;
1153 #endif
1155 /* From here on down, the routines use normal data types. */
1157 #define SItype bogus_type
1158 #define USItype bogus_type
1159 #define DItype bogus_type
1160 #define UDItype bogus_type
1161 #define SFtype bogus_type
1162 #define DFtype bogus_type
1164 #undef char
1165 #undef short
1166 #undef int
1167 #undef long
1168 #undef unsigned
1169 #undef float
1170 #undef double
1172 #ifdef L__gcc_bcmp
1174 /* Like bcmp except the sign is meaningful.
1175 Result is negative if S1 is less than S2,
1176 positive if S1 is greater, 0 if S1 and S2 are equal. */
1179 __gcc_bcmp (s1, s2, size)
1180 unsigned char *s1, *s2;
1181 size_t size;
1183 while (size > 0)
1185 unsigned char c1 = *s1++, c2 = *s2++;
1186 if (c1 != c2)
1187 return c1 - c2;
1188 size--;
1190 return 0;
1193 #endif
1194 \f\f
1195 #ifdef L_varargs
1196 #ifdef __i860__
1197 #if defined(__svr4__) || defined(__alliant__)
1198 asm (" .text");
1199 asm (" .align 4");
1201 /* The Alliant needs the added underscore. */
1202 asm (".globl __builtin_saveregs");
1203 asm ("__builtin_saveregs:");
1204 asm (".globl ___builtin_saveregs");
1205 asm ("___builtin_saveregs:");
1207 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
1208 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
1209 area and also for a new va_list
1210 structure */
1211 /* Save all argument registers in the arg reg save area. The
1212 arg reg save area must have the following layout (according
1213 to the svr4 ABI):
1215 struct {
1216 union {
1217 float freg[8];
1218 double dreg[4];
1219 } float_regs;
1220 long ireg[12];
1224 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
1225 asm (" fst.q %f12,16(%sp)");
1227 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
1228 asm (" st.l %r17,36(%sp)");
1229 asm (" st.l %r18,40(%sp)");
1230 asm (" st.l %r19,44(%sp)");
1231 asm (" st.l %r20,48(%sp)");
1232 asm (" st.l %r21,52(%sp)");
1233 asm (" st.l %r22,56(%sp)");
1234 asm (" st.l %r23,60(%sp)");
1235 asm (" st.l %r24,64(%sp)");
1236 asm (" st.l %r25,68(%sp)");
1237 asm (" st.l %r26,72(%sp)");
1238 asm (" st.l %r27,76(%sp)");
1240 asm (" adds 80,%sp,%r16"); /* compute the address of the new
1241 va_list structure. Put in into
1242 r16 so that it will be returned
1243 to the caller. */
1245 /* Initialize all fields of the new va_list structure. This
1246 structure looks like:
1248 typedef struct {
1249 unsigned long ireg_used;
1250 unsigned long freg_used;
1251 long *reg_base;
1252 long *mem_ptr;
1253 } va_list;
1256 asm (" st.l %r0, 0(%r16)"); /* nfixed */
1257 asm (" st.l %r0, 4(%r16)"); /* nfloating */
1258 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
1259 asm (" bri %r1"); /* delayed return */
1260 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
1262 #else /* not __svr4__ */
1263 #if defined(__PARAGON__)
1265 * we'll use SVR4-ish varargs but need SVR3.2 assembler syntax,
1266 * and we stand a better chance of hooking into libraries
1267 * compiled by PGI. [andyp@ssd.intel.com]
1269 asm (" .text");
1270 asm (" .align 4");
1271 asm (".globl __builtin_saveregs");
1272 asm ("__builtin_saveregs:");
1273 asm (".globl ___builtin_saveregs");
1274 asm ("___builtin_saveregs:");
1276 asm (" andnot 0x0f,sp,sp"); /* round down to 16-byte boundary */
1277 asm (" adds -96,sp,sp"); /* allocate stack space for reg save
1278 area and also for a new va_list
1279 structure */
1280 /* Save all argument registers in the arg reg save area. The
1281 arg reg save area must have the following layout (according
1282 to the svr4 ABI):
1284 struct {
1285 union {
1286 float freg[8];
1287 double dreg[4];
1288 } float_regs;
1289 long ireg[12];
1293 asm (" fst.q f8, 0(sp)");
1294 asm (" fst.q f12,16(sp)");
1295 asm (" st.l r16,32(sp)");
1296 asm (" st.l r17,36(sp)");
1297 asm (" st.l r18,40(sp)");
1298 asm (" st.l r19,44(sp)");
1299 asm (" st.l r20,48(sp)");
1300 asm (" st.l r21,52(sp)");
1301 asm (" st.l r22,56(sp)");
1302 asm (" st.l r23,60(sp)");
1303 asm (" st.l r24,64(sp)");
1304 asm (" st.l r25,68(sp)");
1305 asm (" st.l r26,72(sp)");
1306 asm (" st.l r27,76(sp)");
1308 asm (" adds 80,sp,r16"); /* compute the address of the new
1309 va_list structure. Put in into
1310 r16 so that it will be returned
1311 to the caller. */
1313 /* Initialize all fields of the new va_list structure. This
1314 structure looks like:
1316 typedef struct {
1317 unsigned long ireg_used;
1318 unsigned long freg_used;
1319 long *reg_base;
1320 long *mem_ptr;
1321 } va_list;
1324 asm (" st.l r0, 0(r16)"); /* nfixed */
1325 asm (" st.l r0, 4(r16)"); /* nfloating */
1326 asm (" st.l sp, 8(r16)"); /* __va_ctl points to __va_struct. */
1327 asm (" bri r1"); /* delayed return */
1328 asm (" st.l r28,12(r16)"); /* pointer to overflow args */
1329 #else /* not __PARAGON__ */
1330 asm (" .text");
1331 asm (" .align 4");
1333 asm (".globl ___builtin_saveregs");
1334 asm ("___builtin_saveregs:");
1335 asm (" mov sp,r30");
1336 asm (" andnot 0x0f,sp,sp");
1337 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
1339 /* Fill in the __va_struct. */
1340 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
1341 asm (" st.l r17, 4(sp)"); /* int fixed[12] */
1342 asm (" st.l r18, 8(sp)");
1343 asm (" st.l r19,12(sp)");
1344 asm (" st.l r20,16(sp)");
1345 asm (" st.l r21,20(sp)");
1346 asm (" st.l r22,24(sp)");
1347 asm (" st.l r23,28(sp)");
1348 asm (" st.l r24,32(sp)");
1349 asm (" st.l r25,36(sp)");
1350 asm (" st.l r26,40(sp)");
1351 asm (" st.l r27,44(sp)");
1353 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
1354 asm (" fst.q f12,64(sp)"); /* int floating[8] */
1356 /* Fill in the __va_ctl. */
1357 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
1358 asm (" st.l r28,84(sp)"); /* pointer to more args */
1359 asm (" st.l r0, 88(sp)"); /* nfixed */
1360 asm (" st.l r0, 92(sp)"); /* nfloating */
1362 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
1363 asm (" bri r1");
1364 asm (" mov r30,sp");
1365 /* recover stack and pass address to start
1366 of data. */
1367 #endif /* not __PARAGON__ */
1368 #endif /* not __svr4__ */
1369 #else /* not __i860__ */
1370 #ifdef __sparc__
1371 asm (".global __builtin_saveregs");
1372 asm ("__builtin_saveregs:");
1373 asm (".global ___builtin_saveregs");
1374 asm ("___builtin_saveregs:");
1375 #ifdef NEED_PROC_COMMAND
1376 asm (".proc 020");
1377 #endif
1378 asm ("st %i0,[%fp+68]");
1379 asm ("st %i1,[%fp+72]");
1380 asm ("st %i2,[%fp+76]");
1381 asm ("st %i3,[%fp+80]");
1382 asm ("st %i4,[%fp+84]");
1383 asm ("retl");
1384 asm ("st %i5,[%fp+88]");
1385 #ifdef NEED_TYPE_COMMAND
1386 asm (".type __builtin_saveregs,#function");
1387 asm (".size __builtin_saveregs,.-__builtin_saveregs");
1388 #endif
1389 #else /* not __sparc__ */
1390 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1392 asm (" .text");
1393 asm (" .ent __builtin_saveregs");
1394 asm (" .globl __builtin_saveregs");
1395 asm ("__builtin_saveregs:");
1396 asm (" sw $4,0($30)");
1397 asm (" sw $5,4($30)");
1398 asm (" sw $6,8($30)");
1399 asm (" sw $7,12($30)");
1400 asm (" j $31");
1401 asm (" .end __builtin_saveregs");
1402 #else /* not __mips__, etc. */
1404 void *
1405 __builtin_saveregs ()
1407 abort ();
1410 #endif /* not __mips__ */
1411 #endif /* not __sparc__ */
1412 #endif /* not __i860__ */
1413 #endif
1415 #ifdef L_eprintf
1416 #ifndef inhibit_libc
1418 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1419 #include <stdio.h>
1420 /* This is used by the `assert' macro. */
1421 void
1422 __eprintf (string, expression, line, filename)
1423 const char *string;
1424 const char *expression;
1425 int line;
1426 const char *filename;
1428 fprintf (stderr, string, expression, line, filename);
1429 fflush (stderr);
1430 abort ();
1433 #endif
1434 #endif
1436 #ifdef L_bb
1438 /* Structure emitted by -a */
1439 struct bb
1441 long zero_word;
1442 const char *filename;
1443 long *counts;
1444 long ncounts;
1445 struct bb *next;
1446 const unsigned long *addresses;
1448 /* Older GCC's did not emit these fields. */
1449 long nwords;
1450 const char **functions;
1451 const long *line_nums;
1452 const char **filenames;
1453 char *flags;
1456 #ifdef BLOCK_PROFILER_CODE
1457 BLOCK_PROFILER_CODE
1458 #else
1459 #ifndef inhibit_libc
1461 /* Simple minded basic block profiling output dumper for
1462 systems that don't provide tcov support. At present,
1463 it requires atexit and stdio. */
1465 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1466 #include <stdio.h>
1467 char *ctime ();
1469 #ifdef HAVE_ATEXIT
1470 #ifdef WINNT
1471 extern int atexit (void (*) (void));
1472 #else
1473 extern void atexit (void (*) (void));
1474 #endif
1475 #define ON_EXIT(FUNC,ARG) atexit ((FUNC))
1476 #else
1477 #ifdef sun
1478 extern void on_exit (void*, void*);
1479 #define ON_EXIT(FUNC,ARG) on_exit ((FUNC), (ARG))
1480 #endif
1481 #endif
1483 static struct bb *bb_head;
1485 /* Return the number of digits needed to print a value */
1486 /* __inline__ */ static int num_digits (long value, int base)
1488 int minus = (value < 0 && base != 16);
1489 unsigned long v = (minus) ? -value : value;
1490 int ret = minus;
1494 v /= base;
1495 ret++;
1497 while (v);
1499 return ret;
1502 void
1503 __bb_exit_func (void)
1505 FILE *file = fopen ("bb.out", "a");
1506 long time_value;
1508 if (!file)
1509 perror ("bb.out");
1511 else
1513 struct bb *ptr;
1515 /* This is somewhat type incorrect, but it avoids worrying about
1516 exactly where time.h is included from. It should be ok unless
1517 a void * differs from other pointer formats, or if sizeof (long)
1518 is < sizeof (time_t). It would be nice if we could assume the
1519 use of rationale standards here. */
1521 time ((void *) &time_value);
1522 fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value));
1524 /* We check the length field explicitly in order to allow compatibility
1525 with older GCC's which did not provide it. */
1527 for (ptr = bb_head; ptr != (struct bb *)0; ptr = ptr->next)
1529 int i;
1530 int func_p = (ptr->nwords >= sizeof (struct bb) && ptr->nwords <= 1000);
1531 int line_p = (func_p && ptr->line_nums);
1532 int file_p = (func_p && ptr->filenames);
1533 long ncounts = ptr->ncounts;
1534 long cnt_max = 0;
1535 long line_max = 0;
1536 long addr_max = 0;
1537 int file_len = 0;
1538 int func_len = 0;
1539 int blk_len = num_digits (ncounts, 10);
1540 int cnt_len;
1541 int line_len;
1542 int addr_len;
1544 fprintf (file, "File %s, %ld basic blocks \n\n",
1545 ptr->filename, ncounts);
1547 /* Get max values for each field. */
1548 for (i = 0; i < ncounts; i++)
1550 const char *p;
1551 int len;
1553 if (cnt_max < ptr->counts[i])
1554 cnt_max = ptr->counts[i];
1556 if (addr_max < ptr->addresses[i])
1557 addr_max = ptr->addresses[i];
1559 if (line_p && line_max < ptr->line_nums[i])
1560 line_max = ptr->line_nums[i];
1562 if (func_p)
1564 p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>";
1565 len = strlen (p);
1566 if (func_len < len)
1567 func_len = len;
1570 if (file_p)
1572 p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>";
1573 len = strlen (p);
1574 if (file_len < len)
1575 file_len = len;
1579 addr_len = num_digits (addr_max, 16);
1580 cnt_len = num_digits (cnt_max, 10);
1581 line_len = num_digits (line_max, 10);
1583 /* Now print out the basic block information. */
1584 for (i = 0; i < ncounts; i++)
1586 fprintf (file,
1587 " Block #%*d: executed %*ld time(s) address= 0x%.*lx",
1588 blk_len, i+1,
1589 cnt_len, ptr->counts[i],
1590 addr_len, ptr->addresses[i]);
1592 if (func_p)
1593 fprintf (file, " function= %-*s", func_len,
1594 (ptr->functions[i]) ? ptr->functions[i] : "<none>");
1596 if (line_p)
1597 fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]);
1599 if (file_p)
1600 fprintf (file, " file= %s",
1601 (ptr->filenames[i]) ? ptr->filenames[i] : "<none>");
1603 fprintf (file, "\n");
1606 fprintf (file, "\n");
1607 fflush (file);
1610 fprintf (file, "\n\n");
1611 fclose (file);
1615 void
1616 __bb_init_func (struct bb *blocks)
1618 /* User is supposed to check whether the first word is non-0,
1619 but just in case.... */
1621 if (blocks->zero_word)
1622 return;
1624 #ifdef ON_EXIT
1625 /* Initialize destructor. */
1626 if (!bb_head)
1627 ON_EXIT (__bb_exit_func, 0);
1628 #endif
1630 /* Set up linked list. */
1631 blocks->zero_word = 1;
1632 blocks->next = bb_head;
1633 bb_head = blocks;
1636 #ifndef MACHINE_STATE_SAVE
1637 #define MACHINE_STATE_SAVE(ID)
1638 #endif
1639 #ifndef MACHINE_STATE_RESTORE
1640 #define MACHINE_STATE_RESTORE(ID)
1641 #endif
1643 #include <string.h>
1645 /* Number of buckets in hashtable of basic block addresses. */
1647 #define BB_BUCKETS 311
1649 /* Maximum length of string in file bb.in. */
1651 #define BBINBUFSIZE 500
1653 /* BBINBUFSIZE-1 with double quotes. We could use #BBINBUFSIZE or
1654 "BBINBUFSIZE" but want to avoid trouble with preprocessors. */
1656 #define BBINBUFSIZESTR "499"
1658 struct bb_edge
1660 struct bb_edge *next;
1661 unsigned long src_addr;
1662 unsigned long dst_addr;
1663 unsigned long count;
1666 enum bb_func_mode
1668 TRACE_KEEP = 0, TRACE_ON = 1, TRACE_OFF = 2
1671 struct bb_func
1673 struct bb_func *next;
1674 char *funcname;
1675 char *filename;
1676 enum bb_func_mode mode;
1679 /* This is the connection to the outside world.
1680 The BLOCK_PROFILER macro must set __bb.blocks
1681 and __bb.blockno. */
1683 struct {
1684 unsigned long blockno;
1685 struct bb *blocks;
1686 } __bb;
1688 /* Vars to store addrs of source and destination basic blocks
1689 of a jump. */
1691 static unsigned long bb_src = 0;
1692 static unsigned long bb_dst = 0;
1694 static FILE *bb_tracefile = (FILE*)0;
1695 static struct bb_edge **bb_hashbuckets = (struct bb_edge**)0;
1696 static struct bb_func *bb_func_head = (struct bb_func*)0;
1697 static unsigned long bb_callcount = 0;
1698 static int bb_mode = 0;
1700 static unsigned long *bb_stack = (unsigned long *)0;
1701 static size_t bb_stacksize = 0;
1703 static int reported = 0;
1705 /* Trace modes:
1706 Always : Print execution frequencies of basic blocks
1707 to file bb.out.
1708 bb_mode & 1 != 0 : Dump trace of basic blocks to file bbtrace[.gz]
1709 bb_mode & 2 != 0 : Print jump frequencies to file bb.out.
1710 bb_mode & 4 != 0 : Cut call instructions from basic block flow.
1711 bb_mode & 8 != 0 : Insert return instructions in basic block flow.
1714 #ifdef HAVE_POPEN
1716 /*#include <sys/types.h>*/
1717 #include <sys/stat.h>
1718 /*#include <malloc.h>*/
1720 /* Commands executed by gopen. */
1722 #define GOPENDECOMPRESS "gzip -cd "
1723 #define GOPENCOMPRESS "gzip -c >"
1725 /* Like fopen but pipes through gzip. mode may only be "r" or "w".
1726 If it does not compile, simply replace gopen by fopen and delete
1727 '.gz' from any first parameter to gopen. */
1729 static FILE *
1730 gopen (fn, mode)
1731 char *fn;
1732 char *mode;
1734 int use_gzip;
1735 char *p;
1737 if (mode[1])
1738 return (FILE*)0;
1740 if (mode[0] != 'r' && mode[0] != 'w')
1741 return (FILE*)0;
1743 p = fn + strlen (fn)-1;
1744 use_gzip = ((p[-1] == '.' && (p[0] == 'Z' || p[0] == 'z')) ||
1745 (p[-2] == '.' && p[-1] == 'g' && p[0] == 'z'));
1747 if (use_gzip)
1749 if (mode[0]=='r')
1751 FILE *f;
1752 char *s = (char*) malloc (sizeof (char) * strlen (fn)
1753 + sizeof (GOPENDECOMPRESS));
1754 strcpy (s, GOPENDECOMPRESS);
1755 strcpy (s + (sizeof (GOPENDECOMPRESS)-1), fn);
1756 f = popen (s, mode);
1757 free (s);
1758 return f;
1761 else
1763 FILE *f;
1764 char *s = (char*) malloc (sizeof (char) * strlen (fn)
1765 + sizeof (GOPENCOMPRESS));
1766 strcpy (s, GOPENCOMPRESS);
1767 strcpy (s + (sizeof (GOPENCOMPRESS)-1), fn);
1768 if (!(f = popen (s, mode)))
1769 f = fopen (s, mode);
1770 free (s);
1771 return f;
1775 else
1776 return fopen (fn, mode);
1779 static int
1780 gclose (f)
1781 FILE *f;
1783 struct stat buf;
1785 if (f != NULL)
1787 if (!fstat (fileno (f), &buf) && S_ISFIFO (buf.st_mode))
1788 return pclose (f);
1790 return fclose (f);
1792 return 0;
1795 #endif /* HAVE_POPEN */
1797 /* Called once per program. */
1799 static void
1800 __bb_exit_trace_func ()
1802 FILE *file = fopen ("bb.out", "a");
1803 struct bb_func *f;
1804 struct bb_edge *e;
1805 struct bb *b;
1807 if (!file)
1808 perror ("bb.out");
1810 if (bb_mode & 1)
1812 if (!bb_tracefile)
1813 perror ("bbtrace");
1814 else
1815 #ifdef HAVE_POPEN
1816 gclose (bb_tracefile);
1817 #else
1818 fclose (bb_tracefile);
1819 #endif /* HAVE_POPEN */
1822 /* Check functions in `bb.in'. */
1824 if (file)
1826 long time_value;
1827 const struct bb_func *p;
1828 int printed_something = 0;
1829 struct bb *ptr;
1830 long blk;
1832 /* This is somewhat type incorrect. */
1833 time ((void *) &time_value);
1835 for (p = bb_func_head; p != (struct bb_func *)0; p = p->next)
1837 for (ptr = bb_head; ptr != (struct bb *)0; ptr = ptr->next)
1839 if (!ptr->filename || p->filename != (char *)0 && strcmp (p->filename, ptr->filename))
1840 continue;
1841 for (blk = 0; blk < ptr->ncounts; blk++)
1843 if (!strcmp (p->funcname, ptr->functions[blk]))
1844 goto found;
1848 if (!printed_something)
1850 fprintf (file, "Functions in `bb.in' not executed during basic block profiling on %s\n", ctime ((void *) &time_value));
1851 printed_something = 1;
1854 fprintf (file, "\tFunction %s", p->funcname);
1855 if (p->filename)
1856 fprintf (file, " of file %s", p->filename);
1857 fprintf (file, "\n" );
1859 found: ;
1862 if (printed_something)
1863 fprintf (file, "\n");
1867 if (bb_mode & 2)
1869 if (!bb_hashbuckets)
1871 if (!reported)
1873 fprintf (stderr, "Profiler: out of memory\n");
1874 reported = 1;
1876 return;
1879 else if (file)
1881 long time_value;
1882 int i;
1883 unsigned long addr_max = 0;
1884 unsigned long cnt_max = 0;
1885 int cnt_len;
1886 int addr_len;
1888 /* This is somewhat type incorrect, but it avoids worrying about
1889 exactly where time.h is included from. It should be ok unless
1890 a void * differs from other pointer formats, or if sizeof (long)
1891 is < sizeof (time_t). It would be nice if we could assume the
1892 use of rationale standards here. */
1894 time ((void *) &time_value);
1895 fprintf (file, "Basic block jump tracing");
1897 switch (bb_mode & 12)
1899 case 0:
1900 fprintf (file, " (with call)");
1901 break;
1903 case 4:
1904 /* Print nothing. */
1905 break;
1907 case 8:
1908 fprintf (file, " (with call & ret)");
1909 break;
1911 case 12:
1912 fprintf (file, " (with ret)");
1913 break;
1916 fprintf (file, " finished on %s\n", ctime ((void *) &time_value));
1918 for (i = 0; i < BB_BUCKETS; i++)
1920 struct bb_edge *bucket = bb_hashbuckets[i];
1921 for ( ; bucket; bucket = bucket->next )
1923 if (addr_max < bucket->src_addr)
1924 addr_max = bucket->src_addr;
1925 if (addr_max < bucket->dst_addr)
1926 addr_max = bucket->dst_addr;
1927 if (cnt_max < bucket->count)
1928 cnt_max = bucket->count;
1931 addr_len = num_digits (addr_max, 16);
1932 cnt_len = num_digits (cnt_max, 10);
1934 for ( i = 0; i < BB_BUCKETS; i++)
1936 struct bb_edge *bucket = bb_hashbuckets[i];
1937 for ( ; bucket; bucket = bucket->next )
1939 fprintf (file, "Jump from block 0x%.*lx to "
1940 "block 0x%.*lx executed %*d time(s)\n",
1941 addr_len, bucket->src_addr,
1942 addr_len, bucket->dst_addr,
1943 cnt_len, bucket->count);
1947 fprintf (file, "\n");
1952 if (file)
1953 fclose (file);
1955 /* Free allocated memory. */
1957 f = bb_func_head;
1958 while (f)
1960 struct bb_func *old = f;
1962 f = f->next;
1963 if (old->funcname) free (old->funcname);
1964 if (old->filename) free (old->filename);
1965 free (old);
1968 if (bb_stack)
1969 free (bb_stack);
1971 if (bb_hashbuckets)
1973 int i;
1975 for (i = 0; i < BB_BUCKETS; i++)
1977 struct bb_edge *old, *bucket = bb_hashbuckets[i];
1979 while (bucket)
1981 old = bucket;
1982 bucket = bucket->next;
1983 free (old);
1986 free (bb_hashbuckets);
1989 for (b = bb_head; b; b = b->next)
1990 if (b->flags) free (b->flags);
1993 /* Called once per program. */
1995 static void
1996 __bb_init_prg ()
1999 FILE *file;
2000 char buf[BBINBUFSIZE];
2001 const char *p;
2002 const char *pos;
2003 enum bb_func_mode m;
2005 #ifdef ON_EXIT
2006 /* Initialize destructor. */
2007 ON_EXIT (__bb_exit_func, 0);
2008 #endif
2010 if (!(file = fopen ("bb.in", "r")))
2011 return;
2013 while(fscanf (file, " %" BBINBUFSIZESTR "s ", buf) != EOF)
2015 p = buf;
2016 if (*p == '-')
2018 m = TRACE_OFF;
2019 p++;
2021 else
2023 m = TRACE_ON;
2025 if (!strcmp (p, "__bb_trace__"))
2026 bb_mode |= 1;
2027 else if (!strcmp (p, "__bb_jumps__"))
2028 bb_mode |= 2;
2029 else if (!strcmp (p, "__bb_hidecall__"))
2030 bb_mode |= 4;
2031 else if (!strcmp (p, "__bb_showret__"))
2032 bb_mode |= 8;
2033 else
2035 struct bb_func *f = (struct bb_func*) malloc (sizeof (struct bb_func));
2036 if (f)
2038 unsigned long l;
2039 f->next = bb_func_head;
2040 if (pos = strchr (p, ':'))
2042 if (!(f->funcname = (char*) malloc (strlen (pos+1)+1)))
2043 continue;
2044 strcpy (f->funcname, pos+1);
2045 l = pos-p;
2046 if ((f->filename = (char*) malloc (l+1)))
2048 strncpy (f->filename, p, l);
2049 f->filename[l] = '\0';
2051 else
2052 f->filename = (char*)0;
2054 else
2056 if (!(f->funcname = (char*) malloc (strlen (p)+1)))
2057 continue;
2058 strcpy (f->funcname, p);
2059 f->filename = (char*)0;
2061 f->mode = m;
2062 bb_func_head = f;
2066 fclose (file);
2068 #ifdef HAVE_POPEN
2070 if (bb_mode & 1)
2071 bb_tracefile = gopen ("bbtrace.gz", "w");
2073 #else
2075 if (bb_mode & 1)
2076 bb_tracefile = fopen ("bbtrace", "w");
2078 #endif /* HAVE_POPEN */
2080 if (bb_mode & 2)
2082 bb_hashbuckets = (struct bb_edge **)
2083 malloc (BB_BUCKETS * sizeof (struct bb_edge *));
2084 if (bb_hashbuckets)
2085 bzero ((char *) bb_hashbuckets, BB_BUCKETS);
2088 if (bb_mode & 12)
2090 bb_stacksize = 10;
2091 bb_stack = (unsigned long *) malloc (bb_stacksize * sizeof (*bb_stack));
2094 #ifdef ON_EXIT
2095 /* Initialize destructor. */
2096 ON_EXIT (__bb_exit_trace_func, 0);
2097 #endif
2101 /* Called upon entering a basic block. */
2103 void
2104 __bb_trace_func ()
2106 struct bb_edge *bucket;
2108 MACHINE_STATE_SAVE("1")
2110 if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2111 goto skip;
2113 bb_dst = __bb.blocks->addresses[__bb.blockno];
2114 __bb.blocks->counts[__bb.blockno]++;
2116 if (bb_tracefile)
2118 fwrite (&bb_dst, sizeof (unsigned long), 1, bb_tracefile);
2121 if (bb_hashbuckets)
2123 struct bb_edge **startbucket, **oldnext;
2125 oldnext = startbucket =
2126 & bb_hashbuckets[ (((int)bb_src*8)^(int)bb_dst) % BB_BUCKETS ];
2127 bucket = *startbucket;
2129 for (bucket = *startbucket; bucket;
2130 oldnext = &(bucket->next), bucket = *oldnext)
2132 if ( bucket->src_addr == bb_src &&
2133 bucket->dst_addr == bb_dst )
2135 bucket->count++;
2136 *oldnext = bucket->next;
2137 bucket->next = *startbucket;
2138 *startbucket = bucket;
2139 goto ret;
2143 bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2145 if (!bucket)
2147 if (!reported)
2149 fprintf (stderr, "Profiler: out of memory\n");
2150 reported = 1;
2154 else
2156 bucket->src_addr = bb_src;
2157 bucket->dst_addr = bb_dst;
2158 bucket->next = *startbucket;
2159 *startbucket = bucket;
2160 bucket->count = 1;
2164 ret:
2165 bb_src = bb_dst;
2167 skip:
2170 MACHINE_STATE_RESTORE("1")
2174 /* Called when returning from a function and `__bb_showret__' is set. */
2176 static void
2177 __bb_trace_func_ret ()
2179 struct bb_edge *bucket;
2181 if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2182 goto skip;
2184 if (bb_hashbuckets)
2186 struct bb_edge **startbucket, **oldnext;
2188 oldnext = startbucket =
2189 & bb_hashbuckets[ (((int)bb_dst*8)^(int)bb_src) % BB_BUCKETS ];
2190 bucket = *startbucket;
2192 for (bucket = *startbucket; bucket;
2193 oldnext = &(bucket->next), bucket = *oldnext)
2195 if ( bucket->src_addr == bb_dst &&
2196 bucket->dst_addr == bb_src )
2198 bucket->count++;
2199 *oldnext = bucket->next;
2200 bucket->next = *startbucket;
2201 *startbucket = bucket;
2202 goto ret;
2206 bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2208 if (!bucket)
2210 if (!reported)
2212 fprintf (stderr, "Profiler: out of memory\n");
2213 reported = 1;
2217 else
2219 bucket->src_addr = bb_dst;
2220 bucket->dst_addr = bb_src;
2221 bucket->next = *startbucket;
2222 *startbucket = bucket;
2223 bucket->count = 1;
2227 ret:
2228 bb_dst = bb_src;
2230 skip:
2235 /* Called upon entering the first function of a file. */
2237 static void
2238 __bb_init_file (blocks)
2239 struct bb *blocks;
2242 const struct bb_func *p;
2243 long blk, ncounts = blocks->ncounts;
2244 const char **functions = blocks->functions;
2246 /* Set up linked list. */
2247 blocks->zero_word = 1;
2248 blocks->next = bb_head;
2249 bb_head = blocks;
2251 blocks->flags = 0;
2252 if (!bb_func_head ||
2253 !(blocks->flags = (char*) malloc (sizeof (char) * blocks->ncounts)))
2254 return;
2256 for (blk = 0; blk < ncounts; blk++)
2257 blocks->flags[blk] = 0;
2259 for (blk = 0; blk < ncounts; blk++)
2261 for (p = bb_func_head; p; p = p->next)
2263 if (!strcmp (p->funcname, functions[blk]) &&
2264 (!p->filename || !strcmp (p->filename, blocks->filename)))
2266 blocks->flags[blk] |= p->mode;
2273 /* Called when exiting from a function. */
2275 void
2276 __bb_trace_ret ()
2279 MACHINE_STATE_SAVE("2")
2281 if (bb_callcount)
2283 if ((bb_mode & 12) && bb_stacksize > bb_callcount)
2285 bb_src = bb_stack[bb_callcount];
2286 if (bb_mode & 8)
2287 __bb_trace_func_ret ();
2290 bb_callcount -= 1;
2293 MACHINE_STATE_RESTORE("2")
2297 /* Called when entering a function. */
2299 void
2300 __bb_init_trace_func (blocks, blockno)
2301 struct bb *blocks;
2302 unsigned long blockno;
2304 static int trace_init = 0;
2306 MACHINE_STATE_SAVE("3")
2308 if (!blocks->zero_word)
2310 if (!trace_init)
2312 trace_init = 1;
2313 __bb_init_prg ();
2315 __bb_init_file (blocks);
2318 if (bb_callcount)
2321 bb_callcount += 1;
2323 if (bb_mode & 12)
2325 if (bb_callcount >= bb_stacksize)
2327 size_t newsize = bb_callcount + 100;
2329 bb_stack = (unsigned long *) realloc (bb_stack, newsize);
2330 if (! bb_stack)
2332 if (!reported)
2334 fprintf (stderr, "Profiler: out of memory\n");
2335 reported = 1;
2337 bb_stacksize = 0;
2338 goto stack_overflow;
2340 bb_stacksize = newsize;
2342 bb_stack[bb_callcount] = bb_src;
2344 if (bb_mode & 4)
2345 bb_src = 0;
2349 stack_overflow:;
2353 else if (blocks->flags && (blocks->flags[blockno] & TRACE_ON))
2355 bb_callcount = 1;
2356 bb_src = 0;
2358 if (bb_stack)
2359 bb_stack[bb_callcount] = bb_src;
2362 MACHINE_STATE_RESTORE("3")
2365 #endif /* not inhibit_libc */
2366 #endif /* not BLOCK_PROFILER_CODE */
2367 #endif /* L_bb */
2369 /* Default free-store management functions for C++, per sections 12.5 and
2370 17.3.3 of the Working Paper. */
2372 #ifdef L_op_new
2373 /* operator new (size_t), described in 17.3.3.5. This function is used by
2374 C++ programs to allocate a block of memory to hold a single object. */
2376 typedef void (*vfp)(void);
2377 extern vfp __new_handler;
2378 extern void __default_new_handler (void);
2380 #ifdef WEAK_ALIAS
2381 void * __builtin_new (size_t sz)
2382 __attribute__ ((weak, alias ("___builtin_new")));
2383 void *
2384 ___builtin_new (size_t sz)
2385 #else
2386 void *
2387 __builtin_new (size_t sz)
2388 #endif
2390 void *p;
2391 vfp handler = (__new_handler) ? __new_handler : __default_new_handler;
2393 /* malloc (0) is unpredictable; avoid it. */
2394 if (sz == 0)
2395 sz = 1;
2396 p = (void *) malloc (sz);
2397 while (p == 0)
2399 (*handler) ();
2400 p = (void *) malloc (sz);
2403 return p;
2405 #endif /* L_op_new */
2407 #ifdef L_op_vnew
2408 /* void * operator new [] (size_t), described in 17.3.3.6. This function
2409 is used by C++ programs to allocate a block of memory for an array. */
2411 extern void * __builtin_new (size_t);
2413 #ifdef WEAK_ALIAS
2414 void * __builtin_vec_new (size_t sz)
2415 __attribute__ ((weak, alias ("___builtin_vec_new")));
2416 void *
2417 ___builtin_vec_new (size_t sz)
2418 #else
2419 void *
2420 __builtin_vec_new (size_t sz)
2421 #endif
2423 return __builtin_new (sz);
2425 #endif /* L_op_vnew */
2427 #ifdef L_new_handler
2428 /* set_new_handler (fvoid_t *) and the default new handler, described in
2429 17.3.3.2 and 17.3.3.5. These functions define the result of a failure
2430 to allocate the amount of memory requested from operator new or new []. */
2432 #ifndef inhibit_libc
2433 /* This gets us __GNU_LIBRARY__. */
2434 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2435 #include <stdio.h>
2437 #ifdef __GNU_LIBRARY__
2438 /* Avoid forcing the library's meaning of `write' on the user program
2439 by using the "internal" name (for use within the library) */
2440 #define write(fd, buf, n) __write((fd), (buf), (n))
2441 #endif
2442 #endif /* inhibit_libc */
2444 typedef void (*vfp)(void);
2445 void __default_new_handler (void);
2447 vfp __new_handler = (vfp)0;
2450 set_new_handler (vfp handler)
2452 vfp prev_handler;
2454 prev_handler = __new_handler;
2455 if (handler == 0) handler = __default_new_handler;
2456 __new_handler = handler;
2457 return prev_handler;
2460 #define MESSAGE "Virtual memory exceeded in `new'\n"
2462 void
2463 __default_new_handler ()
2465 #ifndef inhibit_libc
2466 /* don't use fprintf (stderr, ...) because it may need to call malloc. */
2467 /* This should really print the name of the program, but that is hard to
2468 do. We need a standard, clean way to get at the name. */
2469 write (2, MESSAGE, sizeof (MESSAGE));
2470 #endif
2471 /* don't call exit () because that may call global destructors which
2472 may cause a loop. */
2473 _exit (-1);
2475 #endif
2477 #ifdef L_op_delete
2478 /* operator delete (void *), described in 17.3.3.3. This function is used
2479 by C++ programs to return to the free store a block of memory allocated
2480 as a single object. */
2482 #ifdef WEAK_ALIAS
2483 void __builtin_delete (void *ptr)
2484 __attribute__ ((weak, alias ("___builtin_delete")));
2485 void
2486 ___builtin_delete (void *ptr)
2487 #else
2488 void
2489 __builtin_delete (void *ptr)
2490 #endif
2492 if (ptr)
2493 free (ptr);
2495 #endif
2497 #ifdef L_op_vdel
2498 /* operator delete [] (void *), described in 17.3.3.4. This function is
2499 used by C++ programs to return to the free store a block of memory
2500 allocated as an array. */
2502 extern void __builtin_delete (void *);
2504 #ifdef WEAK_ALIAS
2505 void __builtin_vec_delete (void *ptr)
2506 __attribute__ ((weak, alias ("___builtin_vec_delete")));
2507 void
2508 ___builtin_vec_delete (void *ptr)
2509 #else
2510 void
2511 __builtin_vec_delete (void *ptr)
2512 #endif
2514 __builtin_delete (ptr);
2516 #endif
2518 /* End of C++ free-store management functions */
2520 #ifdef L_shtab
2521 unsigned int __shtab[] = {
2522 0x00000001, 0x00000002, 0x00000004, 0x00000008,
2523 0x00000010, 0x00000020, 0x00000040, 0x00000080,
2524 0x00000100, 0x00000200, 0x00000400, 0x00000800,
2525 0x00001000, 0x00002000, 0x00004000, 0x00008000,
2526 0x00010000, 0x00020000, 0x00040000, 0x00080000,
2527 0x00100000, 0x00200000, 0x00400000, 0x00800000,
2528 0x01000000, 0x02000000, 0x04000000, 0x08000000,
2529 0x10000000, 0x20000000, 0x40000000, 0x80000000
2531 #endif
2533 #ifdef L_clear_cache
2534 /* Clear part of an instruction cache. */
2536 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
2538 void
2539 __clear_cache (beg, end)
2540 char *beg, *end;
2542 #ifdef CLEAR_INSN_CACHE
2543 CLEAR_INSN_CACHE (beg, end);
2544 #else
2545 #ifdef INSN_CACHE_SIZE
2546 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
2547 static int initialized;
2548 int offset;
2549 void *start_addr
2550 void *end_addr;
2551 typedef (*function_ptr) ();
2553 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
2554 /* It's cheaper to clear the whole cache.
2555 Put in a series of jump instructions so that calling the beginning
2556 of the cache will clear the whole thing. */
2558 if (! initialized)
2560 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2561 & -INSN_CACHE_LINE_WIDTH);
2562 int end_ptr = ptr + INSN_CACHE_SIZE;
2564 while (ptr < end_ptr)
2566 *(INSTRUCTION_TYPE *)ptr
2567 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
2568 ptr += INSN_CACHE_LINE_WIDTH;
2570 *(INSTRUCTION_TYPE *)(ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
2572 initialized = 1;
2575 /* Call the beginning of the sequence. */
2576 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2577 & -INSN_CACHE_LINE_WIDTH))
2578 ());
2580 #else /* Cache is large. */
2582 if (! initialized)
2584 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2585 & -INSN_CACHE_LINE_WIDTH);
2587 while (ptr < (int) array + sizeof array)
2589 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
2590 ptr += INSN_CACHE_LINE_WIDTH;
2593 initialized = 1;
2596 /* Find the location in array that occupies the same cache line as BEG. */
2598 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
2599 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
2600 & -INSN_CACHE_PLANE_SIZE)
2601 + offset);
2603 /* Compute the cache alignment of the place to stop clearing. */
2604 #if 0 /* This is not needed for gcc's purposes. */
2605 /* If the block to clear is bigger than a cache plane,
2606 we clear the entire cache, and OFFSET is already correct. */
2607 if (end < beg + INSN_CACHE_PLANE_SIZE)
2608 #endif
2609 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
2610 & -INSN_CACHE_LINE_WIDTH)
2611 & (INSN_CACHE_PLANE_SIZE - 1));
2613 #if INSN_CACHE_DEPTH > 1
2614 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
2615 if (end_addr <= start_addr)
2616 end_addr += INSN_CACHE_PLANE_SIZE;
2618 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
2620 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
2621 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
2623 while (addr != stop)
2625 /* Call the return instruction at ADDR. */
2626 ((function_ptr) addr) ();
2628 addr += INSN_CACHE_LINE_WIDTH;
2631 #else /* just one plane */
2634 /* Call the return instruction at START_ADDR. */
2635 ((function_ptr) start_addr) ();
2637 start_addr += INSN_CACHE_LINE_WIDTH;
2639 while ((start_addr % INSN_CACHE_SIZE) != offset);
2640 #endif /* just one plane */
2641 #endif /* Cache is large */
2642 #endif /* Cache exists */
2643 #endif /* CLEAR_INSN_CACHE */
2646 #endif /* L_clear_cache */
2648 #ifdef L_trampoline
2650 /* Jump to a trampoline, loading the static chain address. */
2652 #ifdef WINNT
2654 long getpagesize()
2656 #ifdef _ALPHA_
2657 return 8192;
2658 #else
2659 return 4096;
2660 #endif
2663 int mprotect(addr, len, prot)
2664 char *addr;
2665 int len, prot;
2667 int np, op;
2669 if (prot == 7) np = 0x40;
2670 else if (prot == 5) np = 0x20;
2671 else if (prot == 4) np = 0x10;
2672 else if (prot == 3) np = 0x04;
2673 else if (prot == 1) np = 0x02;
2674 else if (prot == 0) np = 0x01;
2676 if (VirtualProtect (addr, len, np, &op))
2677 return 0;
2678 else
2679 return -1;
2683 #endif
2685 #ifdef TRANSFER_FROM_TRAMPOLINE
2686 TRANSFER_FROM_TRAMPOLINE
2687 #endif
2689 #if defined (NeXT) && defined (__MACH__)
2691 /* Make stack executable so we can call trampolines on stack.
2692 This is called from INITIALIZE_TRAMPOLINE in next.h. */
2693 #ifdef NeXTStep21
2694 #include <mach.h>
2695 #else
2696 #include <mach/mach.h>
2697 #endif
2699 void
2700 __enable_execute_stack (addr)
2701 char *addr;
2703 kern_return_t r;
2704 char *eaddr = addr + TRAMPOLINE_SIZE;
2705 vm_address_t a = (vm_address_t) addr;
2707 /* turn on execute access on stack */
2708 r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
2709 if (r != KERN_SUCCESS)
2711 mach_error("vm_protect VM_PROT_ALL", r);
2712 exit(1);
2715 /* We inline the i-cache invalidation for speed */
2717 #ifdef CLEAR_INSN_CACHE
2718 CLEAR_INSN_CACHE (addr, eaddr);
2719 #else
2720 __clear_cache ((int) addr, (int) eaddr);
2721 #endif
2724 #endif /* defined (NeXT) && defined (__MACH__) */
2726 #ifdef __convex__
2728 /* Make stack executable so we can call trampolines on stack.
2729 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
2731 #include <sys/mman.h>
2732 #include <sys/vmparam.h>
2733 #include <machine/machparam.h>
2735 void
2736 __enable_execute_stack ()
2738 int fp;
2739 static unsigned lowest = USRSTACK;
2740 unsigned current = (unsigned) &fp & -NBPG;
2742 if (lowest > current)
2744 unsigned len = lowest - current;
2745 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
2746 lowest = current;
2749 /* Clear instruction cache in case an old trampoline is in it. */
2750 asm ("pich");
2752 #endif /* __convex__ */
2754 #ifdef __DOLPHIN__
2756 /* Modified from the convex -code above. */
2758 #include <sys/param.h>
2759 #include <errno.h>
2760 #include <sys/m88kbcs.h>
2762 void
2763 __enable_execute_stack ()
2765 int save_errno;
2766 static unsigned long lowest = USRSTACK;
2767 unsigned long current = (unsigned long) &save_errno & -NBPC;
2769 /* Ignore errno being set. memctl sets errno to EINVAL whenever the
2770 address is seen as 'negative'. That is the case with the stack. */
2772 save_errno=errno;
2773 if (lowest > current)
2775 unsigned len=lowest-current;
2776 memctl(current,len,MCT_TEXT);
2777 lowest = current;
2779 else
2780 memctl(current,NBPC,MCT_TEXT);
2781 errno=save_errno;
2784 #endif /* __DOLPHIN__ */
2786 #ifdef __pyr__
2788 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2789 #include <stdio.h>
2790 #include <sys/mman.h>
2791 #include <sys/types.h>
2792 #include <sys/param.h>
2793 #include <sys/vmmac.h>
2795 /* Modified from the convex -code above.
2796 mremap promises to clear the i-cache. */
2798 void
2799 __enable_execute_stack ()
2801 int fp;
2802 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
2803 PROT_READ|PROT_WRITE|PROT_EXEC))
2805 perror ("mprotect in __enable_execute_stack");
2806 fflush (stderr);
2807 abort ();
2810 #endif /* __pyr__ */
2811 #endif /* L_trampoline */
2813 #ifdef L__main
2815 #include "gbl-ctors.h"
2816 /* Some systems use __main in a way incompatible with its use in gcc, in these
2817 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2818 give the same symbol without quotes for an alternative entry point. You
2819 must define both, or neither. */
2820 #ifndef NAME__MAIN
2821 #define NAME__MAIN "__main"
2822 #define SYMBOL__MAIN __main
2823 #endif
2825 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2826 /* Run all the global destructors on exit from the program. */
2828 void
2829 __do_global_dtors ()
2831 #ifdef DO_GLOBAL_DTORS_BODY
2832 DO_GLOBAL_DTORS_BODY;
2833 #else
2834 func_ptr *p;
2835 for (p = __DTOR_LIST__ + 1; *p; )
2836 (*p++) ();
2837 #endif
2839 #endif
2841 #ifndef INIT_SECTION_ASM_OP
2842 /* Run all the global constructors on entry to the program. */
2844 #ifndef ON_EXIT
2845 #define ON_EXIT(a, b)
2846 #else
2847 /* Make sure the exit routine is pulled in to define the globals as
2848 bss symbols, just in case the linker does not automatically pull
2849 bss definitions from the library. */
2851 extern int _exit_dummy_decl;
2852 int *_exit_dummy_ref = &_exit_dummy_decl;
2853 #endif /* ON_EXIT */
2855 void
2856 __do_global_ctors ()
2858 DO_GLOBAL_CTORS_BODY;
2859 ON_EXIT (__do_global_dtors, 0);
2861 #endif /* no INIT_SECTION_ASM_OP */
2863 #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
2864 /* Subroutine called automatically by `main'.
2865 Compiling a global function named `main'
2866 produces an automatic call to this function at the beginning.
2868 For many systems, this routine calls __do_global_ctors.
2869 For systems which support a .init section we use the .init section
2870 to run __do_global_ctors, so we need not do anything here. */
2872 void
2873 SYMBOL__MAIN ()
2875 /* Support recursive calls to `main': run initializers just once. */
2876 static int initialized;
2877 if (! initialized)
2879 initialized = 1;
2880 __do_global_ctors ();
2883 #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
2885 #endif /* L__main */
2887 #ifdef L_ctors
2889 #include "gbl-ctors.h"
2891 /* Provide default definitions for the lists of constructors and
2892 destructors, so that we don't get linker errors. These symbols are
2893 intentionally bss symbols, so that gld and/or collect will provide
2894 the right values. */
2896 /* We declare the lists here with two elements each,
2897 so that they are valid empty lists if no other definition is loaded. */
2898 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
2899 #if defined(__NeXT__) || defined(_AIX)
2900 /* After 2.3, try this definition on all systems. */
2901 func_ptr __CTOR_LIST__[2] = {0, 0};
2902 func_ptr __DTOR_LIST__[2] = {0, 0};
2903 #else
2904 func_ptr __CTOR_LIST__[2];
2905 func_ptr __DTOR_LIST__[2];
2906 #endif
2907 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
2908 #endif /* L_ctors */
2910 #ifdef L_exit
2912 #include "gbl-ctors.h"
2914 #ifndef ON_EXIT
2916 /* If we have no known way of registering our own __do_global_dtors
2917 routine so that it will be invoked at program exit time, then we
2918 have to define our own exit routine which will get this to happen. */
2920 extern void __do_global_dtors ();
2921 extern void _cleanup ();
2922 extern void _exit () __attribute__ ((noreturn));
2924 void
2925 exit (status)
2926 int status;
2928 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2929 __do_global_dtors ();
2930 #endif
2931 #ifdef EXIT_BODY
2932 EXIT_BODY;
2933 #else
2934 _cleanup ();
2935 #endif
2936 _exit (status);
2939 #else
2940 int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */
2941 #endif
2943 #endif /* L_exit */
2945 #ifdef L_eh
2946 typedef struct {
2947 void *start;
2948 void *end;
2949 void *exception_handler;
2950 } exception_table;
2952 struct exception_table_node {
2953 exception_table *table;
2954 void *start;
2955 void *end;
2956 struct exception_table_node *next;
2959 static int except_table_pos;
2960 static void *except_pc;
2961 static struct exception_table_node *exception_table_list;
2963 static exception_table *
2964 find_exception_table (pc)
2965 void* pc;
2967 register struct exception_table_node *table = exception_table_list;
2968 for ( ; table != 0; table = table->next)
2970 if (table->start <= pc && table->end > pc)
2971 return table->table;
2973 return 0;
2976 /* this routine takes a pc, and the address of the exception handler associated
2977 with the closest exception table handler entry associated with that PC,
2978 or 0 if there are no table entries the PC fits in. The algorithm works
2979 something like this:
2981 while(current_entry exists) {
2982 if(current_entry.start < pc )
2983 current_entry = next_entry;
2984 else {
2985 if(prev_entry.start <= pc && prev_entry.end > pc) {
2986 save pointer to prev_entry;
2987 return prev_entry.exception_handler;
2989 else return 0;
2992 return 0;
2994 Assuming a correctly sorted table (ascending order) this routine should
2995 return the tightest match...
2997 In the advent of a tie, we have to give the last entry, as it represents
2998 an inner block.
3002 void *
3003 __find_first_exception_table_match(pc)
3004 void *pc;
3006 exception_table *table = find_exception_table (pc);
3007 int pos = 0;
3008 int best = 0;
3009 if (table == 0)
3010 return (void*)0;
3011 #if 0
3012 printf("find_first_exception_table_match(): pc = %x!\n",pc);
3013 #endif
3015 except_pc = pc;
3017 #if 0
3018 /* We can't do this yet, as we don't know that the table is sorted. */
3019 do {
3020 ++pos;
3021 if (table[pos].start > except_pc)
3022 /* found the first table[pos].start > except_pc, so the previous
3023 entry better be the one we want! */
3024 break;
3025 } while(table[pos].exception_handler != (void*)-1);
3027 --pos;
3028 if (table[pos].start <= except_pc && table[pos].end > except_pc)
3030 except_table_pos = pos;
3031 #if 0
3032 printf("find_first_eh_table_match(): found match: %x\n",table[pos].exception_handler);
3033 #endif
3034 return table[pos].exception_handler;
3036 #else
3037 while (table[++pos].exception_handler != (void*)-1) {
3038 if (table[pos].start <= except_pc && table[pos].end > except_pc)
3040 /* This can apply. Make sure it is better or as good as the previous
3041 best. */
3042 /* The best one ends first. */
3043 if (best == 0 || (table[pos].end <= table[best].end
3044 /* The best one starts last. */
3045 && table[pos].start >= table[best].start))
3046 best = pos;
3049 if (best != 0)
3050 return table[best].exception_handler;
3051 #endif
3053 #if 0
3054 printf("find_first_eh_table_match(): else: returning NULL!\n");
3055 #endif
3056 return (void*)0;
3059 void *
3060 __throw_type_match (void *catch_type, void *throw_type, void* obj)
3062 #if 0
3063 printf("__throw_type_match (): catch_type = %s, throw_type = %s\n",
3064 catch_type, throw_type);
3065 #endif
3066 if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)
3067 return obj;
3068 return 0;
3071 void
3072 __register_exceptions (exception_table *table)
3074 struct exception_table_node *node;
3075 exception_table *range = table + 1;
3077 if (range->start == (void*)-1)
3078 return;
3080 node = (struct exception_table_node*)
3081 malloc (sizeof (struct exception_table_node));
3082 node->table = table;
3084 /* This look can be optimized away either if the table
3085 is sorted, or if we pass in extra parameters. */
3086 node->start = range->start;
3087 node->end = range->end;
3088 for (range++ ; range->start != (void*)(-1); range++)
3090 if (range->start < node->start)
3091 node->start = range->start;
3092 if (range->end > node->end)
3093 node->end = range->end;
3096 node->next = exception_table_list;
3097 exception_table_list = node;
3100 void
3101 __empty ()
3105 #if #machine(i386)
3106 void
3107 __unwind_function(void *ptr)
3109 asm("movl 8(%esp),%ecx");
3110 /* Undo current frame */
3111 asm("movl %ebp,%esp");
3112 asm("popl %ebp");
3113 /* like ret, but stay here */
3114 asm("addl $4,%esp");
3116 /* Now, undo previous frame. */
3117 /* This is a test routine, as we have to dynamically probe to find out
3118 what to pop for certain, this is just a guess. */
3119 asm("leal -16(%ebp),%esp");
3120 asm("pop %ebx");
3121 asm("pop %esi");
3122 asm("pop %edi");
3123 asm("movl %ebp,%esp");
3124 asm("popl %ebp");
3126 asm("movl %ecx,0(%esp)");
3127 asm("ret");
3129 #elif #machine(rs6000) && !defined _ARCH_PPC
3130 __unwind_function(void *ptr)
3132 asm("mr 31,1");
3133 asm("l 1,0(1)");
3134 asm("l 31,-4(1)");
3135 asm("# br");
3137 asm("mr 31,1");
3138 asm("l 1,0(1)");
3139 /* use 31 as a scratch register to restore the link register. */
3140 asm("l 31, 8(1);mtlr 31 # l lr,8(1)");
3141 asm("l 31,-4(1)");
3142 asm("# br");
3143 asm("mtctr 3;bctr # b 3");
3145 #elif (#machine(rs6000) || #machine(powerpc)) && defined _ARCH_PPC
3146 __unwind_function(void *ptr)
3148 asm("mr 31,1");
3149 asm("lwz 1,0(1)");
3150 asm("lwz 31,-4(1)");
3151 asm("# br");
3153 asm("mr 31,1");
3154 asm("lwz 1,0(1)");
3155 /* use 31 as a scratch register to restore the link register. */
3156 asm("lwz 31, 8(1);mtlr 31 # l lr,8(1)");
3157 asm("lwz 31,-4(1)");
3158 asm("# br");
3159 asm("mtctr 3;bctr # b 3");
3161 #elif #machine(vax)
3162 __unwind_function(void *ptr)
3164 __label__ return_again;
3166 /* Replace our frame's return address with the label below.
3167 During execution, we will first return here instead of to
3168 caller, then second return takes caller's frame off the stack.
3169 Two returns matches two actual calls, so is less likely to
3170 confuse debuggers. `16' corresponds to RETURN_ADDRESS_OFFSET. */
3171 __asm ("movl %0,16(fp)" : : "p" (&& return_again));
3172 return;
3174 return_again:
3175 return;
3177 #else
3178 __unwind_function(void *ptr)
3180 abort ();
3182 #endif /* powerpc */
3183 #endif /* L_eh */
3185 #ifdef L_pure
3186 #ifndef inhibit_libc
3187 /* This gets us __GNU_LIBRARY__. */
3188 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
3189 #include <stdio.h>
3191 #ifdef __GNU_LIBRARY__
3192 /* Avoid forcing the library's meaning of `write' on the user program
3193 by using the "internal" name (for use within the library) */
3194 #define write(fd, buf, n) __write((fd), (buf), (n))
3195 #endif
3196 #endif /* inhibit_libc */
3198 #define MESSAGE "pure virtual method called\n"
3200 void
3201 __pure_virtual ()
3203 #ifndef inhibit_libc
3204 write (2, MESSAGE, sizeof (MESSAGE) - 1);
3205 #endif
3206 _exit (-1);
3208 #endif