(cacheflush): Add SONY NEWS-OS 4.2 version.
[official-gcc.git] / gcc / libgcc2.c
blob19e1a137f71b1521f46e53debf4a76175ca0cde3
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, 1996 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) || defined (ASM_OUTPUT_WEAK_ALIAS))
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__dummy
1196 void
1197 __dummy () {}
1198 #endif
1200 #ifdef L_varargs
1201 #ifdef __i860__
1202 #if defined(__svr4__) || defined(__alliant__)
1203 asm (" .text");
1204 asm (" .align 4");
1206 /* The Alliant needs the added underscore. */
1207 asm (".globl __builtin_saveregs");
1208 asm ("__builtin_saveregs:");
1209 asm (".globl ___builtin_saveregs");
1210 asm ("___builtin_saveregs:");
1212 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
1213 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
1214 area and also for a new va_list
1215 structure */
1216 /* Save all argument registers in the arg reg save area. The
1217 arg reg save area must have the following layout (according
1218 to the svr4 ABI):
1220 struct {
1221 union {
1222 float freg[8];
1223 double dreg[4];
1224 } float_regs;
1225 long ireg[12];
1229 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
1230 asm (" fst.q %f12,16(%sp)");
1232 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
1233 asm (" st.l %r17,36(%sp)");
1234 asm (" st.l %r18,40(%sp)");
1235 asm (" st.l %r19,44(%sp)");
1236 asm (" st.l %r20,48(%sp)");
1237 asm (" st.l %r21,52(%sp)");
1238 asm (" st.l %r22,56(%sp)");
1239 asm (" st.l %r23,60(%sp)");
1240 asm (" st.l %r24,64(%sp)");
1241 asm (" st.l %r25,68(%sp)");
1242 asm (" st.l %r26,72(%sp)");
1243 asm (" st.l %r27,76(%sp)");
1245 asm (" adds 80,%sp,%r16"); /* compute the address of the new
1246 va_list structure. Put in into
1247 r16 so that it will be returned
1248 to the caller. */
1250 /* Initialize all fields of the new va_list structure. This
1251 structure looks like:
1253 typedef struct {
1254 unsigned long ireg_used;
1255 unsigned long freg_used;
1256 long *reg_base;
1257 long *mem_ptr;
1258 } va_list;
1261 asm (" st.l %r0, 0(%r16)"); /* nfixed */
1262 asm (" st.l %r0, 4(%r16)"); /* nfloating */
1263 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
1264 asm (" bri %r1"); /* delayed return */
1265 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
1267 #else /* not __svr4__ */
1268 #if defined(__PARAGON__)
1270 * we'll use SVR4-ish varargs but need SVR3.2 assembler syntax,
1271 * and we stand a better chance of hooking into libraries
1272 * compiled by PGI. [andyp@ssd.intel.com]
1274 asm (" .text");
1275 asm (" .align 4");
1276 asm (".globl __builtin_saveregs");
1277 asm ("__builtin_saveregs:");
1278 asm (".globl ___builtin_saveregs");
1279 asm ("___builtin_saveregs:");
1281 asm (" andnot 0x0f,sp,sp"); /* round down to 16-byte boundary */
1282 asm (" adds -96,sp,sp"); /* allocate stack space for reg save
1283 area and also for a new va_list
1284 structure */
1285 /* Save all argument registers in the arg reg save area. The
1286 arg reg save area must have the following layout (according
1287 to the svr4 ABI):
1289 struct {
1290 union {
1291 float freg[8];
1292 double dreg[4];
1293 } float_regs;
1294 long ireg[12];
1298 asm (" fst.q f8, 0(sp)");
1299 asm (" fst.q f12,16(sp)");
1300 asm (" st.l r16,32(sp)");
1301 asm (" st.l r17,36(sp)");
1302 asm (" st.l r18,40(sp)");
1303 asm (" st.l r19,44(sp)");
1304 asm (" st.l r20,48(sp)");
1305 asm (" st.l r21,52(sp)");
1306 asm (" st.l r22,56(sp)");
1307 asm (" st.l r23,60(sp)");
1308 asm (" st.l r24,64(sp)");
1309 asm (" st.l r25,68(sp)");
1310 asm (" st.l r26,72(sp)");
1311 asm (" st.l r27,76(sp)");
1313 asm (" adds 80,sp,r16"); /* compute the address of the new
1314 va_list structure. Put in into
1315 r16 so that it will be returned
1316 to the caller. */
1318 /* Initialize all fields of the new va_list structure. This
1319 structure looks like:
1321 typedef struct {
1322 unsigned long ireg_used;
1323 unsigned long freg_used;
1324 long *reg_base;
1325 long *mem_ptr;
1326 } va_list;
1329 asm (" st.l r0, 0(r16)"); /* nfixed */
1330 asm (" st.l r0, 4(r16)"); /* nfloating */
1331 asm (" st.l sp, 8(r16)"); /* __va_ctl points to __va_struct. */
1332 asm (" bri r1"); /* delayed return */
1333 asm (" st.l r28,12(r16)"); /* pointer to overflow args */
1334 #else /* not __PARAGON__ */
1335 asm (" .text");
1336 asm (" .align 4");
1338 asm (".globl ___builtin_saveregs");
1339 asm ("___builtin_saveregs:");
1340 asm (" mov sp,r30");
1341 asm (" andnot 0x0f,sp,sp");
1342 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
1344 /* Fill in the __va_struct. */
1345 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
1346 asm (" st.l r17, 4(sp)"); /* int fixed[12] */
1347 asm (" st.l r18, 8(sp)");
1348 asm (" st.l r19,12(sp)");
1349 asm (" st.l r20,16(sp)");
1350 asm (" st.l r21,20(sp)");
1351 asm (" st.l r22,24(sp)");
1352 asm (" st.l r23,28(sp)");
1353 asm (" st.l r24,32(sp)");
1354 asm (" st.l r25,36(sp)");
1355 asm (" st.l r26,40(sp)");
1356 asm (" st.l r27,44(sp)");
1358 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
1359 asm (" fst.q f12,64(sp)"); /* int floating[8] */
1361 /* Fill in the __va_ctl. */
1362 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
1363 asm (" st.l r28,84(sp)"); /* pointer to more args */
1364 asm (" st.l r0, 88(sp)"); /* nfixed */
1365 asm (" st.l r0, 92(sp)"); /* nfloating */
1367 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
1368 asm (" bri r1");
1369 asm (" mov r30,sp");
1370 /* recover stack and pass address to start
1371 of data. */
1372 #endif /* not __PARAGON__ */
1373 #endif /* not __svr4__ */
1374 #else /* not __i860__ */
1375 #ifdef __sparc__
1376 asm (".global __builtin_saveregs");
1377 asm ("__builtin_saveregs:");
1378 asm (".global ___builtin_saveregs");
1379 asm ("___builtin_saveregs:");
1380 #ifdef NEED_PROC_COMMAND
1381 asm (".proc 020");
1382 #endif
1383 asm ("st %i0,[%fp+68]");
1384 asm ("st %i1,[%fp+72]");
1385 asm ("st %i2,[%fp+76]");
1386 asm ("st %i3,[%fp+80]");
1387 asm ("st %i4,[%fp+84]");
1388 asm ("retl");
1389 asm ("st %i5,[%fp+88]");
1390 #ifdef NEED_TYPE_COMMAND
1391 asm (".type __builtin_saveregs,#function");
1392 asm (".size __builtin_saveregs,.-__builtin_saveregs");
1393 #endif
1394 #else /* not __sparc__ */
1395 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1397 asm (" .text");
1398 asm (" .ent __builtin_saveregs");
1399 asm (" .globl __builtin_saveregs");
1400 asm ("__builtin_saveregs:");
1401 asm (" sw $4,0($30)");
1402 asm (" sw $5,4($30)");
1403 asm (" sw $6,8($30)");
1404 asm (" sw $7,12($30)");
1405 asm (" j $31");
1406 asm (" .end __builtin_saveregs");
1407 #else /* not __mips__, etc. */
1409 void *
1410 __builtin_saveregs ()
1412 abort ();
1415 #endif /* not __mips__ */
1416 #endif /* not __sparc__ */
1417 #endif /* not __i860__ */
1418 #endif
1420 #ifdef L_eprintf
1421 #ifndef inhibit_libc
1423 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1424 #include <stdio.h>
1425 /* This is used by the `assert' macro. */
1426 void
1427 __eprintf (string, expression, line, filename)
1428 const char *string;
1429 const char *expression;
1430 int line;
1431 const char *filename;
1433 fprintf (stderr, string, expression, line, filename);
1434 fflush (stderr);
1435 abort ();
1438 #endif
1439 #endif
1441 #ifdef L_bb
1443 /* Structure emitted by -a */
1444 struct bb
1446 long zero_word;
1447 const char *filename;
1448 long *counts;
1449 long ncounts;
1450 struct bb *next;
1451 const unsigned long *addresses;
1453 /* Older GCC's did not emit these fields. */
1454 long nwords;
1455 const char **functions;
1456 const long *line_nums;
1457 const char **filenames;
1458 char *flags;
1461 #ifdef BLOCK_PROFILER_CODE
1462 BLOCK_PROFILER_CODE
1463 #else
1464 #ifndef inhibit_libc
1466 /* Simple minded basic block profiling output dumper for
1467 systems that don't provide tcov support. At present,
1468 it requires atexit and stdio. */
1470 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1471 #include <stdio.h>
1472 char *ctime ();
1474 #include "gbl-ctors.h"
1476 static struct bb *bb_head;
1478 /* Return the number of digits needed to print a value */
1479 /* __inline__ */ static int num_digits (long value, int base)
1481 int minus = (value < 0 && base != 16);
1482 unsigned long v = (minus) ? -value : value;
1483 int ret = minus;
1487 v /= base;
1488 ret++;
1490 while (v);
1492 return ret;
1495 void
1496 __bb_exit_func (void)
1498 FILE *file = fopen ("bb.out", "a");
1499 long time_value;
1501 if (!file)
1502 perror ("bb.out");
1504 else
1506 struct bb *ptr;
1508 /* This is somewhat type incorrect, but it avoids worrying about
1509 exactly where time.h is included from. It should be ok unless
1510 a void * differs from other pointer formats, or if sizeof (long)
1511 is < sizeof (time_t). It would be nice if we could assume the
1512 use of rationale standards here. */
1514 time ((void *) &time_value);
1515 fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value));
1517 /* We check the length field explicitly in order to allow compatibility
1518 with older GCC's which did not provide it. */
1520 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1522 int i;
1523 int func_p = (ptr->nwords >= sizeof (struct bb) && ptr->nwords <= 1000);
1524 int line_p = (func_p && ptr->line_nums);
1525 int file_p = (func_p && ptr->filenames);
1526 long ncounts = ptr->ncounts;
1527 long cnt_max = 0;
1528 long line_max = 0;
1529 long addr_max = 0;
1530 int file_len = 0;
1531 int func_len = 0;
1532 int blk_len = num_digits (ncounts, 10);
1533 int cnt_len;
1534 int line_len;
1535 int addr_len;
1537 fprintf (file, "File %s, %ld basic blocks \n\n",
1538 ptr->filename, ncounts);
1540 /* Get max values for each field. */
1541 for (i = 0; i < ncounts; i++)
1543 const char *p;
1544 int len;
1546 if (cnt_max < ptr->counts[i])
1547 cnt_max = ptr->counts[i];
1549 if (addr_max < ptr->addresses[i])
1550 addr_max = ptr->addresses[i];
1552 if (line_p && line_max < ptr->line_nums[i])
1553 line_max = ptr->line_nums[i];
1555 if (func_p)
1557 p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>";
1558 len = strlen (p);
1559 if (func_len < len)
1560 func_len = len;
1563 if (file_p)
1565 p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>";
1566 len = strlen (p);
1567 if (file_len < len)
1568 file_len = len;
1572 addr_len = num_digits (addr_max, 16);
1573 cnt_len = num_digits (cnt_max, 10);
1574 line_len = num_digits (line_max, 10);
1576 /* Now print out the basic block information. */
1577 for (i = 0; i < ncounts; i++)
1579 fprintf (file,
1580 " Block #%*d: executed %*ld time(s) address= 0x%.*lx",
1581 blk_len, i+1,
1582 cnt_len, ptr->counts[i],
1583 addr_len, ptr->addresses[i]);
1585 if (func_p)
1586 fprintf (file, " function= %-*s", func_len,
1587 (ptr->functions[i]) ? ptr->functions[i] : "<none>");
1589 if (line_p)
1590 fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]);
1592 if (file_p)
1593 fprintf (file, " file= %s",
1594 (ptr->filenames[i]) ? ptr->filenames[i] : "<none>");
1596 fprintf (file, "\n");
1599 fprintf (file, "\n");
1600 fflush (file);
1603 fprintf (file, "\n\n");
1604 fclose (file);
1608 void
1609 __bb_init_func (struct bb *blocks)
1611 /* User is supposed to check whether the first word is non-0,
1612 but just in case.... */
1614 if (blocks->zero_word)
1615 return;
1617 #ifdef ON_EXIT
1618 /* Initialize destructor. */
1619 if (!bb_head)
1620 ON_EXIT (__bb_exit_func, 0);
1621 #endif
1623 /* Set up linked list. */
1624 blocks->zero_word = 1;
1625 blocks->next = bb_head;
1626 bb_head = blocks;
1629 #ifndef MACHINE_STATE_SAVE
1630 #define MACHINE_STATE_SAVE(ID)
1631 #endif
1632 #ifndef MACHINE_STATE_RESTORE
1633 #define MACHINE_STATE_RESTORE(ID)
1634 #endif
1636 #include <string.h>
1638 /* Number of buckets in hashtable of basic block addresses. */
1640 #define BB_BUCKETS 311
1642 /* Maximum length of string in file bb.in. */
1644 #define BBINBUFSIZE 500
1646 /* BBINBUFSIZE-1 with double quotes. We could use #BBINBUFSIZE or
1647 "BBINBUFSIZE" but want to avoid trouble with preprocessors. */
1649 #define BBINBUFSIZESTR "499"
1651 struct bb_edge
1653 struct bb_edge *next;
1654 unsigned long src_addr;
1655 unsigned long dst_addr;
1656 unsigned long count;
1659 enum bb_func_mode
1661 TRACE_KEEP = 0, TRACE_ON = 1, TRACE_OFF = 2
1664 struct bb_func
1666 struct bb_func *next;
1667 char *funcname;
1668 char *filename;
1669 enum bb_func_mode mode;
1672 /* This is the connection to the outside world.
1673 The BLOCK_PROFILER macro must set __bb.blocks
1674 and __bb.blockno. */
1676 struct {
1677 unsigned long blockno;
1678 struct bb *blocks;
1679 } __bb;
1681 /* Vars to store addrs of source and destination basic blocks
1682 of a jump. */
1684 static unsigned long bb_src = 0;
1685 static unsigned long bb_dst = 0;
1687 static FILE *bb_tracefile = (FILE *) 0;
1688 static struct bb_edge **bb_hashbuckets = (struct bb_edge **) 0;
1689 static struct bb_func *bb_func_head = (struct bb_func *) 0;
1690 static unsigned long bb_callcount = 0;
1691 static int bb_mode = 0;
1693 static unsigned long *bb_stack = (unsigned long *) 0;
1694 static size_t bb_stacksize = 0;
1696 static int reported = 0;
1698 /* Trace modes:
1699 Always : Print execution frequencies of basic blocks
1700 to file bb.out.
1701 bb_mode & 1 != 0 : Dump trace of basic blocks to file bbtrace[.gz]
1702 bb_mode & 2 != 0 : Print jump frequencies to file bb.out.
1703 bb_mode & 4 != 0 : Cut call instructions from basic block flow.
1704 bb_mode & 8 != 0 : Insert return instructions in basic block flow.
1707 #ifdef HAVE_POPEN
1709 /*#include <sys/types.h>*/
1710 #include <sys/stat.h>
1711 /*#include <malloc.h>*/
1713 /* Commands executed by gopen. */
1715 #define GOPENDECOMPRESS "gzip -cd "
1716 #define GOPENCOMPRESS "gzip -c >"
1718 /* Like fopen but pipes through gzip. mode may only be "r" or "w".
1719 If it does not compile, simply replace gopen by fopen and delete
1720 '.gz' from any first parameter to gopen. */
1722 static FILE *
1723 gopen (fn, mode)
1724 char *fn;
1725 char *mode;
1727 int use_gzip;
1728 char *p;
1730 if (mode[1])
1731 return (FILE *) 0;
1733 if (mode[0] != 'r' && mode[0] != 'w')
1734 return (FILE *) 0;
1736 p = fn + strlen (fn)-1;
1737 use_gzip = ((p[-1] == '.' && (p[0] == 'Z' || p[0] == 'z')) ||
1738 (p[-2] == '.' && p[-1] == 'g' && p[0] == 'z'));
1740 if (use_gzip)
1742 if (mode[0]=='r')
1744 FILE *f;
1745 char *s = (char *) malloc (sizeof (char) * strlen (fn)
1746 + sizeof (GOPENDECOMPRESS));
1747 strcpy (s, GOPENDECOMPRESS);
1748 strcpy (s + (sizeof (GOPENDECOMPRESS)-1), fn);
1749 f = popen (s, mode);
1750 free (s);
1751 return f;
1754 else
1756 FILE *f;
1757 char *s = (char *) malloc (sizeof (char) * strlen (fn)
1758 + sizeof (GOPENCOMPRESS));
1759 strcpy (s, GOPENCOMPRESS);
1760 strcpy (s + (sizeof (GOPENCOMPRESS)-1), fn);
1761 if (!(f = popen (s, mode)))
1762 f = fopen (s, mode);
1763 free (s);
1764 return f;
1768 else
1769 return fopen (fn, mode);
1772 static int
1773 gclose (f)
1774 FILE *f;
1776 struct stat buf;
1778 if (f != NULL)
1780 if (!fstat (fileno (f), &buf) && S_ISFIFO (buf.st_mode))
1781 return pclose (f);
1783 return fclose (f);
1785 return 0;
1788 #endif /* HAVE_POPEN */
1790 /* Called once per program. */
1792 static void
1793 __bb_exit_trace_func ()
1795 FILE *file = fopen ("bb.out", "a");
1796 struct bb_func *f;
1797 struct bb_edge *e;
1798 struct bb *b;
1800 if (!file)
1801 perror ("bb.out");
1803 if (bb_mode & 1)
1805 if (!bb_tracefile)
1806 perror ("bbtrace");
1807 else
1808 #ifdef HAVE_POPEN
1809 gclose (bb_tracefile);
1810 #else
1811 fclose (bb_tracefile);
1812 #endif /* HAVE_POPEN */
1815 /* Check functions in `bb.in'. */
1817 if (file)
1819 long time_value;
1820 const struct bb_func *p;
1821 int printed_something = 0;
1822 struct bb *ptr;
1823 long blk;
1825 /* This is somewhat type incorrect. */
1826 time ((void *) &time_value);
1828 for (p = bb_func_head; p != (struct bb_func *) 0; p = p->next)
1830 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1832 if (!ptr->filename || p->filename != (char *) 0 && strcmp (p->filename, ptr->filename))
1833 continue;
1834 for (blk = 0; blk < ptr->ncounts; blk++)
1836 if (!strcmp (p->funcname, ptr->functions[blk]))
1837 goto found;
1841 if (!printed_something)
1843 fprintf (file, "Functions in `bb.in' not executed during basic block profiling on %s\n", ctime ((void *) &time_value));
1844 printed_something = 1;
1847 fprintf (file, "\tFunction %s", p->funcname);
1848 if (p->filename)
1849 fprintf (file, " of file %s", p->filename);
1850 fprintf (file, "\n" );
1852 found: ;
1855 if (printed_something)
1856 fprintf (file, "\n");
1860 if (bb_mode & 2)
1862 if (!bb_hashbuckets)
1864 if (!reported)
1866 fprintf (stderr, "Profiler: out of memory\n");
1867 reported = 1;
1869 return;
1872 else if (file)
1874 long time_value;
1875 int i;
1876 unsigned long addr_max = 0;
1877 unsigned long cnt_max = 0;
1878 int cnt_len;
1879 int addr_len;
1881 /* This is somewhat type incorrect, but it avoids worrying about
1882 exactly where time.h is included from. It should be ok unless
1883 a void * differs from other pointer formats, or if sizeof (long)
1884 is < sizeof (time_t). It would be nice if we could assume the
1885 use of rationale standards here. */
1887 time ((void *) &time_value);
1888 fprintf (file, "Basic block jump tracing");
1890 switch (bb_mode & 12)
1892 case 0:
1893 fprintf (file, " (with call)");
1894 break;
1896 case 4:
1897 /* Print nothing. */
1898 break;
1900 case 8:
1901 fprintf (file, " (with call & ret)");
1902 break;
1904 case 12:
1905 fprintf (file, " (with ret)");
1906 break;
1909 fprintf (file, " finished on %s\n", ctime ((void *) &time_value));
1911 for (i = 0; i < BB_BUCKETS; i++)
1913 struct bb_edge *bucket = bb_hashbuckets[i];
1914 for ( ; bucket; bucket = bucket->next )
1916 if (addr_max < bucket->src_addr)
1917 addr_max = bucket->src_addr;
1918 if (addr_max < bucket->dst_addr)
1919 addr_max = bucket->dst_addr;
1920 if (cnt_max < bucket->count)
1921 cnt_max = bucket->count;
1924 addr_len = num_digits (addr_max, 16);
1925 cnt_len = num_digits (cnt_max, 10);
1927 for ( i = 0; i < BB_BUCKETS; i++)
1929 struct bb_edge *bucket = bb_hashbuckets[i];
1930 for ( ; bucket; bucket = bucket->next )
1932 fprintf (file, "Jump from block 0x%.*lx to "
1933 "block 0x%.*lx executed %*d time(s)\n",
1934 addr_len, bucket->src_addr,
1935 addr_len, bucket->dst_addr,
1936 cnt_len, bucket->count);
1940 fprintf (file, "\n");
1945 if (file)
1946 fclose (file);
1948 /* Free allocated memory. */
1950 f = bb_func_head;
1951 while (f)
1953 struct bb_func *old = f;
1955 f = f->next;
1956 if (old->funcname) free (old->funcname);
1957 if (old->filename) free (old->filename);
1958 free (old);
1961 if (bb_stack)
1962 free (bb_stack);
1964 if (bb_hashbuckets)
1966 int i;
1968 for (i = 0; i < BB_BUCKETS; i++)
1970 struct bb_edge *old, *bucket = bb_hashbuckets[i];
1972 while (bucket)
1974 old = bucket;
1975 bucket = bucket->next;
1976 free (old);
1979 free (bb_hashbuckets);
1982 for (b = bb_head; b; b = b->next)
1983 if (b->flags) free (b->flags);
1986 /* Called once per program. */
1988 static void
1989 __bb_init_prg ()
1992 FILE *file;
1993 char buf[BBINBUFSIZE];
1994 const char *p;
1995 const char *pos;
1996 enum bb_func_mode m;
1998 #ifdef ON_EXIT
1999 /* Initialize destructor. */
2000 ON_EXIT (__bb_exit_func, 0);
2001 #endif
2003 if (!(file = fopen ("bb.in", "r")))
2004 return;
2006 while(fscanf (file, " %" BBINBUFSIZESTR "s ", buf) != EOF)
2008 p = buf;
2009 if (*p == '-')
2011 m = TRACE_OFF;
2012 p++;
2014 else
2016 m = TRACE_ON;
2018 if (!strcmp (p, "__bb_trace__"))
2019 bb_mode |= 1;
2020 else if (!strcmp (p, "__bb_jumps__"))
2021 bb_mode |= 2;
2022 else if (!strcmp (p, "__bb_hidecall__"))
2023 bb_mode |= 4;
2024 else if (!strcmp (p, "__bb_showret__"))
2025 bb_mode |= 8;
2026 else
2028 struct bb_func *f = (struct bb_func *) malloc (sizeof (struct bb_func));
2029 if (f)
2031 unsigned long l;
2032 f->next = bb_func_head;
2033 if (pos = strchr (p, ':'))
2035 if (!(f->funcname = (char *) malloc (strlen (pos+1)+1)))
2036 continue;
2037 strcpy (f->funcname, pos+1);
2038 l = pos-p;
2039 if ((f->filename = (char *) malloc (l+1)))
2041 strncpy (f->filename, p, l);
2042 f->filename[l] = '\0';
2044 else
2045 f->filename = (char *) 0;
2047 else
2049 if (!(f->funcname = (char *) malloc (strlen (p)+1)))
2050 continue;
2051 strcpy (f->funcname, p);
2052 f->filename = (char *) 0;
2054 f->mode = m;
2055 bb_func_head = f;
2059 fclose (file);
2061 #ifdef HAVE_POPEN
2063 if (bb_mode & 1)
2064 bb_tracefile = gopen ("bbtrace.gz", "w");
2066 #else
2068 if (bb_mode & 1)
2069 bb_tracefile = fopen ("bbtrace", "w");
2071 #endif /* HAVE_POPEN */
2073 if (bb_mode & 2)
2075 bb_hashbuckets = (struct bb_edge **)
2076 malloc (BB_BUCKETS * sizeof (struct bb_edge *));
2077 if (bb_hashbuckets)
2078 bzero ((char *) bb_hashbuckets, BB_BUCKETS);
2081 if (bb_mode & 12)
2083 bb_stacksize = 10;
2084 bb_stack = (unsigned long *) malloc (bb_stacksize * sizeof (*bb_stack));
2087 #ifdef ON_EXIT
2088 /* Initialize destructor. */
2089 ON_EXIT (__bb_exit_trace_func, 0);
2090 #endif
2094 /* Called upon entering a basic block. */
2096 void
2097 __bb_trace_func ()
2099 struct bb_edge *bucket;
2101 MACHINE_STATE_SAVE("1")
2103 if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2104 goto skip;
2106 bb_dst = __bb.blocks->addresses[__bb.blockno];
2107 __bb.blocks->counts[__bb.blockno]++;
2109 if (bb_tracefile)
2111 fwrite (&bb_dst, sizeof (unsigned long), 1, bb_tracefile);
2114 if (bb_hashbuckets)
2116 struct bb_edge **startbucket, **oldnext;
2118 oldnext = startbucket =
2119 & bb_hashbuckets[ (((int) bb_src*8) ^ (int) bb_dst) % BB_BUCKETS ];
2120 bucket = *startbucket;
2122 for (bucket = *startbucket; bucket;
2123 oldnext = &(bucket->next), bucket = *oldnext)
2125 if ( bucket->src_addr == bb_src &&
2126 bucket->dst_addr == bb_dst )
2128 bucket->count++;
2129 *oldnext = bucket->next;
2130 bucket->next = *startbucket;
2131 *startbucket = bucket;
2132 goto ret;
2136 bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2138 if (!bucket)
2140 if (!reported)
2142 fprintf (stderr, "Profiler: out of memory\n");
2143 reported = 1;
2147 else
2149 bucket->src_addr = bb_src;
2150 bucket->dst_addr = bb_dst;
2151 bucket->next = *startbucket;
2152 *startbucket = bucket;
2153 bucket->count = 1;
2157 ret:
2158 bb_src = bb_dst;
2160 skip:
2163 MACHINE_STATE_RESTORE("1")
2167 /* Called when returning from a function and `__bb_showret__' is set. */
2169 static void
2170 __bb_trace_func_ret ()
2172 struct bb_edge *bucket;
2174 if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2175 goto skip;
2177 if (bb_hashbuckets)
2179 struct bb_edge **startbucket, **oldnext;
2181 oldnext = startbucket =
2182 & bb_hashbuckets[ (((int) bb_dst * 8) ^ (int) bb_src) % BB_BUCKETS ];
2183 bucket = *startbucket;
2185 for (bucket = *startbucket; bucket;
2186 oldnext = &(bucket->next), bucket = *oldnext)
2188 if ( bucket->src_addr == bb_dst &&
2189 bucket->dst_addr == bb_src )
2191 bucket->count++;
2192 *oldnext = bucket->next;
2193 bucket->next = *startbucket;
2194 *startbucket = bucket;
2195 goto ret;
2199 bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2201 if (!bucket)
2203 if (!reported)
2205 fprintf (stderr, "Profiler: out of memory\n");
2206 reported = 1;
2210 else
2212 bucket->src_addr = bb_dst;
2213 bucket->dst_addr = bb_src;
2214 bucket->next = *startbucket;
2215 *startbucket = bucket;
2216 bucket->count = 1;
2220 ret:
2221 bb_dst = bb_src;
2223 skip:
2228 /* Called upon entering the first function of a file. */
2230 static void
2231 __bb_init_file (blocks)
2232 struct bb *blocks;
2235 const struct bb_func *p;
2236 long blk, ncounts = blocks->ncounts;
2237 const char **functions = blocks->functions;
2239 /* Set up linked list. */
2240 blocks->zero_word = 1;
2241 blocks->next = bb_head;
2242 bb_head = blocks;
2244 blocks->flags = 0;
2245 if (!bb_func_head ||
2246 !(blocks->flags = (char *) malloc (sizeof (char) * blocks->ncounts)))
2247 return;
2249 for (blk = 0; blk < ncounts; blk++)
2250 blocks->flags[blk] = 0;
2252 for (blk = 0; blk < ncounts; blk++)
2254 for (p = bb_func_head; p; p = p->next)
2256 if (!strcmp (p->funcname, functions[blk]) &&
2257 (!p->filename || !strcmp (p->filename, blocks->filename)))
2259 blocks->flags[blk] |= p->mode;
2266 /* Called when exiting from a function. */
2268 void
2269 __bb_trace_ret ()
2272 MACHINE_STATE_SAVE("2")
2274 if (bb_callcount)
2276 if ((bb_mode & 12) && bb_stacksize > bb_callcount)
2278 bb_src = bb_stack[bb_callcount];
2279 if (bb_mode & 8)
2280 __bb_trace_func_ret ();
2283 bb_callcount -= 1;
2286 MACHINE_STATE_RESTORE("2")
2290 /* Called when entering a function. */
2292 void
2293 __bb_init_trace_func (blocks, blockno)
2294 struct bb *blocks;
2295 unsigned long blockno;
2297 static int trace_init = 0;
2299 MACHINE_STATE_SAVE("3")
2301 if (!blocks->zero_word)
2303 if (!trace_init)
2305 trace_init = 1;
2306 __bb_init_prg ();
2308 __bb_init_file (blocks);
2311 if (bb_callcount)
2314 bb_callcount += 1;
2316 if (bb_mode & 12)
2318 if (bb_callcount >= bb_stacksize)
2320 size_t newsize = bb_callcount + 100;
2322 bb_stack = (unsigned long *) realloc (bb_stack, newsize);
2323 if (! bb_stack)
2325 if (!reported)
2327 fprintf (stderr, "Profiler: out of memory\n");
2328 reported = 1;
2330 bb_stacksize = 0;
2331 goto stack_overflow;
2333 bb_stacksize = newsize;
2335 bb_stack[bb_callcount] = bb_src;
2337 if (bb_mode & 4)
2338 bb_src = 0;
2342 stack_overflow:;
2346 else if (blocks->flags && (blocks->flags[blockno] & TRACE_ON))
2348 bb_callcount = 1;
2349 bb_src = 0;
2351 if (bb_stack)
2352 bb_stack[bb_callcount] = bb_src;
2355 MACHINE_STATE_RESTORE("3")
2358 #endif /* not inhibit_libc */
2359 #endif /* not BLOCK_PROFILER_CODE */
2360 #endif /* L_bb */
2362 /* Default free-store management functions for C++, per sections 12.5 and
2363 17.3.3 of the Working Paper. */
2365 #ifdef L_op_new
2366 /* operator new (size_t), described in 17.3.3.5. This function is used by
2367 C++ programs to allocate a block of memory to hold a single object. */
2369 typedef void (*vfp)(void);
2370 extern vfp __new_handler;
2371 extern void __default_new_handler (void);
2373 #ifdef WEAK_ALIAS
2374 void * __builtin_new (size_t sz)
2375 __attribute__ ((weak, alias ("___builtin_new")));
2376 void *
2377 ___builtin_new (size_t sz)
2378 #else
2379 void *
2380 __builtin_new (size_t sz)
2381 #endif
2383 void *p;
2384 vfp handler = (__new_handler) ? __new_handler : __default_new_handler;
2386 /* malloc (0) is unpredictable; avoid it. */
2387 if (sz == 0)
2388 sz = 1;
2389 p = (void *) malloc (sz);
2390 while (p == 0)
2392 (*handler) ();
2393 p = (void *) malloc (sz);
2396 return p;
2398 #endif /* L_op_new */
2400 #ifdef L_op_vnew
2401 /* void * operator new [] (size_t), described in 17.3.3.6. This function
2402 is used by C++ programs to allocate a block of memory for an array. */
2404 extern void * __builtin_new (size_t);
2406 #ifdef WEAK_ALIAS
2407 void * __builtin_vec_new (size_t sz)
2408 __attribute__ ((weak, alias ("___builtin_vec_new")));
2409 void *
2410 ___builtin_vec_new (size_t sz)
2411 #else
2412 void *
2413 __builtin_vec_new (size_t sz)
2414 #endif
2416 return __builtin_new (sz);
2418 #endif /* L_op_vnew */
2420 #ifdef L_new_handler
2421 /* set_new_handler (fvoid_t *) and the default new handler, described in
2422 17.3.3.2 and 17.3.3.5. These functions define the result of a failure
2423 to allocate the amount of memory requested from operator new or new []. */
2425 #ifndef inhibit_libc
2426 /* This gets us __GNU_LIBRARY__. */
2427 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2428 #include <stdio.h>
2430 #ifdef __GNU_LIBRARY__
2431 /* Avoid forcing the library's meaning of `write' on the user program
2432 by using the "internal" name (for use within the library) */
2433 #define write(fd, buf, n) __write((fd), (buf), (n))
2434 #endif
2435 #endif /* inhibit_libc */
2437 typedef void (*vfp)(void);
2438 void __default_new_handler (void);
2440 vfp __new_handler = (vfp) 0;
2443 set_new_handler (vfp handler)
2445 vfp prev_handler;
2447 prev_handler = __new_handler;
2448 if (handler == 0) handler = __default_new_handler;
2449 __new_handler = handler;
2450 return prev_handler;
2453 #define MESSAGE "Virtual memory exceeded in `new'\n"
2455 void
2456 __default_new_handler ()
2458 #ifndef inhibit_libc
2459 /* don't use fprintf (stderr, ...) because it may need to call malloc. */
2460 /* This should really print the name of the program, but that is hard to
2461 do. We need a standard, clean way to get at the name. */
2462 write (2, MESSAGE, sizeof (MESSAGE));
2463 #endif
2464 /* don't call exit () because that may call global destructors which
2465 may cause a loop. */
2466 _exit (-1);
2468 #endif
2470 #ifdef L_op_delete
2471 /* operator delete (void *), described in 17.3.3.3. This function is used
2472 by C++ programs to return to the free store a block of memory allocated
2473 as a single object. */
2475 #ifdef WEAK_ALIAS
2476 void __builtin_delete (void *ptr)
2477 __attribute__ ((weak, alias ("___builtin_delete")));
2478 void
2479 ___builtin_delete (void *ptr)
2480 #else
2481 void
2482 __builtin_delete (void *ptr)
2483 #endif
2485 if (ptr)
2486 free (ptr);
2488 #endif
2490 #ifdef L_op_vdel
2491 /* operator delete [] (void *), described in 17.3.3.4. This function is
2492 used by C++ programs to return to the free store a block of memory
2493 allocated as an array. */
2495 extern void __builtin_delete (void *);
2497 #ifdef WEAK_ALIAS
2498 void __builtin_vec_delete (void *ptr)
2499 __attribute__ ((weak, alias ("___builtin_vec_delete")));
2500 void
2501 ___builtin_vec_delete (void *ptr)
2502 #else
2503 void
2504 __builtin_vec_delete (void *ptr)
2505 #endif
2507 __builtin_delete (ptr);
2509 #endif
2511 /* End of C++ free-store management functions */
2513 #ifdef L_shtab
2514 unsigned int __shtab[] = {
2515 0x00000001, 0x00000002, 0x00000004, 0x00000008,
2516 0x00000010, 0x00000020, 0x00000040, 0x00000080,
2517 0x00000100, 0x00000200, 0x00000400, 0x00000800,
2518 0x00001000, 0x00002000, 0x00004000, 0x00008000,
2519 0x00010000, 0x00020000, 0x00040000, 0x00080000,
2520 0x00100000, 0x00200000, 0x00400000, 0x00800000,
2521 0x01000000, 0x02000000, 0x04000000, 0x08000000,
2522 0x10000000, 0x20000000, 0x40000000, 0x80000000
2524 #endif
2526 #ifdef L_clear_cache
2527 /* Clear part of an instruction cache. */
2529 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
2531 void
2532 __clear_cache (beg, end)
2533 char *beg, *end;
2535 #ifdef CLEAR_INSN_CACHE
2536 CLEAR_INSN_CACHE (beg, end);
2537 #else
2538 #ifdef INSN_CACHE_SIZE
2539 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
2540 static int initialized;
2541 int offset;
2542 void *start_addr
2543 void *end_addr;
2544 typedef (*function_ptr) ();
2546 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
2547 /* It's cheaper to clear the whole cache.
2548 Put in a series of jump instructions so that calling the beginning
2549 of the cache will clear the whole thing. */
2551 if (! initialized)
2553 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2554 & -INSN_CACHE_LINE_WIDTH);
2555 int end_ptr = ptr + INSN_CACHE_SIZE;
2557 while (ptr < end_ptr)
2559 *(INSTRUCTION_TYPE *)ptr
2560 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
2561 ptr += INSN_CACHE_LINE_WIDTH;
2563 *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
2565 initialized = 1;
2568 /* Call the beginning of the sequence. */
2569 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2570 & -INSN_CACHE_LINE_WIDTH))
2571 ());
2573 #else /* Cache is large. */
2575 if (! initialized)
2577 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2578 & -INSN_CACHE_LINE_WIDTH);
2580 while (ptr < (int) array + sizeof array)
2582 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
2583 ptr += INSN_CACHE_LINE_WIDTH;
2586 initialized = 1;
2589 /* Find the location in array that occupies the same cache line as BEG. */
2591 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
2592 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
2593 & -INSN_CACHE_PLANE_SIZE)
2594 + offset);
2596 /* Compute the cache alignment of the place to stop clearing. */
2597 #if 0 /* This is not needed for gcc's purposes. */
2598 /* If the block to clear is bigger than a cache plane,
2599 we clear the entire cache, and OFFSET is already correct. */
2600 if (end < beg + INSN_CACHE_PLANE_SIZE)
2601 #endif
2602 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
2603 & -INSN_CACHE_LINE_WIDTH)
2604 & (INSN_CACHE_PLANE_SIZE - 1));
2606 #if INSN_CACHE_DEPTH > 1
2607 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
2608 if (end_addr <= start_addr)
2609 end_addr += INSN_CACHE_PLANE_SIZE;
2611 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
2613 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
2614 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
2616 while (addr != stop)
2618 /* Call the return instruction at ADDR. */
2619 ((function_ptr) addr) ();
2621 addr += INSN_CACHE_LINE_WIDTH;
2624 #else /* just one plane */
2627 /* Call the return instruction at START_ADDR. */
2628 ((function_ptr) start_addr) ();
2630 start_addr += INSN_CACHE_LINE_WIDTH;
2632 while ((start_addr % INSN_CACHE_SIZE) != offset);
2633 #endif /* just one plane */
2634 #endif /* Cache is large */
2635 #endif /* Cache exists */
2636 #endif /* CLEAR_INSN_CACHE */
2639 #endif /* L_clear_cache */
2641 #ifdef L_trampoline
2643 /* Jump to a trampoline, loading the static chain address. */
2645 #ifdef WINNT
2647 long getpagesize()
2649 #ifdef _ALPHA_
2650 return 8192;
2651 #else
2652 return 4096;
2653 #endif
2656 int mprotect(addr, len, prot)
2657 char *addr;
2658 int len, prot;
2660 int np, op;
2662 if (prot == 7) np = 0x40;
2663 else if (prot == 5) np = 0x20;
2664 else if (prot == 4) np = 0x10;
2665 else if (prot == 3) np = 0x04;
2666 else if (prot == 1) np = 0x02;
2667 else if (prot == 0) np = 0x01;
2669 if (VirtualProtect (addr, len, np, &op))
2670 return 0;
2671 else
2672 return -1;
2676 #endif
2678 #ifdef TRANSFER_FROM_TRAMPOLINE
2679 TRANSFER_FROM_TRAMPOLINE
2680 #endif
2682 #if defined (NeXT) && defined (__MACH__)
2684 /* Make stack executable so we can call trampolines on stack.
2685 This is called from INITIALIZE_TRAMPOLINE in next.h. */
2686 #ifdef NeXTStep21
2687 #include <mach.h>
2688 #else
2689 #include <mach/mach.h>
2690 #endif
2692 void
2693 __enable_execute_stack (addr)
2694 char *addr;
2696 kern_return_t r;
2697 char *eaddr = addr + TRAMPOLINE_SIZE;
2698 vm_address_t a = (vm_address_t) addr;
2700 /* turn on execute access on stack */
2701 r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
2702 if (r != KERN_SUCCESS)
2704 mach_error("vm_protect VM_PROT_ALL", r);
2705 exit(1);
2708 /* We inline the i-cache invalidation for speed */
2710 #ifdef CLEAR_INSN_CACHE
2711 CLEAR_INSN_CACHE (addr, eaddr);
2712 #else
2713 __clear_cache ((int) addr, (int) eaddr);
2714 #endif
2717 #endif /* defined (NeXT) && defined (__MACH__) */
2719 #ifdef __convex__
2721 /* Make stack executable so we can call trampolines on stack.
2722 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
2724 #include <sys/mman.h>
2725 #include <sys/vmparam.h>
2726 #include <machine/machparam.h>
2728 void
2729 __enable_execute_stack ()
2731 int fp;
2732 static unsigned lowest = USRSTACK;
2733 unsigned current = (unsigned) &fp & -NBPG;
2735 if (lowest > current)
2737 unsigned len = lowest - current;
2738 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
2739 lowest = current;
2742 /* Clear instruction cache in case an old trampoline is in it. */
2743 asm ("pich");
2745 #endif /* __convex__ */
2747 #ifdef __DOLPHIN__
2749 /* Modified from the convex -code above. */
2751 #include <sys/param.h>
2752 #include <errno.h>
2753 #include <sys/m88kbcs.h>
2755 void
2756 __enable_execute_stack ()
2758 int save_errno;
2759 static unsigned long lowest = USRSTACK;
2760 unsigned long current = (unsigned long) &save_errno & -NBPC;
2762 /* Ignore errno being set. memctl sets errno to EINVAL whenever the
2763 address is seen as 'negative'. That is the case with the stack. */
2765 save_errno=errno;
2766 if (lowest > current)
2768 unsigned len=lowest-current;
2769 memctl(current,len,MCT_TEXT);
2770 lowest = current;
2772 else
2773 memctl(current,NBPC,MCT_TEXT);
2774 errno=save_errno;
2777 #endif /* __DOLPHIN__ */
2779 #ifdef __pyr__
2781 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2782 #include <stdio.h>
2783 #include <sys/mman.h>
2784 #include <sys/types.h>
2785 #include <sys/param.h>
2786 #include <sys/vmmac.h>
2788 /* Modified from the convex -code above.
2789 mremap promises to clear the i-cache. */
2791 void
2792 __enable_execute_stack ()
2794 int fp;
2795 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
2796 PROT_READ|PROT_WRITE|PROT_EXEC))
2798 perror ("mprotect in __enable_execute_stack");
2799 fflush (stderr);
2800 abort ();
2803 #endif /* __pyr__ */
2805 #if defined (sony_news) && defined (SYSTYPE_BSD)
2807 #include <stdio.h>
2808 #include <sys/types.h>
2809 #include <sys/param.h>
2810 #include <syscall.h>
2811 #include <machine/sysnews.h>
2813 /* cacheflush function for NEWS-OS 4.2.
2814 This function is called from trampoline-initialize code
2815 defined in config/mips/mips.h. */
2817 void
2818 cacheflush (beg,size,flag)
2819 char *beg;
2820 int size;
2821 int flag;
2823 if (syscall (SYS_sysnews, NEWS_CACHEFLUSH, beg, size, FLUSH_BCACHE))
2825 perror ("cache_flush");
2826 fflush (stderr);
2827 abort ();
2831 #endif /* sony_news */
2832 #endif /* L_trampoline */
2834 #ifdef L__main
2836 #include "gbl-ctors.h"
2837 /* Some systems use __main in a way incompatible with its use in gcc, in these
2838 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2839 give the same symbol without quotes for an alternative entry point. You
2840 must define both, or neither. */
2841 #ifndef NAME__MAIN
2842 #define NAME__MAIN "__main"
2843 #define SYMBOL__MAIN __main
2844 #endif
2846 #ifdef INIT_SECTION_ASM_OP
2847 #undef HAS_INIT_SECTION
2848 #define HAS_INIT_SECTION
2849 #endif
2851 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
2852 /* Run all the global destructors on exit from the program. */
2854 void
2855 __do_global_dtors ()
2857 #ifdef DO_GLOBAL_DTORS_BODY
2858 DO_GLOBAL_DTORS_BODY;
2859 #else
2860 static func_ptr *p = __DTOR_LIST__ + 1;
2861 while (*p)
2863 p++;
2864 (*(p-1)) ();
2866 #endif
2868 #endif
2870 #ifndef HAS_INIT_SECTION
2871 /* Run all the global constructors on entry to the program. */
2873 #ifndef ON_EXIT
2874 #define ON_EXIT(a, b)
2875 #else
2876 /* Make sure the exit routine is pulled in to define the globals as
2877 bss symbols, just in case the linker does not automatically pull
2878 bss definitions from the library. */
2880 extern int _exit_dummy_decl;
2881 int *_exit_dummy_ref = &_exit_dummy_decl;
2882 #endif /* ON_EXIT */
2884 void
2885 __do_global_ctors ()
2887 DO_GLOBAL_CTORS_BODY;
2888 ON_EXIT (__do_global_dtors, 0);
2890 #endif /* no HAS_INIT_SECTION */
2892 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
2893 /* Subroutine called automatically by `main'.
2894 Compiling a global function named `main'
2895 produces an automatic call to this function at the beginning.
2897 For many systems, this routine calls __do_global_ctors.
2898 For systems which support a .init section we use the .init section
2899 to run __do_global_ctors, so we need not do anything here. */
2901 void
2902 SYMBOL__MAIN ()
2904 /* Support recursive calls to `main': run initializers just once. */
2905 static int initialized;
2906 if (! initialized)
2908 initialized = 1;
2909 __do_global_ctors ();
2912 #endif /* no HAS_INIT_SECTION or INVOKE__main */
2914 #endif /* L__main */
2916 #ifdef L_ctors
2918 #include "gbl-ctors.h"
2920 /* Provide default definitions for the lists of constructors and
2921 destructors, so that we don't get linker errors. These symbols are
2922 intentionally bss symbols, so that gld and/or collect will provide
2923 the right values. */
2925 /* We declare the lists here with two elements each,
2926 so that they are valid empty lists if no other definition is loaded. */
2927 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
2928 #if defined(__NeXT__) || defined(_AIX)
2929 /* After 2.3, try this definition on all systems. */
2930 func_ptr __CTOR_LIST__[2] = {0, 0};
2931 func_ptr __DTOR_LIST__[2] = {0, 0};
2932 #else
2933 func_ptr __CTOR_LIST__[2];
2934 func_ptr __DTOR_LIST__[2];
2935 #endif
2936 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
2937 #endif /* L_ctors */
2939 #ifdef L_exit
2941 #include "gbl-ctors.h"
2943 #ifdef NEED_ATEXIT
2944 # ifdef ON_EXIT
2945 # undef ON_EXIT
2946 # endif
2947 int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */
2948 #endif
2950 #ifndef ON_EXIT
2952 #ifdef NEED_ATEXIT
2953 # include <errno.h>
2955 extern void *malloc ();
2956 extern void *realloc ();
2958 static func_ptr *atexit_chain = NULL;
2959 static long atexit_chain_length = 0;
2960 static volatile long last_atexit_chain_slot = -1;
2962 int atexit (func_ptr func)
2964 if (++last_atexit_chain_slot == atexit_chain_length)
2966 atexit_chain_length += 32;
2967 if (atexit_chain)
2968 atexit_chain = realloc (atexit_chain,
2969 atexit_chain_length * sizeof (func_ptr));
2970 else
2971 atexit_chain = malloc (atexit_chain_length * sizeof (func_ptr));
2972 if (! atexit_chain)
2974 atexit_chain_length = 0;
2975 last_atexit_chain_slot = -1;
2976 errno = ENOMEM;
2977 return (-1);
2980 atexit_chain[last_atexit_chain_slot] = func;
2981 return (0);
2983 #endif /* NEED_ATEXIT */
2985 /* If we have no known way of registering our own __do_global_dtors
2986 routine so that it will be invoked at program exit time, then we
2987 have to define our own exit routine which will get this to happen. */
2989 extern void __do_global_dtors ();
2990 extern void _cleanup ();
2991 extern void _exit () __attribute__ ((noreturn));
2993 void
2994 exit (status)
2995 int status;
2997 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2998 #ifdef NEED_ATEXIT
2999 if (atexit_chain)
3001 for ( ; last_atexit_chain_slot-- >= 0; )
3003 (*atexit_chain[last_atexit_chain_slot + 1]) ();
3004 atexit_chain[last_atexit_chain_slot + 1] = NULL;
3006 free (atexit_chain);
3007 atexit_chain = NULL;
3009 #else /* No NEED_ATEXIT */
3010 __do_global_dtors ();
3011 #endif /* No NEED_ATEXIT */
3012 #endif
3013 #ifdef EXIT_BODY
3014 EXIT_BODY;
3015 #else
3016 _cleanup ();
3017 #endif
3018 _exit (status);
3021 #else
3022 int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */
3023 #endif
3025 #endif /* L_exit */
3027 #ifdef L_eh
3029 #ifdef EH_TABLE_LOOKUP
3031 EH_TABLE_LOOKUP
3033 #else
3035 typedef struct {
3036 void *start;
3037 void *end;
3038 void *exception_handler;
3039 } exception_table;
3041 struct exception_table_node {
3042 exception_table *table;
3043 void *start;
3044 void *end;
3045 struct exception_table_node *next;
3048 static int except_table_pos;
3049 static void *except_pc;
3050 static struct exception_table_node *exception_table_list;
3052 static exception_table *
3053 find_exception_table (pc)
3054 void *pc;
3056 register struct exception_table_node *table = exception_table_list;
3057 for ( ; table != 0; table = table->next)
3059 if (table->start <= pc && table->end > pc)
3060 return table->table;
3062 return 0;
3065 /* this routine takes a pc, and the address of the exception handler associated
3066 with the closest exception table handler entry associated with that PC,
3067 or 0 if there are no table entries the PC fits in. The algorithm works
3068 something like this:
3070 while(current_entry exists) {
3071 if(current_entry.start < pc )
3072 current_entry = next_entry;
3073 else {
3074 if(prev_entry.start <= pc && prev_entry.end > pc) {
3075 save pointer to prev_entry;
3076 return prev_entry.exception_handler;
3078 else return 0;
3081 return 0;
3083 Assuming a correctly sorted table (ascending order) this routine should
3084 return the tightest match...
3086 In the advent of a tie, we have to give the last entry, as it represents
3087 an inner block. */
3089 void *
3090 __find_first_exception_table_match(pc)
3091 void *pc;
3093 exception_table *table = find_exception_table (pc);
3094 int pos = 0;
3095 int best = 0;
3096 if (table == 0)
3097 return (void *) 0;
3098 #if 0
3099 printf ("find_first_exception_table_match(): pc = %x!\n", pc);
3100 #endif
3102 except_pc = pc;
3104 #if 0
3105 /* We can't do this yet, as we don't know that the table is sorted. */
3106 do {
3107 ++pos;
3108 if (table[pos].start > except_pc)
3109 /* found the first table[pos].start > except_pc, so the previous
3110 entry better be the one we want! */
3111 break;
3112 } while (table[pos].exception_handler != (void *) -1);
3114 --pos;
3115 if (table[pos].start <= except_pc && table[pos].end > except_pc)
3117 except_table_pos = pos;
3118 #if 0
3119 printf ("find_first_eh_table_match(): found match: %x\n", table[pos].exception_handler);
3120 #endif
3121 return table[pos].exception_handler;
3123 #else
3124 while (table[++pos].exception_handler != (void *) -1) {
3125 if (table[pos].start <= except_pc && table[pos].end > except_pc)
3127 /* This can apply. Make sure it is better or as good as the previous
3128 best. */
3129 /* The best one ends first. */
3130 if (best == 0 || (table[pos].end <= table[best].end
3131 /* The best one starts last. */
3132 && table[pos].start >= table[best].start))
3133 best = pos;
3136 if (best != 0)
3137 return table[best].exception_handler;
3138 #endif
3140 #if 0
3141 printf ("find_first_eh_table_match(): else: returning NULL!\n");
3142 #endif
3143 return (void *) 0;
3146 void
3147 __register_exceptions (exception_table *table)
3149 struct exception_table_node *node;
3150 exception_table *range = table + 1;
3152 if (range->start == (void *) -1)
3153 return;
3155 node = (struct exception_table_node *)
3156 malloc (sizeof (struct exception_table_node));
3157 node->table = table;
3159 /* This look can be optimized away either if the table
3160 is sorted, or if we pass in extra parameters. */
3161 node->start = range->start;
3162 node->end = range->end;
3163 for (range++ ; range->start != (void *) (-1); range++)
3165 if (range->start < node->start)
3166 node->start = range->start;
3167 if (range->end > node->end)
3168 node->end = range->end;
3171 node->next = exception_table_list;
3172 exception_table_list = node;
3174 #endif
3176 void *
3177 __throw_type_match (void *catch_type, void *throw_type, void *obj)
3179 #if 0
3180 printf ("__throw_type_match (): catch_type = %s, throw_type = %s\n",
3181 catch_type, throw_type);
3182 #endif
3183 if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)
3184 return obj;
3185 return 0;
3188 /* Throw stub routine.
3190 This is work in progress, but not completed yet. */
3192 void
3193 __throw ()
3195 abort ();
3198 /* This value identifies the place from which an exception is being
3199 thrown. */
3201 void *__eh_pc;
3203 void
3204 __empty ()
3208 #if #machine(i386)
3209 void
3210 __unwind_function(void *ptr)
3212 asm("movl 8(%esp),%ecx");
3213 /* Undo current frame */
3214 asm("movl %ebp,%esp");
3215 asm("popl %ebp");
3216 /* like ret, but stay here */
3217 asm("addl $4,%esp");
3219 /* Now, undo previous frame. */
3220 /* This is a test routine, as we have to dynamically probe to find out
3221 what to pop for certain, this is just a guess. */
3222 asm("leal -16(%ebp),%esp");
3223 asm("pop %ebx");
3224 asm("pop %esi");
3225 asm("pop %edi");
3226 asm("movl %ebp,%esp");
3227 asm("popl %ebp");
3229 asm("movl %ecx,0(%esp)");
3230 asm("ret");
3232 #elif #machine(rs6000) && !defined _ARCH_PPC
3233 __unwind_function(void *ptr)
3235 asm("mr 31,1");
3236 asm("l 1,0(1)");
3237 asm("l 31,-4(1)");
3238 asm("# br");
3240 asm("mr 31,1");
3241 asm("l 1,0(1)");
3242 /* use 31 as a scratch register to restore the link register. */
3243 asm("l 31, 8(1);mtlr 31 # l lr,8(1)");
3244 asm("l 31,-4(1)");
3245 asm("# br");
3246 asm("mtctr 3;bctr # b 3");
3248 #elif (#machine(rs6000) || #machine(powerpc)) && defined _ARCH_PPC
3249 __unwind_function(void *ptr)
3251 asm("mr 31,1");
3252 asm("lwz 1,0(1)");
3253 asm("lwz 31,-4(1)");
3254 asm("# br");
3256 asm("mr 31,1");
3257 asm("lwz 1,0(1)");
3258 /* use 31 as a scratch register to restore the link register. */
3259 asm("lwz 31, 8(1);mtlr 31 # l lr,8(1)");
3260 asm("lwz 31,-4(1)");
3261 asm("# br");
3262 asm("mtctr 3;bctr # b 3");
3264 #elif #machine(vax)
3265 __unwind_function(void *ptr)
3267 __label__ return_again;
3269 /* Replace our frame's return address with the label below.
3270 During execution, we will first return here instead of to
3271 caller, then second return takes caller's frame off the stack.
3272 Two returns matches two actual calls, so is less likely to
3273 confuse debuggers. `16' corresponds to RETURN_ADDRESS_OFFSET. */
3274 __asm ("movl %0,16(fp)" : : "p" (&& return_again));
3275 return;
3277 return_again:
3278 return;
3280 #else
3281 __unwind_function(void *ptr)
3283 abort ();
3285 #endif /* powerpc */
3286 #endif /* L_eh */
3288 #ifdef L_pure
3289 #ifndef inhibit_libc
3290 /* This gets us __GNU_LIBRARY__. */
3291 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
3292 #include <stdio.h>
3294 #ifdef __GNU_LIBRARY__
3295 /* Avoid forcing the library's meaning of `write' on the user program
3296 by using the "internal" name (for use within the library) */
3297 #define write(fd, buf, n) __write((fd), (buf), (n))
3298 #endif
3299 #endif /* inhibit_libc */
3301 #define MESSAGE "pure virtual method called\n"
3303 void
3304 __pure_virtual ()
3306 #ifndef inhibit_libc
3307 write (2, MESSAGE, sizeof (MESSAGE) - 1);
3308 #endif
3309 _exit (-1);
3311 #endif