* configure.in (LIMITS_INC_SRCDIR): New variable.
[official-gcc.git] / gcc / libgcc2.c
blob3658ffeabae086577800570f6d55af22230ac76e
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, 1996, 1997, 1998, 1999,
4 2000, 2001 Free Software Foundation, Inc.
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
13 In addition to the permissions in the GNU General Public License, the
14 Free Software Foundation gives you unlimited permission to link the
15 compiled version of this file into combinations with other programs,
16 and to distribute those combinations without any restriction coming
17 from the use of this file. (The General Public License restrictions
18 do apply in other respects; for example, they cover modification of
19 the file, and distribution when not linked into a combine
20 executable.)
22 GNU CC is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 GNU General Public License for more details.
27 You should have received a copy of the GNU General Public License
28 along with GNU CC; see the file COPYING. If not, write to
29 the Free Software Foundation, 59 Temple Place - Suite 330,
30 Boston, MA 02111-1307, USA. */
32 /* It is incorrect to include config.h here, because this file is being
33 compiled for the target, and hence definitions concerning only the host
34 do not apply. */
36 #include "tconfig.h"
37 #include "tsystem.h"
38 #include "hwint.h"
40 #include "machmode.h"
42 /* Don't use `fancy_abort' here even if config.h says to use it. */
43 #ifdef abort
44 #undef abort
45 #endif
47 #include "libgcc2.h"
49 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
50 #if defined (L_divdi3) || defined (L_moddi3)
51 static inline
52 #endif
53 DWtype
54 __negdi2 (DWtype u)
56 DWunion w;
57 DWunion uu;
59 uu.ll = u;
61 w.s.low = -uu.s.low;
62 w.s.high = -uu.s.high - ((UWtype) w.s.low > 0);
64 return w.ll;
66 #endif
68 #ifdef L_addvsi3
69 Wtype
70 __addvsi3 (Wtype a, Wtype b)
72 Wtype w;
74 w = a + b;
76 if (b >= 0 ? w < a : w > a)
77 abort ();
79 return w;
81 #endif
83 #ifdef L_addvdi3
84 DWtype
85 __addvdi3 (DWtype a, DWtype b)
87 DWtype w;
89 w = a + b;
91 if (b >= 0 ? w < a : w > a)
92 abort ();
94 return w;
96 #endif
98 #ifdef L_subvsi3
99 Wtype
100 __subvsi3 (Wtype a, Wtype b)
102 #ifdef L_addvsi3
103 return __addvsi3 (a, (-b));
104 #else
105 DWtype w;
107 w = a - b;
109 if (b >= 0 ? w > a : w < a)
110 abort ();
112 return w;
113 #endif
115 #endif
117 #ifdef L_subvdi3
118 DWtype
119 __subvdi3 (DWtype a, DWtype b)
121 #ifdef L_addvdi3
122 return (a, (-b));
123 #else
124 DWtype w;
126 w = a - b;
128 if (b >= 0 ? w > a : w < a)
129 abort ();
131 return w;
132 #endif
134 #endif
136 #ifdef L_mulvsi3
137 Wtype
138 __mulvsi3 (Wtype a, Wtype b)
140 DWtype w;
142 w = a * b;
144 if (((a >= 0) == (b >= 0)) ? w < 0 : w > 0)
145 abort ();
147 return w;
149 #endif
151 #ifdef L_negvsi2
152 Wtype
153 __negvsi2 (Wtype a)
155 Wtype w;
157 w = -a;
159 if (a >= 0 ? w > 0 : w < 0)
160 abort ();
162 return w;
164 #endif
166 #ifdef L_negvdi2
167 DWtype
168 __negvdi2 (DWtype a)
170 DWtype w;
172 w = -a;
174 if (a >= 0 ? w > 0 : w < 0)
175 abort ();
177 return w;
179 #endif
181 #ifdef L_absvsi2
182 Wtype
183 __absvsi2 (Wtype a)
185 Wtype w = a;
187 if (a < 0)
188 #ifdef L_negvsi2
189 w = __negvsi2 (a);
190 #else
191 w = -a;
193 if (w < 0)
194 abort ();
195 #endif
197 return w;
199 #endif
201 #ifdef L_absvdi2
202 DWtype
203 __absvdi2 (DWtype a)
205 DWtype w = a;
207 if (a < 0)
208 #ifdef L_negvsi2
209 w = __negvsi2 (a);
210 #else
211 w = -a;
213 if (w < 0)
214 abort ();
215 #endif
217 return w;
219 #endif
221 #ifdef L_mulvdi3
222 DWtype
223 __mulvdi3 (DWtype u, DWtype v)
225 DWtype w;
227 w = u * v;
229 if (((u >= 0) == (v >= 0)) ? w < 0 : w > 0)
230 abort ();
232 return w;
234 #endif
237 /* Unless shift functions are defined whith full ANSI prototypes,
238 parameter b will be promoted to int if word_type is smaller than an int. */
239 #ifdef L_lshrdi3
240 DWtype
241 __lshrdi3 (DWtype u, word_type b)
243 DWunion w;
244 word_type bm;
245 DWunion uu;
247 if (b == 0)
248 return u;
250 uu.ll = u;
252 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
253 if (bm <= 0)
255 w.s.high = 0;
256 w.s.low = (UWtype) uu.s.high >> -bm;
258 else
260 UWtype carries = (UWtype) uu.s.high << bm;
262 w.s.high = (UWtype) uu.s.high >> b;
263 w.s.low = ((UWtype) uu.s.low >> b) | carries;
266 return w.ll;
268 #endif
270 #ifdef L_ashldi3
271 DWtype
272 __ashldi3 (DWtype u, word_type b)
274 DWunion w;
275 word_type bm;
276 DWunion uu;
278 if (b == 0)
279 return u;
281 uu.ll = u;
283 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
284 if (bm <= 0)
286 w.s.low = 0;
287 w.s.high = (UWtype) uu.s.low << -bm;
289 else
291 UWtype carries = (UWtype) uu.s.low >> bm;
293 w.s.low = (UWtype) uu.s.low << b;
294 w.s.high = ((UWtype) uu.s.high << b) | carries;
297 return w.ll;
299 #endif
301 #ifdef L_ashrdi3
302 DWtype
303 __ashrdi3 (DWtype u, word_type b)
305 DWunion w;
306 word_type bm;
307 DWunion uu;
309 if (b == 0)
310 return u;
312 uu.ll = u;
314 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
315 if (bm <= 0)
317 /* w.s.high = 1..1 or 0..0 */
318 w.s.high = uu.s.high >> (sizeof (Wtype) * BITS_PER_UNIT - 1);
319 w.s.low = uu.s.high >> -bm;
321 else
323 UWtype carries = (UWtype) uu.s.high << bm;
325 w.s.high = uu.s.high >> b;
326 w.s.low = ((UWtype) uu.s.low >> b) | carries;
329 return w.ll;
331 #endif
333 #ifdef L_ffsdi2
334 DWtype
335 __ffsdi2 (DWtype u)
337 DWunion uu;
338 UWtype word, count, add;
340 uu.ll = u;
341 if (uu.s.low != 0)
342 word = uu.s.low, add = 0;
343 else if (uu.s.high != 0)
344 word = uu.s.high, add = BITS_PER_UNIT * sizeof (Wtype);
345 else
346 return 0;
348 count_trailing_zeros (count, word);
349 return count + add + 1;
351 #endif
353 #ifdef L_muldi3
354 DWtype
355 __muldi3 (DWtype u, DWtype v)
357 DWunion w;
358 DWunion uu, vv;
360 uu.ll = u,
361 vv.ll = v;
363 w.ll = __umulsidi3 (uu.s.low, vv.s.low);
364 w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
365 + (UWtype) uu.s.high * (UWtype) vv.s.low);
367 return w.ll;
369 #endif
371 #ifdef L_udiv_w_sdiv
372 #if defined (sdiv_qrnnd)
373 UWtype
374 __udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d)
376 UWtype q, r;
377 UWtype c0, c1, b1;
379 if ((Wtype) d >= 0)
381 if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1)))
383 /* dividend, divisor, and quotient are nonnegative */
384 sdiv_qrnnd (q, r, a1, a0, d);
386 else
388 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
389 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1));
390 /* Divide (c1*2^32 + c0) by d */
391 sdiv_qrnnd (q, r, c1, c0, d);
392 /* Add 2^31 to quotient */
393 q += (UWtype) 1 << (W_TYPE_SIZE - 1);
396 else
398 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
399 c1 = a1 >> 1; /* A/2 */
400 c0 = (a1 << (W_TYPE_SIZE - 1)) + (a0 >> 1);
402 if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
404 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
406 r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
407 if ((d & 1) != 0)
409 if (r >= q)
410 r = r - q;
411 else if (q - r <= d)
413 r = r - q + d;
414 q--;
416 else
418 r = r - q + 2*d;
419 q -= 2;
423 else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
425 c1 = (b1 - 1) - c1;
426 c0 = ~c0; /* logical NOT */
428 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
430 q = ~q; /* (A/2)/b1 */
431 r = (b1 - 1) - r;
433 r = 2*r + (a0 & 1); /* A/(2*b1) */
435 if ((d & 1) != 0)
437 if (r >= q)
438 r = r - q;
439 else if (q - r <= d)
441 r = r - q + d;
442 q--;
444 else
446 r = r - q + 2*d;
447 q -= 2;
451 else /* Implies c1 = b1 */
452 { /* Hence a1 = d - 1 = 2*b1 - 1 */
453 if (a0 >= -d)
455 q = -1;
456 r = a0 + d;
458 else
460 q = -2;
461 r = a0 + 2*d;
466 *rp = r;
467 return q;
469 #else
470 /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */
471 UWtype
472 __udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)),
473 UWtype a1 __attribute__ ((__unused__)),
474 UWtype a0 __attribute__ ((__unused__)),
475 UWtype d __attribute__ ((__unused__)))
477 return 0;
479 #endif
480 #endif
482 #if (defined (L_udivdi3) || defined (L_divdi3) || \
483 defined (L_umoddi3) || defined (L_moddi3))
484 #define L_udivmoddi4
485 #endif
487 #ifdef L_clz
488 const UQItype __clz_tab[] =
490 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,
491 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,
492 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,
493 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,
494 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,
495 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,
496 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,
497 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,
499 #endif
501 #ifdef L_udivmoddi4
503 #if (defined (L_udivdi3) || defined (L_divdi3) || \
504 defined (L_umoddi3) || defined (L_moddi3))
505 static inline
506 #endif
507 UDWtype
508 __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
510 DWunion ww;
511 DWunion nn, dd;
512 DWunion rr;
513 UWtype d0, d1, n0, n1, n2;
514 UWtype q0, q1;
515 UWtype b, bm;
517 nn.ll = n;
518 dd.ll = d;
520 d0 = dd.s.low;
521 d1 = dd.s.high;
522 n0 = nn.s.low;
523 n1 = nn.s.high;
525 #if !UDIV_NEEDS_NORMALIZATION
526 if (d1 == 0)
528 if (d0 > n1)
530 /* 0q = nn / 0D */
532 udiv_qrnnd (q0, n0, n1, n0, d0);
533 q1 = 0;
535 /* Remainder in n0. */
537 else
539 /* qq = NN / 0d */
541 if (d0 == 0)
542 d0 = 1 / d0; /* Divide intentionally by zero. */
544 udiv_qrnnd (q1, n1, 0, n1, d0);
545 udiv_qrnnd (q0, n0, n1, n0, d0);
547 /* Remainder in n0. */
550 if (rp != 0)
552 rr.s.low = n0;
553 rr.s.high = 0;
554 *rp = rr.ll;
558 #else /* UDIV_NEEDS_NORMALIZATION */
560 if (d1 == 0)
562 if (d0 > n1)
564 /* 0q = nn / 0D */
566 count_leading_zeros (bm, d0);
568 if (bm != 0)
570 /* Normalize, i.e. make the most significant bit of the
571 denominator set. */
573 d0 = d0 << bm;
574 n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
575 n0 = n0 << bm;
578 udiv_qrnnd (q0, n0, n1, n0, d0);
579 q1 = 0;
581 /* Remainder in n0 >> bm. */
583 else
585 /* qq = NN / 0d */
587 if (d0 == 0)
588 d0 = 1 / d0; /* Divide intentionally by zero. */
590 count_leading_zeros (bm, d0);
592 if (bm == 0)
594 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
595 conclude (the most significant bit of n1 is set) /\ (the
596 leading quotient digit q1 = 1).
598 This special case is necessary, not an optimization.
599 (Shifts counts of W_TYPE_SIZE are undefined.) */
601 n1 -= d0;
602 q1 = 1;
604 else
606 /* Normalize. */
608 b = W_TYPE_SIZE - bm;
610 d0 = d0 << bm;
611 n2 = n1 >> b;
612 n1 = (n1 << bm) | (n0 >> b);
613 n0 = n0 << bm;
615 udiv_qrnnd (q1, n1, n2, n1, d0);
618 /* n1 != d0... */
620 udiv_qrnnd (q0, n0, n1, n0, d0);
622 /* Remainder in n0 >> bm. */
625 if (rp != 0)
627 rr.s.low = n0 >> bm;
628 rr.s.high = 0;
629 *rp = rr.ll;
632 #endif /* UDIV_NEEDS_NORMALIZATION */
634 else
636 if (d1 > n1)
638 /* 00 = nn / DD */
640 q0 = 0;
641 q1 = 0;
643 /* Remainder in n1n0. */
644 if (rp != 0)
646 rr.s.low = n0;
647 rr.s.high = n1;
648 *rp = rr.ll;
651 else
653 /* 0q = NN / dd */
655 count_leading_zeros (bm, d1);
656 if (bm == 0)
658 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
659 conclude (the most significant bit of n1 is set) /\ (the
660 quotient digit q0 = 0 or 1).
662 This special case is necessary, not an optimization. */
664 /* The condition on the next line takes advantage of that
665 n1 >= d1 (true due to program flow). */
666 if (n1 > d1 || n0 >= d0)
668 q0 = 1;
669 sub_ddmmss (n1, n0, n1, n0, d1, d0);
671 else
672 q0 = 0;
674 q1 = 0;
676 if (rp != 0)
678 rr.s.low = n0;
679 rr.s.high = n1;
680 *rp = rr.ll;
683 else
685 UWtype m1, m0;
686 /* Normalize. */
688 b = W_TYPE_SIZE - bm;
690 d1 = (d1 << bm) | (d0 >> b);
691 d0 = d0 << bm;
692 n2 = n1 >> b;
693 n1 = (n1 << bm) | (n0 >> b);
694 n0 = n0 << bm;
696 udiv_qrnnd (q0, n1, n2, n1, d1);
697 umul_ppmm (m1, m0, q0, d0);
699 if (m1 > n1 || (m1 == n1 && m0 > n0))
701 q0--;
702 sub_ddmmss (m1, m0, m1, m0, d1, d0);
705 q1 = 0;
707 /* Remainder in (n1n0 - m1m0) >> bm. */
708 if (rp != 0)
710 sub_ddmmss (n1, n0, n1, n0, m1, m0);
711 rr.s.low = (n1 << b) | (n0 >> bm);
712 rr.s.high = n1 >> bm;
713 *rp = rr.ll;
719 ww.s.low = q0;
720 ww.s.high = q1;
721 return ww.ll;
723 #endif
725 #ifdef L_divdi3
726 DWtype
727 __divdi3 (DWtype u, DWtype v)
729 word_type c = 0;
730 DWunion uu, vv;
731 DWtype w;
733 uu.ll = u;
734 vv.ll = v;
736 if (uu.s.high < 0)
737 c = ~c,
738 uu.ll = __negdi2 (uu.ll);
739 if (vv.s.high < 0)
740 c = ~c,
741 vv.ll = __negdi2 (vv.ll);
743 w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
744 if (c)
745 w = __negdi2 (w);
747 return w;
749 #endif
751 #ifdef L_moddi3
752 DWtype
753 __moddi3 (DWtype u, DWtype v)
755 word_type c = 0;
756 DWunion uu, vv;
757 DWtype w;
759 uu.ll = u;
760 vv.ll = v;
762 if (uu.s.high < 0)
763 c = ~c,
764 uu.ll = __negdi2 (uu.ll);
765 if (vv.s.high < 0)
766 vv.ll = __negdi2 (vv.ll);
768 (void) __udivmoddi4 (uu.ll, vv.ll, &w);
769 if (c)
770 w = __negdi2 (w);
772 return w;
774 #endif
776 #ifdef L_umoddi3
777 UDWtype
778 __umoddi3 (UDWtype u, UDWtype v)
780 UDWtype w;
782 (void) __udivmoddi4 (u, v, &w);
784 return w;
786 #endif
788 #ifdef L_udivdi3
789 UDWtype
790 __udivdi3 (UDWtype n, UDWtype d)
792 return __udivmoddi4 (n, d, (UDWtype *) 0);
794 #endif
796 #ifdef L_cmpdi2
797 word_type
798 __cmpdi2 (DWtype a, DWtype b)
800 DWunion au, bu;
802 au.ll = a, bu.ll = b;
804 if (au.s.high < bu.s.high)
805 return 0;
806 else if (au.s.high > bu.s.high)
807 return 2;
808 if ((UWtype) au.s.low < (UWtype) bu.s.low)
809 return 0;
810 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
811 return 2;
812 return 1;
814 #endif
816 #ifdef L_ucmpdi2
817 word_type
818 __ucmpdi2 (DWtype a, DWtype b)
820 DWunion au, bu;
822 au.ll = a, bu.ll = b;
824 if ((UWtype) au.s.high < (UWtype) bu.s.high)
825 return 0;
826 else if ((UWtype) au.s.high > (UWtype) bu.s.high)
827 return 2;
828 if ((UWtype) au.s.low < (UWtype) bu.s.low)
829 return 0;
830 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
831 return 2;
832 return 1;
834 #endif
836 #if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
837 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
838 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
840 DWtype
841 __fixunstfDI (TFtype a)
843 TFtype b;
844 UDWtype v;
846 if (a < 0)
847 return 0;
849 /* Compute high word of result, as a flonum. */
850 b = (a / HIGH_WORD_COEFF);
851 /* Convert that to fixed (but not to DWtype!),
852 and shift it into the high word. */
853 v = (UWtype) b;
854 v <<= WORD_SIZE;
855 /* Remove high part from the TFtype, leaving the low part as flonum. */
856 a -= (TFtype)v;
857 /* Convert that to fixed (but not to DWtype!) and add it in.
858 Sometimes A comes out negative. This is significant, since
859 A has more bits than a long int does. */
860 if (a < 0)
861 v -= (UWtype) (- a);
862 else
863 v += (UWtype) a;
864 return v;
866 #endif
868 #if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
869 DWtype
870 __fixtfdi (TFtype a)
872 if (a < 0)
873 return - __fixunstfDI (-a);
874 return __fixunstfDI (a);
876 #endif
878 #if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
879 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
880 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
882 DWtype
883 __fixunsxfDI (XFtype a)
885 XFtype b;
886 UDWtype v;
888 if (a < 0)
889 return 0;
891 /* Compute high word of result, as a flonum. */
892 b = (a / HIGH_WORD_COEFF);
893 /* Convert that to fixed (but not to DWtype!),
894 and shift it into the high word. */
895 v = (UWtype) b;
896 v <<= WORD_SIZE;
897 /* Remove high part from the XFtype, leaving the low part as flonum. */
898 a -= (XFtype)v;
899 /* Convert that to fixed (but not to DWtype!) and add it in.
900 Sometimes A comes out negative. This is significant, since
901 A has more bits than a long int does. */
902 if (a < 0)
903 v -= (UWtype) (- a);
904 else
905 v += (UWtype) a;
906 return v;
908 #endif
910 #if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
911 DWtype
912 __fixxfdi (XFtype a)
914 if (a < 0)
915 return - __fixunsxfDI (-a);
916 return __fixunsxfDI (a);
918 #endif
920 #ifdef L_fixunsdfdi
921 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
922 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
924 DWtype
925 __fixunsdfDI (DFtype a)
927 DFtype b;
928 UDWtype v;
930 if (a < 0)
931 return 0;
933 /* Compute high word of result, as a flonum. */
934 b = (a / HIGH_WORD_COEFF);
935 /* Convert that to fixed (but not to DWtype!),
936 and shift it into the high word. */
937 v = (UWtype) b;
938 v <<= WORD_SIZE;
939 /* Remove high part from the DFtype, leaving the low part as flonum. */
940 a -= (DFtype)v;
941 /* Convert that to fixed (but not to DWtype!) and add it in.
942 Sometimes A comes out negative. This is significant, since
943 A has more bits than a long int does. */
944 if (a < 0)
945 v -= (UWtype) (- a);
946 else
947 v += (UWtype) a;
948 return v;
950 #endif
952 #ifdef L_fixdfdi
953 DWtype
954 __fixdfdi (DFtype a)
956 if (a < 0)
957 return - __fixunsdfDI (-a);
958 return __fixunsdfDI (a);
960 #endif
962 #ifdef L_fixunssfdi
963 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
964 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
966 DWtype
967 __fixunssfDI (SFtype original_a)
969 /* Convert the SFtype to a DFtype, because that is surely not going
970 to lose any bits. Some day someone else can write a faster version
971 that avoids converting to DFtype, and verify it really works right. */
972 DFtype a = original_a;
973 DFtype b;
974 UDWtype v;
976 if (a < 0)
977 return 0;
979 /* Compute high word of result, as a flonum. */
980 b = (a / HIGH_WORD_COEFF);
981 /* Convert that to fixed (but not to DWtype!),
982 and shift it into the high word. */
983 v = (UWtype) b;
984 v <<= WORD_SIZE;
985 /* Remove high part from the DFtype, leaving the low part as flonum. */
986 a -= (DFtype) v;
987 /* Convert that to fixed (but not to DWtype!) and add it in.
988 Sometimes A comes out negative. This is significant, since
989 A has more bits than a long int does. */
990 if (a < 0)
991 v -= (UWtype) (- a);
992 else
993 v += (UWtype) a;
994 return v;
996 #endif
998 #ifdef L_fixsfdi
999 DWtype
1000 __fixsfdi (SFtype a)
1002 if (a < 0)
1003 return - __fixunssfDI (-a);
1004 return __fixunssfDI (a);
1006 #endif
1008 #if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
1009 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1010 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1011 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1013 XFtype
1014 __floatdixf (DWtype u)
1016 XFtype d;
1018 d = (Wtype) (u >> WORD_SIZE);
1019 d *= HIGH_HALFWORD_COEFF;
1020 d *= HIGH_HALFWORD_COEFF;
1021 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1023 return d;
1025 #endif
1027 #if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
1028 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1029 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1030 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1032 TFtype
1033 __floatditf (DWtype u)
1035 TFtype d;
1037 d = (Wtype) (u >> WORD_SIZE);
1038 d *= HIGH_HALFWORD_COEFF;
1039 d *= HIGH_HALFWORD_COEFF;
1040 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1042 return d;
1044 #endif
1046 #ifdef L_floatdidf
1047 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1048 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1049 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1051 DFtype
1052 __floatdidf (DWtype u)
1054 DFtype d;
1056 d = (Wtype) (u >> WORD_SIZE);
1057 d *= HIGH_HALFWORD_COEFF;
1058 d *= HIGH_HALFWORD_COEFF;
1059 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1061 return d;
1063 #endif
1065 #ifdef L_floatdisf
1066 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1067 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1068 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1069 #define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT)
1071 /* Define codes for all the float formats that we know of. Note
1072 that this is copied from real.h. */
1074 #define UNKNOWN_FLOAT_FORMAT 0
1075 #define IEEE_FLOAT_FORMAT 1
1076 #define VAX_FLOAT_FORMAT 2
1077 #define IBM_FLOAT_FORMAT 3
1079 /* Default to IEEE float if not specified. Nearly all machines use it. */
1080 #ifndef HOST_FLOAT_FORMAT
1081 #define HOST_FLOAT_FORMAT IEEE_FLOAT_FORMAT
1082 #endif
1084 #if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1085 #define DF_SIZE 53
1086 #define SF_SIZE 24
1087 #endif
1089 #if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
1090 #define DF_SIZE 56
1091 #define SF_SIZE 24
1092 #endif
1094 #if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
1095 #define DF_SIZE 56
1096 #define SF_SIZE 24
1097 #endif
1099 SFtype
1100 __floatdisf (DWtype u)
1102 /* Do the calculation in DFmode
1103 so that we don't lose any of the precision of the high word
1104 while multiplying it. */
1105 DFtype f;
1107 /* Protect against double-rounding error.
1108 Represent any low-order bits, that might be truncated in DFmode,
1109 by a bit that won't be lost. The bit can go in anywhere below the
1110 rounding position of the SFmode. A fixed mask and bit position
1111 handles all usual configurations. It doesn't handle the case
1112 of 128-bit DImode, however. */
1113 if (DF_SIZE < DI_SIZE
1114 && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1116 #define REP_BIT ((UDWtype) 1 << (DI_SIZE - DF_SIZE))
1117 if (! (- ((DWtype) 1 << DF_SIZE) < u
1118 && u < ((DWtype) 1 << DF_SIZE)))
1120 if ((UDWtype) u & (REP_BIT - 1))
1121 u |= REP_BIT;
1124 f = (Wtype) (u >> WORD_SIZE);
1125 f *= HIGH_HALFWORD_COEFF;
1126 f *= HIGH_HALFWORD_COEFF;
1127 f += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1129 return (SFtype) f;
1131 #endif
1133 #if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
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 UWtype
1147 __fixunsxfSI (XFtype a)
1149 if (a >= - (DFtype) Wtype_MIN)
1150 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1151 return (Wtype) a;
1153 #endif
1155 #ifdef L_fixunsdfsi
1156 /* Reenable the normal types, in case limits.h needs them. */
1157 #undef char
1158 #undef short
1159 #undef int
1160 #undef long
1161 #undef unsigned
1162 #undef float
1163 #undef double
1164 #undef MIN
1165 #undef MAX
1166 #include <limits.h>
1168 UWtype
1169 __fixunsdfSI (DFtype a)
1171 if (a >= - (DFtype) Wtype_MIN)
1172 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1173 return (Wtype) a;
1175 #endif
1177 #ifdef L_fixunssfsi
1178 /* Reenable the normal types, in case limits.h needs them. */
1179 #undef char
1180 #undef short
1181 #undef int
1182 #undef long
1183 #undef unsigned
1184 #undef float
1185 #undef double
1186 #undef MIN
1187 #undef MAX
1188 #include <limits.h>
1190 UWtype
1191 __fixunssfSI (SFtype a)
1193 if (a >= - (SFtype) Wtype_MIN)
1194 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1195 return (Wtype) a;
1197 #endif
1199 /* From here on down, the routines use normal data types. */
1201 #define SItype bogus_type
1202 #define USItype bogus_type
1203 #define DItype bogus_type
1204 #define UDItype bogus_type
1205 #define SFtype bogus_type
1206 #define DFtype bogus_type
1207 #undef Wtype
1208 #undef UWtype
1209 #undef HWtype
1210 #undef UHWtype
1211 #undef DWtype
1212 #undef UDWtype
1214 #undef char
1215 #undef short
1216 #undef int
1217 #undef long
1218 #undef unsigned
1219 #undef float
1220 #undef double
1222 #ifdef L__gcc_bcmp
1224 /* Like bcmp except the sign is meaningful.
1225 Result is negative if S1 is less than S2,
1226 positive if S1 is greater, 0 if S1 and S2 are equal. */
1229 __gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
1231 while (size > 0)
1233 unsigned char c1 = *s1++, c2 = *s2++;
1234 if (c1 != c2)
1235 return c1 - c2;
1236 size--;
1238 return 0;
1241 #endif
1243 /* __eprintf used to be used by GCC's private version of <assert.h>.
1244 We no longer provide that header, but this routine remains in libgcc.a
1245 for binary backward compatibility. Note that it is not included in
1246 the shared version of libgcc. */
1247 #ifdef L_eprintf
1248 #ifndef inhibit_libc
1250 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1251 #include <stdio.h>
1253 void
1254 __eprintf (const char *string, const char *expression,
1255 unsigned int line, const char *filename)
1257 fprintf (stderr, string, expression, line, filename);
1258 fflush (stderr);
1259 abort ();
1262 #endif
1263 #endif
1265 #ifdef L_bb
1267 /* Structure emitted by -a */
1268 struct bb
1270 long zero_word;
1271 const char *filename;
1272 long *counts;
1273 long ncounts;
1274 struct bb *next;
1275 const unsigned long *addresses;
1277 /* Older GCC's did not emit these fields. */
1278 long nwords;
1279 const char **functions;
1280 const long *line_nums;
1281 const char **filenames;
1282 char *flags;
1285 #ifdef BLOCK_PROFILER_CODE
1286 BLOCK_PROFILER_CODE
1287 #else
1288 #ifndef inhibit_libc
1290 /* Simple minded basic block profiling output dumper for
1291 systems that don't provide tcov support. At present,
1292 it requires atexit and stdio. */
1294 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1295 #include <stdio.h>
1296 char *ctime PARAMS ((const time_t *));
1298 #include "gbl-ctors.h"
1299 #include "gcov-io.h"
1300 #include <string.h>
1301 #ifdef TARGET_HAS_F_SETLKW
1302 #include <fcntl.h>
1303 #include <errno.h>
1304 #endif
1306 static struct bb *bb_head;
1308 static int num_digits (long value, int base) __attribute__ ((const));
1310 /* Return the number of digits needed to print a value */
1311 /* __inline__ */ static int num_digits (long value, int base)
1313 int minus = (value < 0 && base != 16);
1314 unsigned long v = (minus) ? -value : value;
1315 int ret = minus;
1319 v /= base;
1320 ret++;
1322 while (v);
1324 return ret;
1327 void
1328 __bb_exit_func (void)
1330 FILE *da_file, *file;
1331 long time_value;
1332 int i;
1334 if (bb_head == 0)
1335 return;
1337 i = strlen (bb_head->filename) - 3;
1339 if (!strcmp (bb_head->filename+i, ".da"))
1341 /* Must be -fprofile-arcs not -a.
1342 Dump data in a form that gcov expects. */
1344 struct bb *ptr;
1346 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1348 int firstchar;
1350 /* Make sure the output file exists -
1351 but don't clobber exiting data. */
1352 if ((da_file = fopen (ptr->filename, "a")) != 0)
1353 fclose (da_file);
1355 /* Need to re-open in order to be able to write from the start. */
1356 da_file = fopen (ptr->filename, "r+b");
1357 /* Some old systems might not allow the 'b' mode modifier.
1358 Therefore, try to open without it. This can lead to a race
1359 condition so that when you delete and re-create the file, the
1360 file might be opened in text mode, but then, you shouldn't
1361 delete the file in the first place. */
1362 if (da_file == 0)
1363 da_file = fopen (ptr->filename, "r+");
1364 if (da_file == 0)
1366 fprintf (stderr, "arc profiling: Can't open output file %s.\n",
1367 ptr->filename);
1368 continue;
1371 /* After a fork, another process might try to read and/or write
1372 the same file simultanously. So if we can, lock the file to
1373 avoid race conditions. */
1374 #if defined (TARGET_HAS_F_SETLKW)
1376 struct flock s_flock;
1378 s_flock.l_type = F_WRLCK;
1379 s_flock.l_whence = SEEK_SET;
1380 s_flock.l_start = 0;
1381 s_flock.l_len = 1;
1382 s_flock.l_pid = getpid ();
1384 while (fcntl (fileno (da_file), F_SETLKW, &s_flock)
1385 && errno == EINTR);
1387 #endif
1389 /* If the file is not empty, and the number of counts in it is the
1390 same, then merge them in. */
1391 firstchar = fgetc (da_file);
1392 if (firstchar == EOF)
1394 if (ferror (da_file))
1396 fprintf (stderr, "arc profiling: Can't read output file ");
1397 perror (ptr->filename);
1400 else
1402 long n_counts = 0;
1404 if (ungetc (firstchar, da_file) == EOF)
1405 rewind (da_file);
1406 if (__read_long (&n_counts, da_file, 8) != 0)
1408 fprintf (stderr, "arc profiling: Can't read output file %s.\n",
1409 ptr->filename);
1410 continue;
1413 if (n_counts == ptr->ncounts)
1415 int i;
1417 for (i = 0; i < n_counts; i++)
1419 long v = 0;
1421 if (__read_long (&v, da_file, 8) != 0)
1423 fprintf (stderr, "arc profiling: Can't read output file %s.\n",
1424 ptr->filename);
1425 break;
1427 ptr->counts[i] += v;
1433 rewind (da_file);
1435 /* ??? Should first write a header to the file. Preferably, a 4 byte
1436 magic number, 4 bytes containing the time the program was
1437 compiled, 4 bytes containing the last modification time of the
1438 source file, and 4 bytes indicating the compiler options used.
1440 That way we can easily verify that the proper source/executable/
1441 data file combination is being used from gcov. */
1443 if (__write_long (ptr->ncounts, da_file, 8) != 0)
1446 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1447 ptr->filename);
1449 else
1451 int j;
1452 long *count_ptr = ptr->counts;
1453 int ret = 0;
1454 for (j = ptr->ncounts; j > 0; j--)
1456 if (__write_long (*count_ptr, da_file, 8) != 0)
1458 ret=1;
1459 break;
1461 count_ptr++;
1463 if (ret)
1464 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1465 ptr->filename);
1468 if (fclose (da_file) == EOF)
1469 fprintf (stderr, "arc profiling: Error closing output file %s.\n",
1470 ptr->filename);
1473 return;
1476 /* Must be basic block profiling. Emit a human readable output file. */
1478 file = fopen ("bb.out", "a");
1480 if (!file)
1481 perror ("bb.out");
1483 else
1485 struct bb *ptr;
1487 /* This is somewhat type incorrect, but it avoids worrying about
1488 exactly where time.h is included from. It should be ok unless
1489 a void * differs from other pointer formats, or if sizeof (long)
1490 is < sizeof (time_t). It would be nice if we could assume the
1491 use of rationale standards here. */
1493 time ((void *) &time_value);
1494 fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value));
1496 /* We check the length field explicitly in order to allow compatibility
1497 with older GCC's which did not provide it. */
1499 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1501 int i;
1502 int func_p = (ptr->nwords >= (long) sizeof (struct bb)
1503 && ptr->nwords <= 1000
1504 && ptr->functions);
1505 int line_p = (func_p && ptr->line_nums);
1506 int file_p = (func_p && ptr->filenames);
1507 int addr_p = (ptr->addresses != 0);
1508 long ncounts = ptr->ncounts;
1509 long cnt_max = 0;
1510 long line_max = 0;
1511 long addr_max = 0;
1512 int file_len = 0;
1513 int func_len = 0;
1514 int blk_len = num_digits (ncounts, 10);
1515 int cnt_len;
1516 int line_len;
1517 int addr_len;
1519 fprintf (file, "File %s, %ld basic blocks \n\n",
1520 ptr->filename, ncounts);
1522 /* Get max values for each field. */
1523 for (i = 0; i < ncounts; i++)
1525 const char *p;
1526 int len;
1528 if (cnt_max < ptr->counts[i])
1529 cnt_max = ptr->counts[i];
1531 if (addr_p && (unsigned long) addr_max < ptr->addresses[i])
1532 addr_max = ptr->addresses[i];
1534 if (line_p && line_max < ptr->line_nums[i])
1535 line_max = ptr->line_nums[i];
1537 if (func_p)
1539 p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>";
1540 len = strlen (p);
1541 if (func_len < len)
1542 func_len = len;
1545 if (file_p)
1547 p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>";
1548 len = strlen (p);
1549 if (file_len < len)
1550 file_len = len;
1554 addr_len = num_digits (addr_max, 16);
1555 cnt_len = num_digits (cnt_max, 10);
1556 line_len = num_digits (line_max, 10);
1558 /* Now print out the basic block information. */
1559 for (i = 0; i < ncounts; i++)
1561 fprintf (file,
1562 " Block #%*d: executed %*ld time(s)",
1563 blk_len, i+1,
1564 cnt_len, ptr->counts[i]);
1566 if (addr_p)
1567 fprintf (file, " address= 0x%.*lx", addr_len,
1568 ptr->addresses[i]);
1570 if (func_p)
1571 fprintf (file, " function= %-*s", func_len,
1572 (ptr->functions[i]) ? ptr->functions[i] : "<none>");
1574 if (line_p)
1575 fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]);
1577 if (file_p)
1578 fprintf (file, " file= %s",
1579 (ptr->filenames[i]) ? ptr->filenames[i] : "<none>");
1581 fprintf (file, "\n");
1584 fprintf (file, "\n");
1585 fflush (file);
1588 fprintf (file, "\n\n");
1589 fclose (file);
1593 void
1594 __bb_init_func (struct bb *blocks)
1596 /* User is supposed to check whether the first word is non-0,
1597 but just in case.... */
1599 if (blocks->zero_word)
1600 return;
1602 /* Initialize destructor. */
1603 if (!bb_head)
1604 atexit (__bb_exit_func);
1606 /* Set up linked list. */
1607 blocks->zero_word = 1;
1608 blocks->next = bb_head;
1609 bb_head = blocks;
1612 /* Called before fork or exec - write out profile information gathered so
1613 far and reset it to zero. This avoids duplication or loss of the
1614 profile information gathered so far. */
1615 void
1616 __bb_fork_func (void)
1618 struct bb *ptr;
1620 __bb_exit_func ();
1621 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1623 long i;
1624 for (i = ptr->ncounts - 1; i >= 0; i--)
1625 ptr->counts[i] = 0;
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 /* Number of buckets in hashtable of basic block addresses. */
1638 #define BB_BUCKETS 311
1640 /* Maximum length of string in file bb.in. */
1642 #define BBINBUFSIZE 500
1644 struct bb_edge
1646 struct bb_edge *next;
1647 unsigned long src_addr;
1648 unsigned long dst_addr;
1649 unsigned long count;
1652 enum bb_func_mode
1654 TRACE_KEEP = 0, TRACE_ON = 1, TRACE_OFF = 2
1657 struct bb_func
1659 struct bb_func *next;
1660 char *funcname;
1661 char *filename;
1662 enum bb_func_mode mode;
1665 /* This is the connection to the outside world.
1666 The BLOCK_PROFILER macro must set __bb.blocks
1667 and __bb.blockno. */
1669 struct {
1670 unsigned long blockno;
1671 struct bb *blocks;
1672 } __bb;
1674 /* Vars to store addrs of source and destination basic blocks
1675 of a jump. */
1677 static unsigned long bb_src = 0;
1678 static unsigned long bb_dst = 0;
1680 static FILE *bb_tracefile = (FILE *) 0;
1681 static struct bb_edge **bb_hashbuckets = (struct bb_edge **) 0;
1682 static struct bb_func *bb_func_head = (struct bb_func *) 0;
1683 static unsigned long bb_callcount = 0;
1684 static int bb_mode = 0;
1686 static unsigned long *bb_stack = (unsigned long *) 0;
1687 static size_t bb_stacksize = 0;
1689 static int reported = 0;
1691 /* Trace modes:
1692 Always : Print execution frequencies of basic blocks
1693 to file bb.out.
1694 bb_mode & 1 != 0 : Dump trace of basic blocks to file bbtrace[.gz]
1695 bb_mode & 2 != 0 : Print jump frequencies to file bb.out.
1696 bb_mode & 4 != 0 : Cut call instructions from basic block flow.
1697 bb_mode & 8 != 0 : Insert return instructions in basic block flow.
1700 #ifdef HAVE_POPEN
1702 /*#include <sys/types.h>*/
1703 #include <sys/stat.h>
1704 /*#include <malloc.h>*/
1706 /* Commands executed by gopen. */
1708 #define GOPENDECOMPRESS "gzip -cd "
1709 #define GOPENCOMPRESS "gzip -c >"
1711 /* Like fopen but pipes through gzip. mode may only be "r" or "w".
1712 If it does not compile, simply replace gopen by fopen and delete
1713 '.gz' from any first parameter to gopen. */
1715 static FILE *
1716 gopen (char *fn, char *mode)
1718 int use_gzip;
1719 char *p;
1721 if (mode[1])
1722 return (FILE *) 0;
1724 if (mode[0] != 'r' && mode[0] != 'w')
1725 return (FILE *) 0;
1727 p = fn + strlen (fn)-1;
1728 use_gzip = ((p[-1] == '.' && (p[0] == 'Z' || p[0] == 'z'))
1729 || (p[-2] == '.' && p[-1] == 'g' && p[0] == 'z'));
1731 if (use_gzip)
1733 if (mode[0]=='r')
1735 FILE *f;
1736 char *s = (char *) malloc (sizeof (char) * strlen (fn)
1737 + sizeof (GOPENDECOMPRESS));
1738 strcpy (s, GOPENDECOMPRESS);
1739 strcpy (s + (sizeof (GOPENDECOMPRESS)-1), fn);
1740 f = popen (s, mode);
1741 free (s);
1742 return f;
1745 else
1747 FILE *f;
1748 char *s = (char *) malloc (sizeof (char) * strlen (fn)
1749 + sizeof (GOPENCOMPRESS));
1750 strcpy (s, GOPENCOMPRESS);
1751 strcpy (s + (sizeof (GOPENCOMPRESS)-1), fn);
1752 if (!(f = popen (s, mode)))
1753 f = fopen (s, mode);
1754 free (s);
1755 return f;
1759 else
1760 return fopen (fn, mode);
1763 static int
1764 gclose (FILE *f)
1766 struct stat buf;
1768 if (f != 0)
1770 if (!fstat (fileno (f), &buf) && S_ISFIFO (buf.st_mode))
1771 return pclose (f);
1773 return fclose (f);
1775 return 0;
1778 #endif /* HAVE_POPEN */
1780 /* Called once per program. */
1782 static void
1783 __bb_exit_trace_func (void)
1785 FILE *file = fopen ("bb.out", "a");
1786 struct bb_func *f;
1787 struct bb *b;
1789 if (!file)
1790 perror ("bb.out");
1792 if (bb_mode & 1)
1794 if (!bb_tracefile)
1795 perror ("bbtrace");
1796 else
1797 #ifdef HAVE_POPEN
1798 gclose (bb_tracefile);
1799 #else
1800 fclose (bb_tracefile);
1801 #endif /* HAVE_POPEN */
1804 /* Check functions in `bb.in'. */
1806 if (file)
1808 long time_value;
1809 const struct bb_func *p;
1810 int printed_something = 0;
1811 struct bb *ptr;
1812 long blk;
1814 /* This is somewhat type incorrect. */
1815 time ((void *) &time_value);
1817 for (p = bb_func_head; p != (struct bb_func *) 0; p = p->next)
1819 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1821 if (!ptr->filename || (p->filename != (char *) 0 && strcmp (p->filename, ptr->filename)))
1822 continue;
1823 for (blk = 0; blk < ptr->ncounts; blk++)
1825 if (!strcmp (p->funcname, ptr->functions[blk]))
1826 goto found;
1830 if (!printed_something)
1832 fprintf (file, "Functions in `bb.in' not executed during basic block profiling on %s\n", ctime ((void *) &time_value));
1833 printed_something = 1;
1836 fprintf (file, "\tFunction %s", p->funcname);
1837 if (p->filename)
1838 fprintf (file, " of file %s", p->filename);
1839 fprintf (file, "\n" );
1841 found: ;
1844 if (printed_something)
1845 fprintf (file, "\n");
1849 if (bb_mode & 2)
1851 if (!bb_hashbuckets)
1853 if (!reported)
1855 fprintf (stderr, "Profiler: out of memory\n");
1856 reported = 1;
1858 return;
1861 else if (file)
1863 long time_value;
1864 int i;
1865 unsigned long addr_max = 0;
1866 unsigned long cnt_max = 0;
1867 int cnt_len;
1868 int addr_len;
1870 /* This is somewhat type incorrect, but it avoids worrying about
1871 exactly where time.h is included from. It should be ok unless
1872 a void * differs from other pointer formats, or if sizeof (long)
1873 is < sizeof (time_t). It would be nice if we could assume the
1874 use of rationale standards here. */
1876 time ((void *) &time_value);
1877 fprintf (file, "Basic block jump tracing");
1879 switch (bb_mode & 12)
1881 case 0:
1882 fprintf (file, " (with call)");
1883 break;
1885 case 4:
1886 /* Print nothing. */
1887 break;
1889 case 8:
1890 fprintf (file, " (with call & ret)");
1891 break;
1893 case 12:
1894 fprintf (file, " (with ret)");
1895 break;
1898 fprintf (file, " finished on %s\n", ctime ((void *) &time_value));
1900 for (i = 0; i < BB_BUCKETS; i++)
1902 struct bb_edge *bucket = bb_hashbuckets[i];
1903 for ( ; bucket; bucket = bucket->next )
1905 if (addr_max < bucket->src_addr)
1906 addr_max = bucket->src_addr;
1907 if (addr_max < bucket->dst_addr)
1908 addr_max = bucket->dst_addr;
1909 if (cnt_max < bucket->count)
1910 cnt_max = bucket->count;
1913 addr_len = num_digits (addr_max, 16);
1914 cnt_len = num_digits (cnt_max, 10);
1916 for ( i = 0; i < BB_BUCKETS; i++)
1918 struct bb_edge *bucket = bb_hashbuckets[i];
1919 for ( ; bucket; bucket = bucket->next )
1921 fprintf (file,
1922 "Jump from block 0x%.*lx to block 0x%.*lx executed %*lu time(s)\n",
1923 addr_len, bucket->src_addr,
1924 addr_len, bucket->dst_addr,
1925 cnt_len, bucket->count);
1929 fprintf (file, "\n");
1934 if (file)
1935 fclose (file);
1937 /* Free allocated memory. */
1939 f = bb_func_head;
1940 while (f)
1942 struct bb_func *old = f;
1944 f = f->next;
1945 if (old->funcname) free (old->funcname);
1946 if (old->filename) free (old->filename);
1947 free (old);
1950 if (bb_stack)
1951 free (bb_stack);
1953 if (bb_hashbuckets)
1955 int i;
1957 for (i = 0; i < BB_BUCKETS; i++)
1959 struct bb_edge *old, *bucket = bb_hashbuckets[i];
1961 while (bucket)
1963 old = bucket;
1964 bucket = bucket->next;
1965 free (old);
1968 free (bb_hashbuckets);
1971 for (b = bb_head; b; b = b->next)
1972 if (b->flags) free (b->flags);
1975 /* Called once per program. */
1977 static void
1978 __bb_init_prg (void)
1980 FILE *file;
1981 char buf[BBINBUFSIZE];
1982 const char *p;
1983 const char *pos;
1984 enum bb_func_mode m;
1985 int i;
1987 /* Initialize destructor. */
1988 atexit (__bb_exit_func);
1990 if (!(file = fopen ("bb.in", "r")))
1991 return;
1993 while(fgets (buf, BBINBUFSIZE, file) != 0)
1995 i = strlen (buf);
1996 if (buf[i] == '\n')
1997 buf[i--] = '\0';
1999 p = buf;
2000 if (*p == '-')
2002 m = TRACE_OFF;
2003 p++;
2005 else
2007 m = TRACE_ON;
2009 if (!strcmp (p, "__bb_trace__"))
2010 bb_mode |= 1;
2011 else if (!strcmp (p, "__bb_jumps__"))
2012 bb_mode |= 2;
2013 else if (!strcmp (p, "__bb_hidecall__"))
2014 bb_mode |= 4;
2015 else if (!strcmp (p, "__bb_showret__"))
2016 bb_mode |= 8;
2017 else
2019 struct bb_func *f = (struct bb_func *) malloc (sizeof (struct bb_func));
2020 if (f)
2022 unsigned long l;
2023 f->next = bb_func_head;
2024 if ((pos = strchr (p, ':')))
2026 if (!(f->funcname = (char *) malloc (strlen (pos+1)+1)))
2027 continue;
2028 strcpy (f->funcname, pos+1);
2029 l = pos-p;
2030 if ((f->filename = (char *) malloc (l+1)))
2032 strncpy (f->filename, p, l);
2033 f->filename[l] = '\0';
2035 else
2036 f->filename = (char *) 0;
2038 else
2040 if (!(f->funcname = (char *) malloc (strlen (p)+1)))
2041 continue;
2042 strcpy (f->funcname, p);
2043 f->filename = (char *) 0;
2045 f->mode = m;
2046 bb_func_head = f;
2050 fclose (file);
2052 #ifdef HAVE_POPEN
2054 if (bb_mode & 1)
2055 bb_tracefile = gopen ("bbtrace.gz", "w");
2057 #else
2059 if (bb_mode & 1)
2060 bb_tracefile = fopen ("bbtrace", "w");
2062 #endif /* HAVE_POPEN */
2064 if (bb_mode & 2)
2066 bb_hashbuckets = (struct bb_edge **)
2067 malloc (BB_BUCKETS * sizeof (struct bb_edge *));
2068 if (bb_hashbuckets)
2069 /* Use a loop here rather than calling bzero to avoid having to
2070 conditionalize its existance. */
2071 for (i = 0; i < BB_BUCKETS; i++)
2072 bb_hashbuckets[i] = 0;
2075 if (bb_mode & 12)
2077 bb_stacksize = 10;
2078 bb_stack = (unsigned long *) malloc (bb_stacksize * sizeof (*bb_stack));
2081 /* Initialize destructor. */
2082 atexit (__bb_exit_trace_func);
2085 /* Called upon entering a basic block. */
2087 void
2088 __bb_trace_func (void)
2090 struct bb_edge *bucket;
2092 MACHINE_STATE_SAVE("1")
2094 if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2095 goto skip;
2097 bb_dst = __bb.blocks->addresses[__bb.blockno];
2098 __bb.blocks->counts[__bb.blockno]++;
2100 if (bb_tracefile)
2102 fwrite (&bb_dst, sizeof (unsigned long), 1, bb_tracefile);
2105 if (bb_hashbuckets)
2107 struct bb_edge **startbucket, **oldnext;
2109 oldnext = startbucket
2110 = & bb_hashbuckets[ (((int) bb_src*8) ^ (int) bb_dst) % BB_BUCKETS ];
2111 bucket = *startbucket;
2113 for (bucket = *startbucket; bucket;
2114 oldnext = &(bucket->next), bucket = *oldnext)
2116 if (bucket->src_addr == bb_src
2117 && bucket->dst_addr == bb_dst)
2119 bucket->count++;
2120 *oldnext = bucket->next;
2121 bucket->next = *startbucket;
2122 *startbucket = bucket;
2123 goto ret;
2127 bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2129 if (!bucket)
2131 if (!reported)
2133 fprintf (stderr, "Profiler: out of memory\n");
2134 reported = 1;
2138 else
2140 bucket->src_addr = bb_src;
2141 bucket->dst_addr = bb_dst;
2142 bucket->next = *startbucket;
2143 *startbucket = bucket;
2144 bucket->count = 1;
2148 ret:
2149 bb_src = bb_dst;
2151 skip:
2154 MACHINE_STATE_RESTORE("1")
2158 /* Called when returning from a function and `__bb_showret__' is set. */
2160 static void
2161 __bb_trace_func_ret (void)
2163 struct bb_edge *bucket;
2165 if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2166 goto skip;
2168 if (bb_hashbuckets)
2170 struct bb_edge **startbucket, **oldnext;
2172 oldnext = startbucket
2173 = & bb_hashbuckets[ (((int) bb_dst * 8) ^ (int) bb_src) % BB_BUCKETS ];
2174 bucket = *startbucket;
2176 for (bucket = *startbucket; bucket;
2177 oldnext = &(bucket->next), bucket = *oldnext)
2179 if (bucket->src_addr == bb_dst
2180 && bucket->dst_addr == bb_src)
2182 bucket->count++;
2183 *oldnext = bucket->next;
2184 bucket->next = *startbucket;
2185 *startbucket = bucket;
2186 goto ret;
2190 bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2192 if (!bucket)
2194 if (!reported)
2196 fprintf (stderr, "Profiler: out of memory\n");
2197 reported = 1;
2201 else
2203 bucket->src_addr = bb_dst;
2204 bucket->dst_addr = bb_src;
2205 bucket->next = *startbucket;
2206 *startbucket = bucket;
2207 bucket->count = 1;
2211 ret:
2212 bb_dst = bb_src;
2214 skip:
2219 /* Called upon entering the first function of a file. */
2221 static void
2222 __bb_init_file (struct bb *blocks)
2225 const struct bb_func *p;
2226 long blk, ncounts = blocks->ncounts;
2227 const char **functions = blocks->functions;
2229 /* Set up linked list. */
2230 blocks->zero_word = 1;
2231 blocks->next = bb_head;
2232 bb_head = blocks;
2234 blocks->flags = 0;
2235 if (!bb_func_head
2236 || !(blocks->flags = (char *) malloc (sizeof (char) * blocks->ncounts)))
2237 return;
2239 for (blk = 0; blk < ncounts; blk++)
2240 blocks->flags[blk] = 0;
2242 for (blk = 0; blk < ncounts; blk++)
2244 for (p = bb_func_head; p; p = p->next)
2246 if (!strcmp (p->funcname, functions[blk])
2247 && (!p->filename || !strcmp (p->filename, blocks->filename)))
2249 blocks->flags[blk] |= p->mode;
2256 /* Called when exiting from a function. */
2258 void
2259 __bb_trace_ret (void)
2262 MACHINE_STATE_SAVE("2")
2264 if (bb_callcount)
2266 if ((bb_mode & 12) && bb_stacksize > bb_callcount)
2268 bb_src = bb_stack[bb_callcount];
2269 if (bb_mode & 8)
2270 __bb_trace_func_ret ();
2273 bb_callcount -= 1;
2276 MACHINE_STATE_RESTORE("2")
2280 /* Called when entering a function. */
2282 void
2283 __bb_init_trace_func (struct bb *blocks, unsigned long blockno)
2285 static int trace_init = 0;
2287 MACHINE_STATE_SAVE("3")
2289 if (!blocks->zero_word)
2291 if (!trace_init)
2293 trace_init = 1;
2294 __bb_init_prg ();
2296 __bb_init_file (blocks);
2299 if (bb_callcount)
2302 bb_callcount += 1;
2304 if (bb_mode & 12)
2306 if (bb_callcount >= bb_stacksize)
2308 size_t newsize = bb_callcount + 100;
2310 bb_stack = (unsigned long *) realloc (bb_stack, newsize);
2311 if (! bb_stack)
2313 if (!reported)
2315 fprintf (stderr, "Profiler: out of memory\n");
2316 reported = 1;
2318 bb_stacksize = 0;
2319 goto stack_overflow;
2321 bb_stacksize = newsize;
2323 bb_stack[bb_callcount] = bb_src;
2325 if (bb_mode & 4)
2326 bb_src = 0;
2330 stack_overflow:;
2334 else if (blocks->flags && (blocks->flags[blockno] & TRACE_ON))
2336 bb_callcount = 1;
2337 bb_src = 0;
2339 if (bb_stack)
2340 bb_stack[bb_callcount] = bb_src;
2343 MACHINE_STATE_RESTORE("3")
2346 #endif /* not inhibit_libc */
2347 #endif /* not BLOCK_PROFILER_CODE */
2348 #endif /* L_bb */
2350 #ifdef L_clear_cache
2351 /* Clear part of an instruction cache. */
2353 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
2355 void
2356 __clear_cache (char *beg __attribute__((__unused__)),
2357 char *end __attribute__((__unused__)))
2359 #ifdef CLEAR_INSN_CACHE
2360 CLEAR_INSN_CACHE (beg, end);
2361 #else
2362 #ifdef INSN_CACHE_SIZE
2363 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
2364 static int initialized;
2365 int offset;
2366 void *start_addr
2367 void *end_addr;
2368 typedef (*function_ptr) (void);
2370 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
2371 /* It's cheaper to clear the whole cache.
2372 Put in a series of jump instructions so that calling the beginning
2373 of the cache will clear the whole thing. */
2375 if (! initialized)
2377 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2378 & -INSN_CACHE_LINE_WIDTH);
2379 int end_ptr = ptr + INSN_CACHE_SIZE;
2381 while (ptr < end_ptr)
2383 *(INSTRUCTION_TYPE *)ptr
2384 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
2385 ptr += INSN_CACHE_LINE_WIDTH;
2387 *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
2389 initialized = 1;
2392 /* Call the beginning of the sequence. */
2393 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2394 & -INSN_CACHE_LINE_WIDTH))
2395 ());
2397 #else /* Cache is large. */
2399 if (! initialized)
2401 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2402 & -INSN_CACHE_LINE_WIDTH);
2404 while (ptr < (int) array + sizeof array)
2406 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
2407 ptr += INSN_CACHE_LINE_WIDTH;
2410 initialized = 1;
2413 /* Find the location in array that occupies the same cache line as BEG. */
2415 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
2416 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
2417 & -INSN_CACHE_PLANE_SIZE)
2418 + offset);
2420 /* Compute the cache alignment of the place to stop clearing. */
2421 #if 0 /* This is not needed for gcc's purposes. */
2422 /* If the block to clear is bigger than a cache plane,
2423 we clear the entire cache, and OFFSET is already correct. */
2424 if (end < beg + INSN_CACHE_PLANE_SIZE)
2425 #endif
2426 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
2427 & -INSN_CACHE_LINE_WIDTH)
2428 & (INSN_CACHE_PLANE_SIZE - 1));
2430 #if INSN_CACHE_DEPTH > 1
2431 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
2432 if (end_addr <= start_addr)
2433 end_addr += INSN_CACHE_PLANE_SIZE;
2435 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
2437 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
2438 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
2440 while (addr != stop)
2442 /* Call the return instruction at ADDR. */
2443 ((function_ptr) addr) ();
2445 addr += INSN_CACHE_LINE_WIDTH;
2448 #else /* just one plane */
2451 /* Call the return instruction at START_ADDR. */
2452 ((function_ptr) start_addr) ();
2454 start_addr += INSN_CACHE_LINE_WIDTH;
2456 while ((start_addr % INSN_CACHE_SIZE) != offset);
2457 #endif /* just one plane */
2458 #endif /* Cache is large */
2459 #endif /* Cache exists */
2460 #endif /* CLEAR_INSN_CACHE */
2463 #endif /* L_clear_cache */
2465 #ifdef L_trampoline
2467 /* Jump to a trampoline, loading the static chain address. */
2469 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
2471 long
2472 getpagesize (void)
2474 #ifdef _ALPHA_
2475 return 8192;
2476 #else
2477 return 4096;
2478 #endif
2481 #ifdef __i386__
2482 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
2483 #endif
2486 mprotect (char *addr, int len, int prot)
2488 int np, op;
2490 if (prot == 7)
2491 np = 0x40;
2492 else if (prot == 5)
2493 np = 0x20;
2494 else if (prot == 4)
2495 np = 0x10;
2496 else if (prot == 3)
2497 np = 0x04;
2498 else if (prot == 1)
2499 np = 0x02;
2500 else if (prot == 0)
2501 np = 0x01;
2503 if (VirtualProtect (addr, len, np, &op))
2504 return 0;
2505 else
2506 return -1;
2509 #endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
2511 #ifdef TRANSFER_FROM_TRAMPOLINE
2512 TRANSFER_FROM_TRAMPOLINE
2513 #endif
2515 #if defined (NeXT) && defined (__MACH__)
2517 /* Make stack executable so we can call trampolines on stack.
2518 This is called from INITIALIZE_TRAMPOLINE in next.h. */
2519 #ifdef NeXTStep21
2520 #include <mach.h>
2521 #else
2522 #include <mach/mach.h>
2523 #endif
2525 void
2526 __enable_execute_stack (char *addr)
2528 kern_return_t r;
2529 char *eaddr = addr + TRAMPOLINE_SIZE;
2530 vm_address_t a = (vm_address_t) addr;
2532 /* turn on execute access on stack */
2533 r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
2534 if (r != KERN_SUCCESS)
2536 mach_error("vm_protect VM_PROT_ALL", r);
2537 exit(1);
2540 /* We inline the i-cache invalidation for speed */
2542 #ifdef CLEAR_INSN_CACHE
2543 CLEAR_INSN_CACHE (addr, eaddr);
2544 #else
2545 __clear_cache ((int) addr, (int) eaddr);
2546 #endif
2549 #endif /* defined (NeXT) && defined (__MACH__) */
2551 #ifdef __convex__
2553 /* Make stack executable so we can call trampolines on stack.
2554 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
2556 #include <sys/mman.h>
2557 #include <sys/vmparam.h>
2558 #include <machine/machparam.h>
2560 void
2561 __enable_execute_stack (void)
2563 int fp;
2564 static unsigned lowest = USRSTACK;
2565 unsigned current = (unsigned) &fp & -NBPG;
2567 if (lowest > current)
2569 unsigned len = lowest - current;
2570 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
2571 lowest = current;
2574 /* Clear instruction cache in case an old trampoline is in it. */
2575 asm ("pich");
2577 #endif /* __convex__ */
2579 #ifdef __sysV88__
2581 /* Modified from the convex -code above. */
2583 #include <sys/param.h>
2584 #include <errno.h>
2585 #include <sys/m88kbcs.h>
2587 void
2588 __enable_execute_stack (void)
2590 int save_errno;
2591 static unsigned long lowest = USRSTACK;
2592 unsigned long current = (unsigned long) &save_errno & -NBPC;
2594 /* Ignore errno being set. memctl sets errno to EINVAL whenever the
2595 address is seen as 'negative'. That is the case with the stack. */
2597 save_errno=errno;
2598 if (lowest > current)
2600 unsigned len=lowest-current;
2601 memctl(current,len,MCT_TEXT);
2602 lowest = current;
2604 else
2605 memctl(current,NBPC,MCT_TEXT);
2606 errno=save_errno;
2609 #endif /* __sysV88__ */
2611 #ifdef __sysV68__
2613 #include <sys/signal.h>
2614 #include <errno.h>
2616 /* Motorola forgot to put memctl.o in the libp version of libc881.a,
2617 so define it here, because we need it in __clear_insn_cache below */
2618 /* On older versions of this OS, no memctl or MCT_TEXT are defined;
2619 hence we enable this stuff only if MCT_TEXT is #define'd. */
2621 #ifdef MCT_TEXT
2622 asm("\n\
2623 global memctl\n\
2624 memctl:\n\
2625 movq &75,%d0\n\
2626 trap &0\n\
2627 bcc.b noerror\n\
2628 jmp cerror%\n\
2629 noerror:\n\
2630 movq &0,%d0\n\
2631 rts");
2632 #endif
2634 /* Clear instruction cache so we can call trampolines on stack.
2635 This is called from FINALIZE_TRAMPOLINE in mot3300.h. */
2637 void
2638 __clear_insn_cache (void)
2640 #ifdef MCT_TEXT
2641 int save_errno;
2643 /* Preserve errno, because users would be surprised to have
2644 errno changing without explicitly calling any system-call. */
2645 save_errno = errno;
2647 /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache.
2648 No need to use an address derived from _start or %sp, as 0 works also. */
2649 memctl(0, 4096, MCT_TEXT);
2650 errno = save_errno;
2651 #endif
2654 #endif /* __sysV68__ */
2656 #ifdef __pyr__
2658 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2659 #include <stdio.h>
2660 #include <sys/mman.h>
2661 #include <sys/types.h>
2662 #include <sys/param.h>
2663 #include <sys/vmmac.h>
2665 /* Modified from the convex -code above.
2666 mremap promises to clear the i-cache. */
2668 void
2669 __enable_execute_stack (void)
2671 int fp;
2672 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
2673 PROT_READ|PROT_WRITE|PROT_EXEC))
2675 perror ("mprotect in __enable_execute_stack");
2676 fflush (stderr);
2677 abort ();
2680 #endif /* __pyr__ */
2682 #if defined (sony_news) && defined (SYSTYPE_BSD)
2684 #include <stdio.h>
2685 #include <sys/types.h>
2686 #include <sys/param.h>
2687 #include <syscall.h>
2688 #include <machine/sysnews.h>
2690 /* cacheflush function for NEWS-OS 4.2.
2691 This function is called from trampoline-initialize code
2692 defined in config/mips/mips.h. */
2694 void
2695 cacheflush (char *beg, int size, int flag)
2697 if (syscall (SYS_sysnews, NEWS_CACHEFLUSH, beg, size, FLUSH_BCACHE))
2699 perror ("cache_flush");
2700 fflush (stderr);
2701 abort ();
2705 #endif /* sony_news */
2706 #endif /* L_trampoline */
2708 #ifndef __CYGWIN__
2709 #ifdef L__main
2711 #include "gbl-ctors.h"
2712 /* Some systems use __main in a way incompatible with its use in gcc, in these
2713 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2714 give the same symbol without quotes for an alternative entry point. You
2715 must define both, or neither. */
2716 #ifndef NAME__MAIN
2717 #define NAME__MAIN "__main"
2718 #define SYMBOL__MAIN __main
2719 #endif
2721 #ifdef INIT_SECTION_ASM_OP
2722 #undef HAS_INIT_SECTION
2723 #define HAS_INIT_SECTION
2724 #endif
2726 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
2728 /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
2729 code to run constructors. In that case, we need to handle EH here, too. */
2731 #ifdef EH_FRAME_SECTION
2732 #include "unwind-dw2-fde.h"
2733 extern unsigned char __EH_FRAME_BEGIN__[];
2734 #endif
2736 /* Run all the global destructors on exit from the program. */
2738 void
2739 __do_global_dtors (void)
2741 #ifdef DO_GLOBAL_DTORS_BODY
2742 DO_GLOBAL_DTORS_BODY;
2743 #else
2744 static func_ptr *p = __DTOR_LIST__ + 1;
2745 while (*p)
2747 p++;
2748 (*(p-1)) ();
2750 #endif
2751 #if defined (EH_FRAME_SECTION) && !defined (HAS_INIT_SECTION)
2753 static int completed = 0;
2754 if (! completed)
2756 completed = 1;
2757 __deregister_frame_info (__EH_FRAME_BEGIN__);
2760 #endif
2762 #endif
2764 #ifndef HAS_INIT_SECTION
2765 /* Run all the global constructors on entry to the program. */
2767 void
2768 __do_global_ctors (void)
2770 #ifdef EH_FRAME_SECTION
2772 static struct object object;
2773 __register_frame_info (__EH_FRAME_BEGIN__, &object);
2775 #endif
2776 DO_GLOBAL_CTORS_BODY;
2777 atexit (__do_global_dtors);
2779 #endif /* no HAS_INIT_SECTION */
2781 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
2782 /* Subroutine called automatically by `main'.
2783 Compiling a global function named `main'
2784 produces an automatic call to this function at the beginning.
2786 For many systems, this routine calls __do_global_ctors.
2787 For systems which support a .init section we use the .init section
2788 to run __do_global_ctors, so we need not do anything here. */
2790 void
2791 SYMBOL__MAIN ()
2793 /* Support recursive calls to `main': run initializers just once. */
2794 static int initialized;
2795 if (! initialized)
2797 initialized = 1;
2798 __do_global_ctors ();
2801 #endif /* no HAS_INIT_SECTION or INVOKE__main */
2803 #endif /* L__main */
2804 #endif /* __CYGWIN__ */
2806 #ifdef L_ctors
2808 #include "gbl-ctors.h"
2810 /* Provide default definitions for the lists of constructors and
2811 destructors, so that we don't get linker errors. These symbols are
2812 intentionally bss symbols, so that gld and/or collect will provide
2813 the right values. */
2815 /* We declare the lists here with two elements each,
2816 so that they are valid empty lists if no other definition is loaded.
2818 If we are using the old "set" extensions to have the gnu linker
2819 collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
2820 must be in the bss/common section.
2822 Long term no port should use those extensions. But many still do. */
2823 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
2824 #if defined (ASM_OUTPUT_CONSTRUCTOR) || defined (USE_COLLECT2)
2825 func_ptr __CTOR_LIST__[2] = {0, 0};
2826 func_ptr __DTOR_LIST__[2] = {0, 0};
2827 #else
2828 func_ptr __CTOR_LIST__[2];
2829 func_ptr __DTOR_LIST__[2];
2830 #endif
2831 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
2832 #endif /* L_ctors */
2834 #ifdef L_exit
2836 #include "gbl-ctors.h"
2838 #ifdef NEED_ATEXIT
2840 #ifndef ON_EXIT
2842 # include <errno.h>
2844 static func_ptr *atexit_chain = 0;
2845 static long atexit_chain_length = 0;
2846 static volatile long last_atexit_chain_slot = -1;
2849 atexit (func_ptr func)
2851 if (++last_atexit_chain_slot == atexit_chain_length)
2853 atexit_chain_length += 32;
2854 if (atexit_chain)
2855 atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
2856 * sizeof (func_ptr));
2857 else
2858 atexit_chain = (func_ptr *) malloc (atexit_chain_length
2859 * sizeof (func_ptr));
2860 if (! atexit_chain)
2862 atexit_chain_length = 0;
2863 last_atexit_chain_slot = -1;
2864 errno = ENOMEM;
2865 return (-1);
2868 atexit_chain[last_atexit_chain_slot] = func;
2869 return (0);
2872 extern void _cleanup (void);
2873 extern void _exit (int) __attribute__ ((__noreturn__));
2875 void
2876 exit (int status)
2878 if (atexit_chain)
2880 for ( ; last_atexit_chain_slot-- >= 0; )
2882 (*atexit_chain[last_atexit_chain_slot + 1]) ();
2883 atexit_chain[last_atexit_chain_slot + 1] = 0;
2885 free (atexit_chain);
2886 atexit_chain = 0;
2888 #ifdef EXIT_BODY
2889 EXIT_BODY;
2890 #else
2891 _cleanup ();
2892 #endif
2893 _exit (status);
2896 #else /* ON_EXIT */
2898 /* Simple; we just need a wrapper for ON_EXIT. */
2900 atexit (func_ptr func)
2902 return ON_EXIT (func);
2905 #endif /* ON_EXIT */
2906 #endif /* NEED_ATEXIT */
2908 #endif /* L_exit */