* m68k/m68k.c (m68k_last_compare_had_fp_operands): New variable.
[official-gcc.git] / gcc / libgcc2.c
blob16b15fff3f85e0c7d2ae441a2cdfcb50588e3aa2
1 /* More subroutines needed by GCC output code on some machines. */
2 /* Compile this one with gcc. */
3 /* Copyright (C) 1989, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* As a special exception, if you link this library with other files,
23 some of which are compiled with GCC, to produce an executable,
24 this library does not by itself cause the resulting executable
25 to be covered by the GNU General Public License.
26 This exception does not however invalidate any other reasons why
27 the executable file might be covered by the GNU General Public License. */
29 /* It is incorrect to include config.h here, because this file is being
30 compiled for the target, and hence definitions concerning only the host
31 do not apply. */
33 #include "tconfig.h"
34 #include "machmode.h"
35 #include "defaults.h"
36 #ifndef L_trampoline
37 #include <stddef.h>
38 #endif
40 /* Don't use `fancy_abort' here even if config.h says to use it. */
41 #ifdef abort
42 #undef abort
43 #endif
45 #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 (DItype u)
143 DIunion w;
144 DIunion uu;
146 uu.ll = u;
148 w.s.low = -uu.s.low;
149 w.s.high = -uu.s.high - ((USItype) w.s.low > 0);
151 return w.ll;
153 #endif
155 /* Unless shift functions are defined whith full ANSI prototypes,
156 parameter b will be promoted to int if word_type is smaller than an int. */
157 #ifdef L_lshrdi3
158 DItype
159 __lshrdi3 (DItype u, word_type b)
161 DIunion w;
162 word_type bm;
163 DIunion uu;
165 if (b == 0)
166 return u;
168 uu.ll = u;
170 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
171 if (bm <= 0)
173 w.s.high = 0;
174 w.s.low = (USItype)uu.s.high >> -bm;
176 else
178 USItype carries = (USItype)uu.s.high << bm;
179 w.s.high = (USItype)uu.s.high >> b;
180 w.s.low = ((USItype)uu.s.low >> b) | carries;
183 return w.ll;
185 #endif
187 #ifdef L_ashldi3
188 DItype
189 __ashldi3 (DItype u, word_type b)
191 DIunion w;
192 word_type bm;
193 DIunion uu;
195 if (b == 0)
196 return u;
198 uu.ll = u;
200 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
201 if (bm <= 0)
203 w.s.low = 0;
204 w.s.high = (USItype)uu.s.low << -bm;
206 else
208 USItype carries = (USItype)uu.s.low >> bm;
209 w.s.low = (USItype)uu.s.low << b;
210 w.s.high = ((USItype)uu.s.high << b) | carries;
213 return w.ll;
215 #endif
217 #ifdef L_ashrdi3
218 DItype
219 __ashrdi3 (DItype u, word_type b)
221 DIunion w;
222 word_type bm;
223 DIunion uu;
225 if (b == 0)
226 return u;
228 uu.ll = u;
230 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
231 if (bm <= 0)
233 /* w.s.high = 1..1 or 0..0 */
234 w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
235 w.s.low = uu.s.high >> -bm;
237 else
239 USItype carries = (USItype)uu.s.high << bm;
240 w.s.high = uu.s.high >> b;
241 w.s.low = ((USItype)uu.s.low >> b) | carries;
244 return w.ll;
246 #endif
248 #ifdef L_ffsdi2
249 DItype
250 __ffsdi2 (DItype u)
252 DIunion uu, w;
253 uu.ll = u;
254 w.s.high = 0;
255 w.s.low = ffs (uu.s.low);
256 if (w.s.low != 0)
257 return w.ll;
258 w.s.low = ffs (uu.s.high);
259 if (w.s.low != 0)
261 w.s.low += BITS_PER_UNIT * sizeof (SItype);
262 return w.ll;
264 return w.ll;
266 #endif
268 #ifdef L_muldi3
269 DItype
270 __muldi3 (DItype u, DItype v)
272 DIunion w;
273 DIunion uu, vv;
275 uu.ll = u,
276 vv.ll = v;
278 w.ll = __umulsidi3 (uu.s.low, vv.s.low);
279 w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
280 + (USItype) uu.s.high * (USItype) vv.s.low);
282 return w.ll;
284 #endif
286 #ifdef L_udiv_w_sdiv
287 #if defined (sdiv_qrnnd)
288 USItype
289 __udiv_w_sdiv (USItype *rp, USItype a1, USItype a0, USItype d)
291 USItype q, r;
292 USItype c0, c1, b1;
294 if ((SItype) d >= 0)
296 if (a1 < d - a1 - (a0 >> (SI_TYPE_SIZE - 1)))
298 /* dividend, divisor, and quotient are nonnegative */
299 sdiv_qrnnd (q, r, a1, a0, d);
301 else
303 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
304 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (SI_TYPE_SIZE - 1));
305 /* Divide (c1*2^32 + c0) by d */
306 sdiv_qrnnd (q, r, c1, c0, d);
307 /* Add 2^31 to quotient */
308 q += (USItype) 1 << (SI_TYPE_SIZE - 1);
311 else
313 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
314 c1 = a1 >> 1; /* A/2 */
315 c0 = (a1 << (SI_TYPE_SIZE - 1)) + (a0 >> 1);
317 if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
319 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
321 r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
322 if ((d & 1) != 0)
324 if (r >= q)
325 r = r - q;
326 else if (q - r <= d)
328 r = r - q + d;
329 q--;
331 else
333 r = r - q + 2*d;
334 q -= 2;
338 else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
340 c1 = (b1 - 1) - c1;
341 c0 = ~c0; /* logical NOT */
343 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
345 q = ~q; /* (A/2)/b1 */
346 r = (b1 - 1) - r;
348 r = 2*r + (a0 & 1); /* A/(2*b1) */
350 if ((d & 1) != 0)
352 if (r >= q)
353 r = r - q;
354 else if (q - r <= d)
356 r = r - q + d;
357 q--;
359 else
361 r = r - q + 2*d;
362 q -= 2;
366 else /* Implies c1 = b1 */
367 { /* Hence a1 = d - 1 = 2*b1 - 1 */
368 if (a0 >= -d)
370 q = -1;
371 r = a0 + d;
373 else
375 q = -2;
376 r = a0 + 2*d;
381 *rp = r;
382 return q;
384 #else
385 /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */
386 USItype
387 __udiv_w_sdiv (USItype *rp, USItype a1, USItype a0, USItype d)
389 #endif
390 #endif
392 #if (defined (L_udivdi3) || defined (L_divdi3) || \
393 defined (L_umoddi3) || defined (L_moddi3))
394 #define L_udivmoddi4
395 #endif
397 #ifdef L_udivmoddi4
398 static const UQItype __clz_tab[] =
400 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,
401 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,
402 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,
403 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,
404 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,
405 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
406 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,
407 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,
410 #if (defined (L_udivdi3) || defined (L_divdi3) || \
411 defined (L_umoddi3) || defined (L_moddi3))
412 static inline
413 #endif
414 UDItype
415 __udivmoddi4 (UDItype n, UDItype d, UDItype *rp)
417 DIunion ww;
418 DIunion nn, dd;
419 DIunion rr;
420 USItype d0, d1, n0, n1, n2;
421 USItype q0, q1;
422 USItype b, bm;
424 nn.ll = n;
425 dd.ll = d;
427 d0 = dd.s.low;
428 d1 = dd.s.high;
429 n0 = nn.s.low;
430 n1 = nn.s.high;
432 #if !UDIV_NEEDS_NORMALIZATION
433 if (d1 == 0)
435 if (d0 > n1)
437 /* 0q = nn / 0D */
439 udiv_qrnnd (q0, n0, n1, n0, d0);
440 q1 = 0;
442 /* Remainder in n0. */
444 else
446 /* qq = NN / 0d */
448 if (d0 == 0)
449 d0 = 1 / d0; /* Divide intentionally by zero. */
451 udiv_qrnnd (q1, n1, 0, n1, d0);
452 udiv_qrnnd (q0, n0, n1, n0, d0);
454 /* Remainder in n0. */
457 if (rp != 0)
459 rr.s.low = n0;
460 rr.s.high = 0;
461 *rp = rr.ll;
465 #else /* UDIV_NEEDS_NORMALIZATION */
467 if (d1 == 0)
469 if (d0 > n1)
471 /* 0q = nn / 0D */
473 count_leading_zeros (bm, d0);
475 if (bm != 0)
477 /* Normalize, i.e. make the most significant bit of the
478 denominator set. */
480 d0 = d0 << bm;
481 n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
482 n0 = n0 << bm;
485 udiv_qrnnd (q0, n0, n1, n0, d0);
486 q1 = 0;
488 /* Remainder in n0 >> bm. */
490 else
492 /* qq = NN / 0d */
494 if (d0 == 0)
495 d0 = 1 / d0; /* Divide intentionally by zero. */
497 count_leading_zeros (bm, d0);
499 if (bm == 0)
501 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
502 conclude (the most significant bit of n1 is set) /\ (the
503 leading quotient digit q1 = 1).
505 This special case is necessary, not an optimization.
506 (Shifts counts of SI_TYPE_SIZE are undefined.) */
508 n1 -= d0;
509 q1 = 1;
511 else
513 /* Normalize. */
515 b = SI_TYPE_SIZE - bm;
517 d0 = d0 << bm;
518 n2 = n1 >> b;
519 n1 = (n1 << bm) | (n0 >> b);
520 n0 = n0 << bm;
522 udiv_qrnnd (q1, n1, n2, n1, d0);
525 /* n1 != d0... */
527 udiv_qrnnd (q0, n0, n1, n0, d0);
529 /* Remainder in n0 >> bm. */
532 if (rp != 0)
534 rr.s.low = n0 >> bm;
535 rr.s.high = 0;
536 *rp = rr.ll;
539 #endif /* UDIV_NEEDS_NORMALIZATION */
541 else
543 if (d1 > n1)
545 /* 00 = nn / DD */
547 q0 = 0;
548 q1 = 0;
550 /* Remainder in n1n0. */
551 if (rp != 0)
553 rr.s.low = n0;
554 rr.s.high = n1;
555 *rp = rr.ll;
558 else
560 /* 0q = NN / dd */
562 count_leading_zeros (bm, d1);
563 if (bm == 0)
565 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
566 conclude (the most significant bit of n1 is set) /\ (the
567 quotient digit q0 = 0 or 1).
569 This special case is necessary, not an optimization. */
571 /* The condition on the next line takes advantage of that
572 n1 >= d1 (true due to program flow). */
573 if (n1 > d1 || n0 >= d0)
575 q0 = 1;
576 sub_ddmmss (n1, n0, n1, n0, d1, d0);
578 else
579 q0 = 0;
581 q1 = 0;
583 if (rp != 0)
585 rr.s.low = n0;
586 rr.s.high = n1;
587 *rp = rr.ll;
590 else
592 USItype m1, m0;
593 /* Normalize. */
595 b = SI_TYPE_SIZE - bm;
597 d1 = (d1 << bm) | (d0 >> b);
598 d0 = d0 << bm;
599 n2 = n1 >> b;
600 n1 = (n1 << bm) | (n0 >> b);
601 n0 = n0 << bm;
603 udiv_qrnnd (q0, n1, n2, n1, d1);
604 umul_ppmm (m1, m0, q0, d0);
606 if (m1 > n1 || (m1 == n1 && m0 > n0))
608 q0--;
609 sub_ddmmss (m1, m0, m1, m0, d1, d0);
612 q1 = 0;
614 /* Remainder in (n1n0 - m1m0) >> bm. */
615 if (rp != 0)
617 sub_ddmmss (n1, n0, n1, n0, m1, m0);
618 rr.s.low = (n1 << b) | (n0 >> bm);
619 rr.s.high = n1 >> bm;
620 *rp = rr.ll;
626 ww.s.low = q0;
627 ww.s.high = q1;
628 return ww.ll;
630 #endif
632 #ifdef L_divdi3
633 UDItype __udivmoddi4 ();
635 DItype
636 __divdi3 (DItype u, DItype v)
638 word_type c = 0;
639 DIunion uu, vv;
640 DItype w;
642 uu.ll = u;
643 vv.ll = v;
645 if (uu.s.high < 0)
646 c = ~c,
647 uu.ll = __negdi2 (uu.ll);
648 if (vv.s.high < 0)
649 c = ~c,
650 vv.ll = __negdi2 (vv.ll);
652 w = __udivmoddi4 (uu.ll, vv.ll, (UDItype *) 0);
653 if (c)
654 w = __negdi2 (w);
656 return w;
658 #endif
660 #ifdef L_moddi3
661 UDItype __udivmoddi4 ();
662 DItype
663 __moddi3 (DItype u, DItype v)
665 word_type c = 0;
666 DIunion uu, vv;
667 DItype w;
669 uu.ll = u;
670 vv.ll = v;
672 if (uu.s.high < 0)
673 c = ~c,
674 uu.ll = __negdi2 (uu.ll);
675 if (vv.s.high < 0)
676 vv.ll = __negdi2 (vv.ll);
678 (void) __udivmoddi4 (uu.ll, vv.ll, &w);
679 if (c)
680 w = __negdi2 (w);
682 return w;
684 #endif
686 #ifdef L_umoddi3
687 UDItype __udivmoddi4 ();
688 UDItype
689 __umoddi3 (UDItype u, UDItype v)
691 UDItype w;
693 (void) __udivmoddi4 (u, v, &w);
695 return w;
697 #endif
699 #ifdef L_udivdi3
700 UDItype __udivmoddi4 ();
701 UDItype
702 __udivdi3 (UDItype n, UDItype d)
704 return __udivmoddi4 (n, d, (UDItype *) 0);
706 #endif
708 #ifdef L_cmpdi2
709 word_type
710 __cmpdi2 (DItype a, DItype b)
712 DIunion au, bu;
714 au.ll = a, bu.ll = b;
716 if (au.s.high < bu.s.high)
717 return 0;
718 else if (au.s.high > bu.s.high)
719 return 2;
720 if ((USItype) au.s.low < (USItype) bu.s.low)
721 return 0;
722 else if ((USItype) au.s.low > (USItype) bu.s.low)
723 return 2;
724 return 1;
726 #endif
728 #ifdef L_ucmpdi2
729 word_type
730 __ucmpdi2 (DItype a, DItype b)
732 DIunion au, bu;
734 au.ll = a, bu.ll = b;
736 if ((USItype) au.s.high < (USItype) bu.s.high)
737 return 0;
738 else if ((USItype) au.s.high > (USItype) bu.s.high)
739 return 2;
740 if ((USItype) au.s.low < (USItype) bu.s.low)
741 return 0;
742 else if ((USItype) au.s.low > (USItype) bu.s.low)
743 return 2;
744 return 1;
746 #endif
748 #if defined(L_fixunstfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
749 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
750 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
752 DItype
753 __fixunstfdi (TFtype a)
755 TFtype b;
756 UDItype v;
758 if (a < 0)
759 return 0;
761 /* Compute high word of result, as a flonum. */
762 b = (a / HIGH_WORD_COEFF);
763 /* Convert that to fixed (but not to DItype!),
764 and shift it into the high word. */
765 v = (USItype) b;
766 v <<= WORD_SIZE;
767 /* Remove high part from the TFtype, leaving the low part as flonum. */
768 a -= (TFtype)v;
769 /* Convert that to fixed (but not to DItype!) and add it in.
770 Sometimes A comes out negative. This is significant, since
771 A has more bits than a long int does. */
772 if (a < 0)
773 v -= (USItype) (- a);
774 else
775 v += (USItype) a;
776 return v;
778 #endif
780 #if defined(L_fixtfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
781 DItype
782 __fixtfdi (TFtype a)
784 if (a < 0)
785 return - __fixunstfdi (-a);
786 return __fixunstfdi (a);
788 #endif
790 #if defined(L_fixunsxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
791 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
792 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
794 DItype
795 __fixunsxfdi (XFtype a)
797 XFtype b;
798 UDItype v;
800 if (a < 0)
801 return 0;
803 /* Compute high word of result, as a flonum. */
804 b = (a / HIGH_WORD_COEFF);
805 /* Convert that to fixed (but not to DItype!),
806 and shift it into the high word. */
807 v = (USItype) b;
808 v <<= WORD_SIZE;
809 /* Remove high part from the XFtype, leaving the low part as flonum. */
810 a -= (XFtype)v;
811 /* Convert that to fixed (but not to DItype!) and add it in.
812 Sometimes A comes out negative. This is significant, since
813 A has more bits than a long int does. */
814 if (a < 0)
815 v -= (USItype) (- a);
816 else
817 v += (USItype) a;
818 return v;
820 #endif
822 #if defined(L_fixxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
823 DItype
824 __fixxfdi (XFtype a)
826 if (a < 0)
827 return - __fixunsxfdi (-a);
828 return __fixunsxfdi (a);
830 #endif
832 #ifdef L_fixunsdfdi
833 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
834 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
836 DItype
837 __fixunsdfdi (DFtype a)
839 DFtype b;
840 UDItype v;
842 if (a < 0)
843 return 0;
845 /* Compute high word of result, as a flonum. */
846 b = (a / HIGH_WORD_COEFF);
847 /* Convert that to fixed (but not to DItype!),
848 and shift it into the high word. */
849 v = (USItype) b;
850 v <<= WORD_SIZE;
851 /* Remove high part from the DFtype, leaving the low part as flonum. */
852 a -= (DFtype)v;
853 /* Convert that to fixed (but not to DItype!) and add it in.
854 Sometimes A comes out negative. This is significant, since
855 A has more bits than a long int does. */
856 if (a < 0)
857 v -= (USItype) (- a);
858 else
859 v += (USItype) a;
860 return v;
862 #endif
864 #ifdef L_fixdfdi
865 DItype
866 __fixdfdi (DFtype a)
868 if (a < 0)
869 return - __fixunsdfdi (-a);
870 return __fixunsdfdi (a);
872 #endif
874 #ifdef L_fixunssfdi
875 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
876 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
878 DItype
879 __fixunssfdi (SFtype original_a)
881 /* Convert the SFtype to a DFtype, because that is surely not going
882 to lose any bits. Some day someone else can write a faster version
883 that avoids converting to DFtype, and verify it really works right. */
884 DFtype a = original_a;
885 DFtype b;
886 UDItype 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 DItype!),
894 and shift it into the high word. */
895 v = (USItype) b;
896 v <<= WORD_SIZE;
897 /* Remove high part from the DFtype, leaving the low part as flonum. */
898 a -= (DFtype)v;
899 /* Convert that to fixed (but not to DItype!) 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 -= (USItype) (- a);
904 else
905 v += (USItype) a;
906 return v;
908 #endif
910 #ifdef L_fixsfdi
911 DItype
912 __fixsfdi (SFtype a)
914 if (a < 0)
915 return - __fixunssfdi (-a);
916 return __fixunssfdi (a);
918 #endif
920 #if defined(L_floatdixf) && (LONG_DOUBLE_TYPE_SIZE == 96)
921 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
922 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
923 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
925 XFtype
926 __floatdixf (DItype u)
928 XFtype d;
929 SItype negate = 0;
931 if (u < 0)
932 u = -u, negate = 1;
934 d = (USItype) (u >> WORD_SIZE);
935 d *= HIGH_HALFWORD_COEFF;
936 d *= HIGH_HALFWORD_COEFF;
937 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
939 return (negate ? -d : d);
941 #endif
943 #if defined(L_floatditf) && (LONG_DOUBLE_TYPE_SIZE == 128)
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 TFtype
949 __floatditf (DItype u)
951 TFtype d;
952 SItype negate = 0;
954 if (u < 0)
955 u = -u, negate = 1;
957 d = (USItype) (u >> WORD_SIZE);
958 d *= HIGH_HALFWORD_COEFF;
959 d *= HIGH_HALFWORD_COEFF;
960 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
962 return (negate ? -d : d);
964 #endif
966 #ifdef L_floatdidf
967 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
968 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
969 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
971 DFtype
972 __floatdidf (DItype u)
974 DFtype d;
975 SItype negate = 0;
977 if (u < 0)
978 u = -u, negate = 1;
980 d = (USItype) (u >> WORD_SIZE);
981 d *= HIGH_HALFWORD_COEFF;
982 d *= HIGH_HALFWORD_COEFF;
983 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
985 return (negate ? -d : d);
987 #endif
989 #ifdef L_floatdisf
990 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
991 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
992 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
993 #define DI_SIZE (sizeof (DItype) * BITS_PER_UNIT)
995 /* Define codes for all the float formats that we know of. Note
996 that this is copied from real.h. */
998 #define UNKNOWN_FLOAT_FORMAT 0
999 #define IEEE_FLOAT_FORMAT 1
1000 #define VAX_FLOAT_FORMAT 2
1001 #define IBM_FLOAT_FORMAT 3
1003 /* Default to IEEE float if not specified. Nearly all machines use it. */
1004 #ifndef HOST_FLOAT_FORMAT
1005 #define HOST_FLOAT_FORMAT IEEE_FLOAT_FORMAT
1006 #endif
1008 #if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1009 #define DF_SIZE 53
1010 #define SF_SIZE 24
1011 #endif
1013 #if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
1014 #define DF_SIZE 56
1015 #define SF_SIZE 24
1016 #endif
1018 #if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
1019 #define DF_SIZE 56
1020 #define SF_SIZE 24
1021 #endif
1023 SFtype
1024 __floatdisf (DItype u)
1026 /* Do the calculation in DFmode
1027 so that we don't lose any of the precision of the high word
1028 while multiplying it. */
1029 DFtype f;
1030 SItype negate = 0;
1032 if (u < 0)
1033 u = -u, negate = 1;
1035 /* Protect against double-rounding error.
1036 Represent any low-order bits, that might be truncated in DFmode,
1037 by a bit that won't be lost. The bit can go in anywhere below the
1038 rounding position of the SFmode. A fixed mask and bit position
1039 handles all usual configurations. It doesn't handle the case
1040 of 128-bit DImode, however. */
1041 if (DF_SIZE < DI_SIZE
1042 && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1044 #define REP_BIT ((USItype) 1 << (DI_SIZE - DF_SIZE))
1045 if (u >= ((UDItype) 1 << DF_SIZE))
1047 if ((USItype) u & (REP_BIT - 1))
1048 u |= REP_BIT;
1051 f = (USItype) (u >> WORD_SIZE);
1052 f *= HIGH_HALFWORD_COEFF;
1053 f *= HIGH_HALFWORD_COEFF;
1054 f += (USItype) (u & (HIGH_WORD_COEFF - 1));
1056 return (SFtype) (negate ? -f : f);
1058 #endif
1060 #if defined(L_fixunsxfsi) && LONG_DOUBLE_TYPE_SIZE == 96
1061 /* Reenable the normal types, in case limits.h needs them. */
1062 #undef char
1063 #undef short
1064 #undef int
1065 #undef long
1066 #undef unsigned
1067 #undef float
1068 #undef double
1069 #undef MIN
1070 #undef MAX
1071 #include <limits.h>
1073 USItype
1074 __fixunsxfsi (XFtype a)
1076 if (a >= - (DFtype) LONG_MIN)
1077 return (SItype) (a + LONG_MIN) - LONG_MIN;
1078 return (SItype) a;
1080 #endif
1082 #ifdef L_fixunsdfsi
1083 /* Reenable the normal types, in case limits.h needs them. */
1084 #undef char
1085 #undef short
1086 #undef int
1087 #undef long
1088 #undef unsigned
1089 #undef float
1090 #undef double
1091 #undef MIN
1092 #undef MAX
1093 #include <limits.h>
1095 USItype
1096 __fixunsdfsi (DFtype a)
1098 if (a >= - (DFtype) LONG_MIN)
1099 return (SItype) (a + LONG_MIN) - LONG_MIN;
1100 return (SItype) a;
1102 #endif
1104 #ifdef L_fixunssfsi
1105 /* Reenable the normal types, in case limits.h needs them. */
1106 #undef char
1107 #undef short
1108 #undef int
1109 #undef long
1110 #undef unsigned
1111 #undef float
1112 #undef double
1113 #undef MIN
1114 #undef MAX
1115 #include <limits.h>
1117 USItype
1118 __fixunssfsi (SFtype a)
1120 if (a >= - (SFtype) LONG_MIN)
1121 return (SItype) (a + LONG_MIN) - LONG_MIN;
1122 return (SItype) a;
1124 #endif
1126 /* From here on down, the routines use normal data types. */
1128 #define SItype bogus_type
1129 #define USItype bogus_type
1130 #define DItype bogus_type
1131 #define UDItype bogus_type
1132 #define SFtype bogus_type
1133 #define DFtype bogus_type
1135 #undef char
1136 #undef short
1137 #undef int
1138 #undef long
1139 #undef unsigned
1140 #undef float
1141 #undef double
1143 #ifdef L__gcc_bcmp
1145 /* Like bcmp except the sign is meaningful.
1146 Result is negative if S1 is less than S2,
1147 positive if S1 is greater, 0 if S1 and S2 are equal. */
1150 __gcc_bcmp (unsigned char *s1, unsigned char *s2, size_t size)
1152 while (size > 0)
1154 unsigned char c1 = *s1++, c2 = *s2++;
1155 if (c1 != c2)
1156 return c1 - c2;
1157 size--;
1159 return 0;
1162 #endif
1163 \f\f
1164 #ifdef L__dummy
1165 void
1166 __dummy () {}
1167 #endif
1169 #ifdef L_varargs
1170 #ifdef __i860__
1171 #if defined(__svr4__) || defined(__alliant__)
1172 asm (" .text");
1173 asm (" .align 4");
1175 /* The Alliant needs the added underscore. */
1176 asm (".globl __builtin_saveregs");
1177 asm ("__builtin_saveregs:");
1178 asm (".globl ___builtin_saveregs");
1179 asm ("___builtin_saveregs:");
1181 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
1182 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
1183 area and also for a new va_list
1184 structure */
1185 /* Save all argument registers in the arg reg save area. The
1186 arg reg save area must have the following layout (according
1187 to the svr4 ABI):
1189 struct {
1190 union {
1191 float freg[8];
1192 double dreg[4];
1193 } float_regs;
1194 long ireg[12];
1198 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
1199 asm (" fst.q %f12,16(%sp)");
1201 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
1202 asm (" st.l %r17,36(%sp)");
1203 asm (" st.l %r18,40(%sp)");
1204 asm (" st.l %r19,44(%sp)");
1205 asm (" st.l %r20,48(%sp)");
1206 asm (" st.l %r21,52(%sp)");
1207 asm (" st.l %r22,56(%sp)");
1208 asm (" st.l %r23,60(%sp)");
1209 asm (" st.l %r24,64(%sp)");
1210 asm (" st.l %r25,68(%sp)");
1211 asm (" st.l %r26,72(%sp)");
1212 asm (" st.l %r27,76(%sp)");
1214 asm (" adds 80,%sp,%r16"); /* compute the address of the new
1215 va_list structure. Put in into
1216 r16 so that it will be returned
1217 to the caller. */
1219 /* Initialize all fields of the new va_list structure. This
1220 structure looks like:
1222 typedef struct {
1223 unsigned long ireg_used;
1224 unsigned long freg_used;
1225 long *reg_base;
1226 long *mem_ptr;
1227 } va_list;
1230 asm (" st.l %r0, 0(%r16)"); /* nfixed */
1231 asm (" st.l %r0, 4(%r16)"); /* nfloating */
1232 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
1233 asm (" bri %r1"); /* delayed return */
1234 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
1236 #else /* not __svr4__ */
1237 #if defined(__PARAGON__)
1239 * we'll use SVR4-ish varargs but need SVR3.2 assembler syntax,
1240 * and we stand a better chance of hooking into libraries
1241 * compiled by PGI. [andyp@ssd.intel.com]
1243 asm (" .text");
1244 asm (" .align 4");
1245 asm (".globl __builtin_saveregs");
1246 asm ("__builtin_saveregs:");
1247 asm (".globl ___builtin_saveregs");
1248 asm ("___builtin_saveregs:");
1250 asm (" andnot 0x0f,sp,sp"); /* round down to 16-byte boundary */
1251 asm (" adds -96,sp,sp"); /* allocate stack space for reg save
1252 area and also for a new va_list
1253 structure */
1254 /* Save all argument registers in the arg reg save area. The
1255 arg reg save area must have the following layout (according
1256 to the svr4 ABI):
1258 struct {
1259 union {
1260 float freg[8];
1261 double dreg[4];
1262 } float_regs;
1263 long ireg[12];
1267 asm (" fst.q f8, 0(sp)");
1268 asm (" fst.q f12,16(sp)");
1269 asm (" st.l r16,32(sp)");
1270 asm (" st.l r17,36(sp)");
1271 asm (" st.l r18,40(sp)");
1272 asm (" st.l r19,44(sp)");
1273 asm (" st.l r20,48(sp)");
1274 asm (" st.l r21,52(sp)");
1275 asm (" st.l r22,56(sp)");
1276 asm (" st.l r23,60(sp)");
1277 asm (" st.l r24,64(sp)");
1278 asm (" st.l r25,68(sp)");
1279 asm (" st.l r26,72(sp)");
1280 asm (" st.l r27,76(sp)");
1282 asm (" adds 80,sp,r16"); /* compute the address of the new
1283 va_list structure. Put in into
1284 r16 so that it will be returned
1285 to the caller. */
1287 /* Initialize all fields of the new va_list structure. This
1288 structure looks like:
1290 typedef struct {
1291 unsigned long ireg_used;
1292 unsigned long freg_used;
1293 long *reg_base;
1294 long *mem_ptr;
1295 } va_list;
1298 asm (" st.l r0, 0(r16)"); /* nfixed */
1299 asm (" st.l r0, 4(r16)"); /* nfloating */
1300 asm (" st.l sp, 8(r16)"); /* __va_ctl points to __va_struct. */
1301 asm (" bri r1"); /* delayed return */
1302 asm (" st.l r28,12(r16)"); /* pointer to overflow args */
1303 #else /* not __PARAGON__ */
1304 asm (" .text");
1305 asm (" .align 4");
1307 asm (".globl ___builtin_saveregs");
1308 asm ("___builtin_saveregs:");
1309 asm (" mov sp,r30");
1310 asm (" andnot 0x0f,sp,sp");
1311 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
1313 /* Fill in the __va_struct. */
1314 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
1315 asm (" st.l r17, 4(sp)"); /* int fixed[12] */
1316 asm (" st.l r18, 8(sp)");
1317 asm (" st.l r19,12(sp)");
1318 asm (" st.l r20,16(sp)");
1319 asm (" st.l r21,20(sp)");
1320 asm (" st.l r22,24(sp)");
1321 asm (" st.l r23,28(sp)");
1322 asm (" st.l r24,32(sp)");
1323 asm (" st.l r25,36(sp)");
1324 asm (" st.l r26,40(sp)");
1325 asm (" st.l r27,44(sp)");
1327 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
1328 asm (" fst.q f12,64(sp)"); /* int floating[8] */
1330 /* Fill in the __va_ctl. */
1331 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
1332 asm (" st.l r28,84(sp)"); /* pointer to more args */
1333 asm (" st.l r0, 88(sp)"); /* nfixed */
1334 asm (" st.l r0, 92(sp)"); /* nfloating */
1336 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
1337 asm (" bri r1");
1338 asm (" mov r30,sp");
1339 /* recover stack and pass address to start
1340 of data. */
1341 #endif /* not __PARAGON__ */
1342 #endif /* not __svr4__ */
1343 #else /* not __i860__ */
1344 #ifdef __sparc__
1345 asm (".global __builtin_saveregs");
1346 asm ("__builtin_saveregs:");
1347 asm (".global ___builtin_saveregs");
1348 asm ("___builtin_saveregs:");
1349 #ifdef NEED_PROC_COMMAND
1350 asm (".proc 020");
1351 #endif
1352 asm ("st %i0,[%fp+68]");
1353 asm ("st %i1,[%fp+72]");
1354 asm ("st %i2,[%fp+76]");
1355 asm ("st %i3,[%fp+80]");
1356 asm ("st %i4,[%fp+84]");
1357 asm ("retl");
1358 asm ("st %i5,[%fp+88]");
1359 #ifdef NEED_TYPE_COMMAND
1360 asm (".type __builtin_saveregs,#function");
1361 asm (".size __builtin_saveregs,.-__builtin_saveregs");
1362 #endif
1363 #else /* not __sparc__ */
1364 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1366 asm (" .text");
1367 asm (" .ent __builtin_saveregs");
1368 asm (" .globl __builtin_saveregs");
1369 asm ("__builtin_saveregs:");
1370 asm (" sw $4,0($30)");
1371 asm (" sw $5,4($30)");
1372 asm (" sw $6,8($30)");
1373 asm (" sw $7,12($30)");
1374 asm (" j $31");
1375 asm (" .end __builtin_saveregs");
1376 #else /* not __mips__, etc. */
1378 void *
1379 __builtin_saveregs ()
1381 abort ();
1384 #endif /* not __mips__ */
1385 #endif /* not __sparc__ */
1386 #endif /* not __i860__ */
1387 #endif
1389 #ifdef L_eprintf
1390 #ifndef inhibit_libc
1392 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1393 #include <stdio.h>
1394 /* This is used by the `assert' macro. */
1395 void
1396 __eprintf (const char *string, const char *expression,
1397 int line, const char *filename)
1399 fprintf (stderr, string, expression, line, filename);
1400 fflush (stderr);
1401 abort ();
1404 #endif
1405 #endif
1407 #ifdef L_bb
1409 /* Structure emitted by -a */
1410 struct bb
1412 long zero_word;
1413 const char *filename;
1414 long *counts;
1415 long ncounts;
1416 struct bb *next;
1417 const unsigned long *addresses;
1419 /* Older GCC's did not emit these fields. */
1420 long nwords;
1421 const char **functions;
1422 const long *line_nums;
1423 const char **filenames;
1424 char *flags;
1427 #ifdef BLOCK_PROFILER_CODE
1428 BLOCK_PROFILER_CODE
1429 #else
1430 #ifndef inhibit_libc
1432 /* Simple minded basic block profiling output dumper for
1433 systems that don't provide tcov support. At present,
1434 it requires atexit and stdio. */
1436 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1437 #include <stdio.h>
1438 char *ctime ();
1440 #include "gbl-ctors.h"
1442 static struct bb *bb_head;
1444 /* Return the number of digits needed to print a value */
1445 /* __inline__ */ static int num_digits (long value, int base)
1447 int minus = (value < 0 && base != 16);
1448 unsigned long v = (minus) ? -value : value;
1449 int ret = minus;
1453 v /= base;
1454 ret++;
1456 while (v);
1458 return ret;
1461 void
1462 __bb_exit_func (void)
1464 FILE *file = fopen ("bb.out", "a");
1465 long time_value;
1467 if (!file)
1468 perror ("bb.out");
1470 else
1472 struct bb *ptr;
1474 /* This is somewhat type incorrect, but it avoids worrying about
1475 exactly where time.h is included from. It should be ok unless
1476 a void * differs from other pointer formats, or if sizeof (long)
1477 is < sizeof (time_t). It would be nice if we could assume the
1478 use of rationale standards here. */
1480 time ((void *) &time_value);
1481 fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value));
1483 /* We check the length field explicitly in order to allow compatibility
1484 with older GCC's which did not provide it. */
1486 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1488 int i;
1489 int func_p = (ptr->nwords >= sizeof (struct bb) && ptr->nwords <= 1000);
1490 int line_p = (func_p && ptr->line_nums);
1491 int file_p = (func_p && ptr->filenames);
1492 long ncounts = ptr->ncounts;
1493 long cnt_max = 0;
1494 long line_max = 0;
1495 long addr_max = 0;
1496 int file_len = 0;
1497 int func_len = 0;
1498 int blk_len = num_digits (ncounts, 10);
1499 int cnt_len;
1500 int line_len;
1501 int addr_len;
1503 fprintf (file, "File %s, %ld basic blocks \n\n",
1504 ptr->filename, ncounts);
1506 /* Get max values for each field. */
1507 for (i = 0; i < ncounts; i++)
1509 const char *p;
1510 int len;
1512 if (cnt_max < ptr->counts[i])
1513 cnt_max = ptr->counts[i];
1515 if (addr_max < ptr->addresses[i])
1516 addr_max = ptr->addresses[i];
1518 if (line_p && line_max < ptr->line_nums[i])
1519 line_max = ptr->line_nums[i];
1521 if (func_p)
1523 p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>";
1524 len = strlen (p);
1525 if (func_len < len)
1526 func_len = len;
1529 if (file_p)
1531 p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>";
1532 len = strlen (p);
1533 if (file_len < len)
1534 file_len = len;
1538 addr_len = num_digits (addr_max, 16);
1539 cnt_len = num_digits (cnt_max, 10);
1540 line_len = num_digits (line_max, 10);
1542 /* Now print out the basic block information. */
1543 for (i = 0; i < ncounts; i++)
1545 fprintf (file,
1546 " Block #%*d: executed %*ld time(s) address= 0x%.*lx",
1547 blk_len, i+1,
1548 cnt_len, ptr->counts[i],
1549 addr_len, ptr->addresses[i]);
1551 if (func_p)
1552 fprintf (file, " function= %-*s", func_len,
1553 (ptr->functions[i]) ? ptr->functions[i] : "<none>");
1555 if (line_p)
1556 fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]);
1558 if (file_p)
1559 fprintf (file, " file= %s",
1560 (ptr->filenames[i]) ? ptr->filenames[i] : "<none>");
1562 fprintf (file, "\n");
1565 fprintf (file, "\n");
1566 fflush (file);
1569 fprintf (file, "\n\n");
1570 fclose (file);
1574 void
1575 __bb_init_func (struct bb *blocks)
1577 /* User is supposed to check whether the first word is non-0,
1578 but just in case.... */
1580 if (blocks->zero_word)
1581 return;
1583 #ifdef ON_EXIT
1584 /* Initialize destructor. */
1585 if (!bb_head)
1586 ON_EXIT (__bb_exit_func, 0);
1587 #endif
1589 /* Set up linked list. */
1590 blocks->zero_word = 1;
1591 blocks->next = bb_head;
1592 bb_head = blocks;
1595 #ifndef MACHINE_STATE_SAVE
1596 #define MACHINE_STATE_SAVE(ID)
1597 #endif
1598 #ifndef MACHINE_STATE_RESTORE
1599 #define MACHINE_STATE_RESTORE(ID)
1600 #endif
1602 #include <string.h>
1604 /* Number of buckets in hashtable of basic block addresses. */
1606 #define BB_BUCKETS 311
1608 /* Maximum length of string in file bb.in. */
1610 #define BBINBUFSIZE 500
1612 /* BBINBUFSIZE-1 with double quotes. We could use #BBINBUFSIZE or
1613 "BBINBUFSIZE" but want to avoid trouble with preprocessors. */
1615 #define BBINBUFSIZESTR "499"
1617 struct bb_edge
1619 struct bb_edge *next;
1620 unsigned long src_addr;
1621 unsigned long dst_addr;
1622 unsigned long count;
1625 enum bb_func_mode
1627 TRACE_KEEP = 0, TRACE_ON = 1, TRACE_OFF = 2
1630 struct bb_func
1632 struct bb_func *next;
1633 char *funcname;
1634 char *filename;
1635 enum bb_func_mode mode;
1638 /* This is the connection to the outside world.
1639 The BLOCK_PROFILER macro must set __bb.blocks
1640 and __bb.blockno. */
1642 struct {
1643 unsigned long blockno;
1644 struct bb *blocks;
1645 } __bb;
1647 /* Vars to store addrs of source and destination basic blocks
1648 of a jump. */
1650 static unsigned long bb_src = 0;
1651 static unsigned long bb_dst = 0;
1653 static FILE *bb_tracefile = (FILE *) 0;
1654 static struct bb_edge **bb_hashbuckets = (struct bb_edge **) 0;
1655 static struct bb_func *bb_func_head = (struct bb_func *) 0;
1656 static unsigned long bb_callcount = 0;
1657 static int bb_mode = 0;
1659 static unsigned long *bb_stack = (unsigned long *) 0;
1660 static size_t bb_stacksize = 0;
1662 static int reported = 0;
1664 /* Trace modes:
1665 Always : Print execution frequencies of basic blocks
1666 to file bb.out.
1667 bb_mode & 1 != 0 : Dump trace of basic blocks to file bbtrace[.gz]
1668 bb_mode & 2 != 0 : Print jump frequencies to file bb.out.
1669 bb_mode & 4 != 0 : Cut call instructions from basic block flow.
1670 bb_mode & 8 != 0 : Insert return instructions in basic block flow.
1673 #ifdef HAVE_POPEN
1675 /*#include <sys/types.h>*/
1676 #include <sys/stat.h>
1677 /*#include <malloc.h>*/
1679 /* Commands executed by gopen. */
1681 #define GOPENDECOMPRESS "gzip -cd "
1682 #define GOPENCOMPRESS "gzip -c >"
1684 /* Like fopen but pipes through gzip. mode may only be "r" or "w".
1685 If it does not compile, simply replace gopen by fopen and delete
1686 '.gz' from any first parameter to gopen. */
1688 static FILE *
1689 gopen (char *fn, char *mode)
1691 int use_gzip;
1692 char *p;
1694 if (mode[1])
1695 return (FILE *) 0;
1697 if (mode[0] != 'r' && mode[0] != 'w')
1698 return (FILE *) 0;
1700 p = fn + strlen (fn)-1;
1701 use_gzip = ((p[-1] == '.' && (p[0] == 'Z' || p[0] == 'z')) ||
1702 (p[-2] == '.' && p[-1] == 'g' && p[0] == 'z'));
1704 if (use_gzip)
1706 if (mode[0]=='r')
1708 FILE *f;
1709 char *s = (char *) malloc (sizeof (char) * strlen (fn)
1710 + sizeof (GOPENDECOMPRESS));
1711 strcpy (s, GOPENDECOMPRESS);
1712 strcpy (s + (sizeof (GOPENDECOMPRESS)-1), fn);
1713 f = popen (s, mode);
1714 free (s);
1715 return f;
1718 else
1720 FILE *f;
1721 char *s = (char *) malloc (sizeof (char) * strlen (fn)
1722 + sizeof (GOPENCOMPRESS));
1723 strcpy (s, GOPENCOMPRESS);
1724 strcpy (s + (sizeof (GOPENCOMPRESS)-1), fn);
1725 if (!(f = popen (s, mode)))
1726 f = fopen (s, mode);
1727 free (s);
1728 return f;
1732 else
1733 return fopen (fn, mode);
1736 static int
1737 gclose (FILE *f)
1739 struct stat buf;
1741 if (f != NULL)
1743 if (!fstat (fileno (f), &buf) && S_ISFIFO (buf.st_mode))
1744 return pclose (f);
1746 return fclose (f);
1748 return 0;
1751 #endif /* HAVE_POPEN */
1753 /* Called once per program. */
1755 static void
1756 __bb_exit_trace_func ()
1758 FILE *file = fopen ("bb.out", "a");
1759 struct bb_func *f;
1760 struct bb_edge *e;
1761 struct bb *b;
1763 if (!file)
1764 perror ("bb.out");
1766 if (bb_mode & 1)
1768 if (!bb_tracefile)
1769 perror ("bbtrace");
1770 else
1771 #ifdef HAVE_POPEN
1772 gclose (bb_tracefile);
1773 #else
1774 fclose (bb_tracefile);
1775 #endif /* HAVE_POPEN */
1778 /* Check functions in `bb.in'. */
1780 if (file)
1782 long time_value;
1783 const struct bb_func *p;
1784 int printed_something = 0;
1785 struct bb *ptr;
1786 long blk;
1788 /* This is somewhat type incorrect. */
1789 time ((void *) &time_value);
1791 for (p = bb_func_head; p != (struct bb_func *) 0; p = p->next)
1793 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1795 if (!ptr->filename || p->filename != (char *) 0 && strcmp (p->filename, ptr->filename))
1796 continue;
1797 for (blk = 0; blk < ptr->ncounts; blk++)
1799 if (!strcmp (p->funcname, ptr->functions[blk]))
1800 goto found;
1804 if (!printed_something)
1806 fprintf (file, "Functions in `bb.in' not executed during basic block profiling on %s\n", ctime ((void *) &time_value));
1807 printed_something = 1;
1810 fprintf (file, "\tFunction %s", p->funcname);
1811 if (p->filename)
1812 fprintf (file, " of file %s", p->filename);
1813 fprintf (file, "\n" );
1815 found: ;
1818 if (printed_something)
1819 fprintf (file, "\n");
1823 if (bb_mode & 2)
1825 if (!bb_hashbuckets)
1827 if (!reported)
1829 fprintf (stderr, "Profiler: out of memory\n");
1830 reported = 1;
1832 return;
1835 else if (file)
1837 long time_value;
1838 int i;
1839 unsigned long addr_max = 0;
1840 unsigned long cnt_max = 0;
1841 int cnt_len;
1842 int addr_len;
1844 /* This is somewhat type incorrect, but it avoids worrying about
1845 exactly where time.h is included from. It should be ok unless
1846 a void * differs from other pointer formats, or if sizeof (long)
1847 is < sizeof (time_t). It would be nice if we could assume the
1848 use of rationale standards here. */
1850 time ((void *) &time_value);
1851 fprintf (file, "Basic block jump tracing");
1853 switch (bb_mode & 12)
1855 case 0:
1856 fprintf (file, " (with call)");
1857 break;
1859 case 4:
1860 /* Print nothing. */
1861 break;
1863 case 8:
1864 fprintf (file, " (with call & ret)");
1865 break;
1867 case 12:
1868 fprintf (file, " (with ret)");
1869 break;
1872 fprintf (file, " finished on %s\n", ctime ((void *) &time_value));
1874 for (i = 0; i < BB_BUCKETS; i++)
1876 struct bb_edge *bucket = bb_hashbuckets[i];
1877 for ( ; bucket; bucket = bucket->next )
1879 if (addr_max < bucket->src_addr)
1880 addr_max = bucket->src_addr;
1881 if (addr_max < bucket->dst_addr)
1882 addr_max = bucket->dst_addr;
1883 if (cnt_max < bucket->count)
1884 cnt_max = bucket->count;
1887 addr_len = num_digits (addr_max, 16);
1888 cnt_len = num_digits (cnt_max, 10);
1890 for ( i = 0; i < BB_BUCKETS; i++)
1892 struct bb_edge *bucket = bb_hashbuckets[i];
1893 for ( ; bucket; bucket = bucket->next )
1895 fprintf (file, "Jump from block 0x%.*lx to "
1896 "block 0x%.*lx executed %*d time(s)\n",
1897 addr_len, bucket->src_addr,
1898 addr_len, bucket->dst_addr,
1899 cnt_len, bucket->count);
1903 fprintf (file, "\n");
1908 if (file)
1909 fclose (file);
1911 /* Free allocated memory. */
1913 f = bb_func_head;
1914 while (f)
1916 struct bb_func *old = f;
1918 f = f->next;
1919 if (old->funcname) free (old->funcname);
1920 if (old->filename) free (old->filename);
1921 free (old);
1924 if (bb_stack)
1925 free (bb_stack);
1927 if (bb_hashbuckets)
1929 int i;
1931 for (i = 0; i < BB_BUCKETS; i++)
1933 struct bb_edge *old, *bucket = bb_hashbuckets[i];
1935 while (bucket)
1937 old = bucket;
1938 bucket = bucket->next;
1939 free (old);
1942 free (bb_hashbuckets);
1945 for (b = bb_head; b; b = b->next)
1946 if (b->flags) free (b->flags);
1949 /* Called once per program. */
1951 static void
1952 __bb_init_prg ()
1955 FILE *file;
1956 char buf[BBINBUFSIZE];
1957 const char *p;
1958 const char *pos;
1959 enum bb_func_mode m;
1961 #ifdef ON_EXIT
1962 /* Initialize destructor. */
1963 ON_EXIT (__bb_exit_func, 0);
1964 #endif
1966 if (!(file = fopen ("bb.in", "r")))
1967 return;
1969 while(fscanf (file, " %" BBINBUFSIZESTR "s ", buf) != EOF)
1971 p = buf;
1972 if (*p == '-')
1974 m = TRACE_OFF;
1975 p++;
1977 else
1979 m = TRACE_ON;
1981 if (!strcmp (p, "__bb_trace__"))
1982 bb_mode |= 1;
1983 else if (!strcmp (p, "__bb_jumps__"))
1984 bb_mode |= 2;
1985 else if (!strcmp (p, "__bb_hidecall__"))
1986 bb_mode |= 4;
1987 else if (!strcmp (p, "__bb_showret__"))
1988 bb_mode |= 8;
1989 else
1991 struct bb_func *f = (struct bb_func *) malloc (sizeof (struct bb_func));
1992 if (f)
1994 unsigned long l;
1995 f->next = bb_func_head;
1996 if (pos = strchr (p, ':'))
1998 if (!(f->funcname = (char *) malloc (strlen (pos+1)+1)))
1999 continue;
2000 strcpy (f->funcname, pos+1);
2001 l = pos-p;
2002 if ((f->filename = (char *) malloc (l+1)))
2004 strncpy (f->filename, p, l);
2005 f->filename[l] = '\0';
2007 else
2008 f->filename = (char *) 0;
2010 else
2012 if (!(f->funcname = (char *) malloc (strlen (p)+1)))
2013 continue;
2014 strcpy (f->funcname, p);
2015 f->filename = (char *) 0;
2017 f->mode = m;
2018 bb_func_head = f;
2022 fclose (file);
2024 #ifdef HAVE_POPEN
2026 if (bb_mode & 1)
2027 bb_tracefile = gopen ("bbtrace.gz", "w");
2029 #else
2031 if (bb_mode & 1)
2032 bb_tracefile = fopen ("bbtrace", "w");
2034 #endif /* HAVE_POPEN */
2036 if (bb_mode & 2)
2038 bb_hashbuckets = (struct bb_edge **)
2039 malloc (BB_BUCKETS * sizeof (struct bb_edge *));
2040 if (bb_hashbuckets)
2041 bzero ((char *) bb_hashbuckets, BB_BUCKETS);
2044 if (bb_mode & 12)
2046 bb_stacksize = 10;
2047 bb_stack = (unsigned long *) malloc (bb_stacksize * sizeof (*bb_stack));
2050 #ifdef ON_EXIT
2051 /* Initialize destructor. */
2052 ON_EXIT (__bb_exit_trace_func, 0);
2053 #endif
2057 /* Called upon entering a basic block. */
2059 void
2060 __bb_trace_func ()
2062 struct bb_edge *bucket;
2064 MACHINE_STATE_SAVE("1")
2066 if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2067 goto skip;
2069 bb_dst = __bb.blocks->addresses[__bb.blockno];
2070 __bb.blocks->counts[__bb.blockno]++;
2072 if (bb_tracefile)
2074 fwrite (&bb_dst, sizeof (unsigned long), 1, bb_tracefile);
2077 if (bb_hashbuckets)
2079 struct bb_edge **startbucket, **oldnext;
2081 oldnext = startbucket =
2082 & bb_hashbuckets[ (((int) bb_src*8) ^ (int) bb_dst) % BB_BUCKETS ];
2083 bucket = *startbucket;
2085 for (bucket = *startbucket; bucket;
2086 oldnext = &(bucket->next), bucket = *oldnext)
2088 if ( bucket->src_addr == bb_src &&
2089 bucket->dst_addr == bb_dst )
2091 bucket->count++;
2092 *oldnext = bucket->next;
2093 bucket->next = *startbucket;
2094 *startbucket = bucket;
2095 goto ret;
2099 bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2101 if (!bucket)
2103 if (!reported)
2105 fprintf (stderr, "Profiler: out of memory\n");
2106 reported = 1;
2110 else
2112 bucket->src_addr = bb_src;
2113 bucket->dst_addr = bb_dst;
2114 bucket->next = *startbucket;
2115 *startbucket = bucket;
2116 bucket->count = 1;
2120 ret:
2121 bb_src = bb_dst;
2123 skip:
2126 MACHINE_STATE_RESTORE("1")
2130 /* Called when returning from a function and `__bb_showret__' is set. */
2132 static void
2133 __bb_trace_func_ret ()
2135 struct bb_edge *bucket;
2137 if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2138 goto skip;
2140 if (bb_hashbuckets)
2142 struct bb_edge **startbucket, **oldnext;
2144 oldnext = startbucket =
2145 & bb_hashbuckets[ (((int) bb_dst * 8) ^ (int) bb_src) % BB_BUCKETS ];
2146 bucket = *startbucket;
2148 for (bucket = *startbucket; bucket;
2149 oldnext = &(bucket->next), bucket = *oldnext)
2151 if ( bucket->src_addr == bb_dst &&
2152 bucket->dst_addr == bb_src )
2154 bucket->count++;
2155 *oldnext = bucket->next;
2156 bucket->next = *startbucket;
2157 *startbucket = bucket;
2158 goto ret;
2162 bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2164 if (!bucket)
2166 if (!reported)
2168 fprintf (stderr, "Profiler: out of memory\n");
2169 reported = 1;
2173 else
2175 bucket->src_addr = bb_dst;
2176 bucket->dst_addr = bb_src;
2177 bucket->next = *startbucket;
2178 *startbucket = bucket;
2179 bucket->count = 1;
2183 ret:
2184 bb_dst = bb_src;
2186 skip:
2191 /* Called upon entering the first function of a file. */
2193 static void
2194 __bb_init_file (struct bb *blocks)
2197 const struct bb_func *p;
2198 long blk, ncounts = blocks->ncounts;
2199 const char **functions = blocks->functions;
2201 /* Set up linked list. */
2202 blocks->zero_word = 1;
2203 blocks->next = bb_head;
2204 bb_head = blocks;
2206 blocks->flags = 0;
2207 if (!bb_func_head ||
2208 !(blocks->flags = (char *) malloc (sizeof (char) * blocks->ncounts)))
2209 return;
2211 for (blk = 0; blk < ncounts; blk++)
2212 blocks->flags[blk] = 0;
2214 for (blk = 0; blk < ncounts; blk++)
2216 for (p = bb_func_head; p; p = p->next)
2218 if (!strcmp (p->funcname, functions[blk]) &&
2219 (!p->filename || !strcmp (p->filename, blocks->filename)))
2221 blocks->flags[blk] |= p->mode;
2228 /* Called when exiting from a function. */
2230 void
2231 __bb_trace_ret ()
2234 MACHINE_STATE_SAVE("2")
2236 if (bb_callcount)
2238 if ((bb_mode & 12) && bb_stacksize > bb_callcount)
2240 bb_src = bb_stack[bb_callcount];
2241 if (bb_mode & 8)
2242 __bb_trace_func_ret ();
2245 bb_callcount -= 1;
2248 MACHINE_STATE_RESTORE("2")
2252 /* Called when entering a function. */
2254 void
2255 __bb_init_trace_func (struct bb *blocks, unsigned long blockno)
2257 static int trace_init = 0;
2259 MACHINE_STATE_SAVE("3")
2261 if (!blocks->zero_word)
2263 if (!trace_init)
2265 trace_init = 1;
2266 __bb_init_prg ();
2268 __bb_init_file (blocks);
2271 if (bb_callcount)
2274 bb_callcount += 1;
2276 if (bb_mode & 12)
2278 if (bb_callcount >= bb_stacksize)
2280 size_t newsize = bb_callcount + 100;
2282 bb_stack = (unsigned long *) realloc (bb_stack, newsize);
2283 if (! bb_stack)
2285 if (!reported)
2287 fprintf (stderr, "Profiler: out of memory\n");
2288 reported = 1;
2290 bb_stacksize = 0;
2291 goto stack_overflow;
2293 bb_stacksize = newsize;
2295 bb_stack[bb_callcount] = bb_src;
2297 if (bb_mode & 4)
2298 bb_src = 0;
2302 stack_overflow:;
2306 else if (blocks->flags && (blocks->flags[blockno] & TRACE_ON))
2308 bb_callcount = 1;
2309 bb_src = 0;
2311 if (bb_stack)
2312 bb_stack[bb_callcount] = bb_src;
2315 MACHINE_STATE_RESTORE("3")
2318 #endif /* not inhibit_libc */
2319 #endif /* not BLOCK_PROFILER_CODE */
2320 #endif /* L_bb */
2322 /* Default free-store management functions for C++, per sections 12.5 and
2323 17.3.3 of the Working Paper. */
2325 #ifdef L_op_new
2326 /* operator new (size_t), described in 17.3.3.5. This function is used by
2327 C++ programs to allocate a block of memory to hold a single object. */
2329 typedef void (*vfp)(void);
2330 extern vfp __new_handler;
2331 extern void __default_new_handler (void);
2333 #ifdef WEAK_ALIAS
2334 void * __builtin_new (size_t sz)
2335 __attribute__ ((weak, alias ("___builtin_new")));
2336 void *
2337 ___builtin_new (size_t sz)
2338 #else
2339 void *
2340 __builtin_new (size_t sz)
2341 #endif
2343 void *p;
2344 vfp handler = (__new_handler) ? __new_handler : __default_new_handler;
2346 /* malloc (0) is unpredictable; avoid it. */
2347 if (sz == 0)
2348 sz = 1;
2349 p = (void *) malloc (sz);
2350 while (p == 0)
2352 (*handler) ();
2353 p = (void *) malloc (sz);
2356 return p;
2358 #endif /* L_op_new */
2360 #ifdef L_op_vnew
2361 /* void * operator new [] (size_t), described in 17.3.3.6. This function
2362 is used by C++ programs to allocate a block of memory for an array. */
2364 extern void * __builtin_new (size_t);
2366 #ifdef WEAK_ALIAS
2367 void * __builtin_vec_new (size_t sz)
2368 __attribute__ ((weak, alias ("___builtin_vec_new")));
2369 void *
2370 ___builtin_vec_new (size_t sz)
2371 #else
2372 void *
2373 __builtin_vec_new (size_t sz)
2374 #endif
2376 return __builtin_new (sz);
2378 #endif /* L_op_vnew */
2380 #ifdef L_new_handler
2381 /* set_new_handler (fvoid_t *) and the default new handler, described in
2382 17.3.3.2 and 17.3.3.5. These functions define the result of a failure
2383 to allocate the amount of memory requested from operator new or new []. */
2385 #ifndef inhibit_libc
2386 /* This gets us __GNU_LIBRARY__. */
2387 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2388 #include <stdio.h>
2390 #ifdef __GNU_LIBRARY__
2391 /* Avoid forcing the library's meaning of `write' on the user program
2392 by using the "internal" name (for use within the library) */
2393 #define write(fd, buf, n) __write((fd), (buf), (n))
2394 #endif
2395 #endif /* inhibit_libc */
2397 typedef void (*vfp)(void);
2398 void __default_new_handler (void);
2400 vfp __new_handler = (vfp) 0;
2403 set_new_handler (vfp handler)
2405 vfp prev_handler;
2407 prev_handler = __new_handler;
2408 if (handler == 0) handler = __default_new_handler;
2409 __new_handler = handler;
2410 return prev_handler;
2413 #define MESSAGE "Virtual memory exceeded in `new'\n"
2415 void
2416 __default_new_handler ()
2418 #ifndef inhibit_libc
2419 /* don't use fprintf (stderr, ...) because it may need to call malloc. */
2420 /* This should really print the name of the program, but that is hard to
2421 do. We need a standard, clean way to get at the name. */
2422 write (2, MESSAGE, sizeof (MESSAGE));
2423 #endif
2424 /* don't call exit () because that may call global destructors which
2425 may cause a loop. */
2426 _exit (-1);
2428 #endif
2430 #ifdef L_op_delete
2431 /* operator delete (void *), described in 17.3.3.3. This function is used
2432 by C++ programs to return to the free store a block of memory allocated
2433 as a single object. */
2435 #ifdef WEAK_ALIAS
2436 void __builtin_delete (void *ptr)
2437 __attribute__ ((weak, alias ("___builtin_delete")));
2438 void
2439 ___builtin_delete (void *ptr)
2440 #else
2441 void
2442 __builtin_delete (void *ptr)
2443 #endif
2445 if (ptr)
2446 free (ptr);
2448 #endif
2450 #ifdef L_op_vdel
2451 /* operator delete [] (void *), described in 17.3.3.4. This function is
2452 used by C++ programs to return to the free store a block of memory
2453 allocated as an array. */
2455 extern void __builtin_delete (void *);
2457 #ifdef WEAK_ALIAS
2458 void __builtin_vec_delete (void *ptr)
2459 __attribute__ ((weak, alias ("___builtin_vec_delete")));
2460 void
2461 ___builtin_vec_delete (void *ptr)
2462 #else
2463 void
2464 __builtin_vec_delete (void *ptr)
2465 #endif
2467 __builtin_delete (ptr);
2469 #endif
2471 /* End of C++ free-store management functions */
2473 #ifdef L_shtab
2474 unsigned int __shtab[] = {
2475 0x00000001, 0x00000002, 0x00000004, 0x00000008,
2476 0x00000010, 0x00000020, 0x00000040, 0x00000080,
2477 0x00000100, 0x00000200, 0x00000400, 0x00000800,
2478 0x00001000, 0x00002000, 0x00004000, 0x00008000,
2479 0x00010000, 0x00020000, 0x00040000, 0x00080000,
2480 0x00100000, 0x00200000, 0x00400000, 0x00800000,
2481 0x01000000, 0x02000000, 0x04000000, 0x08000000,
2482 0x10000000, 0x20000000, 0x40000000, 0x80000000
2484 #endif
2486 #ifdef L_clear_cache
2487 /* Clear part of an instruction cache. */
2489 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
2491 void
2492 __clear_cache (char *beg, char *end)
2494 #ifdef CLEAR_INSN_CACHE
2495 CLEAR_INSN_CACHE (beg, end);
2496 #else
2497 #ifdef INSN_CACHE_SIZE
2498 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
2499 static int initialized;
2500 int offset;
2501 void *start_addr
2502 void *end_addr;
2503 typedef (*function_ptr) ();
2505 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
2506 /* It's cheaper to clear the whole cache.
2507 Put in a series of jump instructions so that calling the beginning
2508 of the cache will clear the whole thing. */
2510 if (! initialized)
2512 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2513 & -INSN_CACHE_LINE_WIDTH);
2514 int end_ptr = ptr + INSN_CACHE_SIZE;
2516 while (ptr < end_ptr)
2518 *(INSTRUCTION_TYPE *)ptr
2519 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
2520 ptr += INSN_CACHE_LINE_WIDTH;
2522 *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
2524 initialized = 1;
2527 /* Call the beginning of the sequence. */
2528 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2529 & -INSN_CACHE_LINE_WIDTH))
2530 ());
2532 #else /* Cache is large. */
2534 if (! initialized)
2536 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2537 & -INSN_CACHE_LINE_WIDTH);
2539 while (ptr < (int) array + sizeof array)
2541 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
2542 ptr += INSN_CACHE_LINE_WIDTH;
2545 initialized = 1;
2548 /* Find the location in array that occupies the same cache line as BEG. */
2550 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
2551 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
2552 & -INSN_CACHE_PLANE_SIZE)
2553 + offset);
2555 /* Compute the cache alignment of the place to stop clearing. */
2556 #if 0 /* This is not needed for gcc's purposes. */
2557 /* If the block to clear is bigger than a cache plane,
2558 we clear the entire cache, and OFFSET is already correct. */
2559 if (end < beg + INSN_CACHE_PLANE_SIZE)
2560 #endif
2561 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
2562 & -INSN_CACHE_LINE_WIDTH)
2563 & (INSN_CACHE_PLANE_SIZE - 1));
2565 #if INSN_CACHE_DEPTH > 1
2566 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
2567 if (end_addr <= start_addr)
2568 end_addr += INSN_CACHE_PLANE_SIZE;
2570 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
2572 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
2573 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
2575 while (addr != stop)
2577 /* Call the return instruction at ADDR. */
2578 ((function_ptr) addr) ();
2580 addr += INSN_CACHE_LINE_WIDTH;
2583 #else /* just one plane */
2586 /* Call the return instruction at START_ADDR. */
2587 ((function_ptr) start_addr) ();
2589 start_addr += INSN_CACHE_LINE_WIDTH;
2591 while ((start_addr % INSN_CACHE_SIZE) != offset);
2592 #endif /* just one plane */
2593 #endif /* Cache is large */
2594 #endif /* Cache exists */
2595 #endif /* CLEAR_INSN_CACHE */
2598 #endif /* L_clear_cache */
2600 #ifdef L_trampoline
2602 /* Jump to a trampoline, loading the static chain address. */
2604 #ifdef WINNT
2606 long getpagesize()
2608 #ifdef _ALPHA_
2609 return 8192;
2610 #else
2611 return 4096;
2612 #endif
2615 int mprotect(char *addr, int len, int prot)
2617 int np, op;
2619 if (prot == 7) np = 0x40;
2620 else if (prot == 5) np = 0x20;
2621 else if (prot == 4) np = 0x10;
2622 else if (prot == 3) np = 0x04;
2623 else if (prot == 1) np = 0x02;
2624 else if (prot == 0) np = 0x01;
2626 if (VirtualProtect (addr, len, np, &op))
2627 return 0;
2628 else
2629 return -1;
2633 #endif
2635 #ifdef TRANSFER_FROM_TRAMPOLINE
2636 TRANSFER_FROM_TRAMPOLINE
2637 #endif
2639 #if defined (NeXT) && defined (__MACH__)
2641 /* Make stack executable so we can call trampolines on stack.
2642 This is called from INITIALIZE_TRAMPOLINE in next.h. */
2643 #ifdef NeXTStep21
2644 #include <mach.h>
2645 #else
2646 #include <mach/mach.h>
2647 #endif
2649 void
2650 __enable_execute_stack (char *addr)
2652 kern_return_t r;
2653 char *eaddr = addr + TRAMPOLINE_SIZE;
2654 vm_address_t a = (vm_address_t) addr;
2656 /* turn on execute access on stack */
2657 r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
2658 if (r != KERN_SUCCESS)
2660 mach_error("vm_protect VM_PROT_ALL", r);
2661 exit(1);
2664 /* We inline the i-cache invalidation for speed */
2666 #ifdef CLEAR_INSN_CACHE
2667 CLEAR_INSN_CACHE (addr, eaddr);
2668 #else
2669 __clear_cache ((int) addr, (int) eaddr);
2670 #endif
2673 #endif /* defined (NeXT) && defined (__MACH__) */
2675 #ifdef __convex__
2677 /* Make stack executable so we can call trampolines on stack.
2678 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
2680 #include <sys/mman.h>
2681 #include <sys/vmparam.h>
2682 #include <machine/machparam.h>
2684 void
2685 __enable_execute_stack ()
2687 int fp;
2688 static unsigned lowest = USRSTACK;
2689 unsigned current = (unsigned) &fp & -NBPG;
2691 if (lowest > current)
2693 unsigned len = lowest - current;
2694 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
2695 lowest = current;
2698 /* Clear instruction cache in case an old trampoline is in it. */
2699 asm ("pich");
2701 #endif /* __convex__ */
2703 #ifdef __DOLPHIN__
2705 /* Modified from the convex -code above. */
2707 #include <sys/param.h>
2708 #include <errno.h>
2709 #include <sys/m88kbcs.h>
2711 void
2712 __enable_execute_stack ()
2714 int save_errno;
2715 static unsigned long lowest = USRSTACK;
2716 unsigned long current = (unsigned long) &save_errno & -NBPC;
2718 /* Ignore errno being set. memctl sets errno to EINVAL whenever the
2719 address is seen as 'negative'. That is the case with the stack. */
2721 save_errno=errno;
2722 if (lowest > current)
2724 unsigned len=lowest-current;
2725 memctl(current,len,MCT_TEXT);
2726 lowest = current;
2728 else
2729 memctl(current,NBPC,MCT_TEXT);
2730 errno=save_errno;
2733 #endif /* __DOLPHIN__ */
2735 #ifdef __pyr__
2737 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2738 #include <stdio.h>
2739 #include <sys/mman.h>
2740 #include <sys/types.h>
2741 #include <sys/param.h>
2742 #include <sys/vmmac.h>
2744 /* Modified from the convex -code above.
2745 mremap promises to clear the i-cache. */
2747 void
2748 __enable_execute_stack ()
2750 int fp;
2751 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
2752 PROT_READ|PROT_WRITE|PROT_EXEC))
2754 perror ("mprotect in __enable_execute_stack");
2755 fflush (stderr);
2756 abort ();
2759 #endif /* __pyr__ */
2761 #if defined (sony_news) && defined (SYSTYPE_BSD)
2763 #include <stdio.h>
2764 #include <sys/types.h>
2765 #include <sys/param.h>
2766 #include <syscall.h>
2767 #include <machine/sysnews.h>
2769 /* cacheflush function for NEWS-OS 4.2.
2770 This function is called from trampoline-initialize code
2771 defined in config/mips/mips.h. */
2773 void
2774 cacheflush (char *beg, int size, int flag)
2776 if (syscall (SYS_sysnews, NEWS_CACHEFLUSH, beg, size, FLUSH_BCACHE))
2778 perror ("cache_flush");
2779 fflush (stderr);
2780 abort ();
2784 #endif /* sony_news */
2785 #endif /* L_trampoline */
2787 #ifdef L__main
2789 #include "gbl-ctors.h"
2790 /* Some systems use __main in a way incompatible with its use in gcc, in these
2791 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2792 give the same symbol without quotes for an alternative entry point. You
2793 must define both, or neither. */
2794 #ifndef NAME__MAIN
2795 #define NAME__MAIN "__main"
2796 #define SYMBOL__MAIN __main
2797 #endif
2799 #ifdef INIT_SECTION_ASM_OP
2800 #undef HAS_INIT_SECTION
2801 #define HAS_INIT_SECTION
2802 #endif
2804 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
2805 /* Run all the global destructors on exit from the program. */
2807 void
2808 __do_global_dtors ()
2810 #ifdef DO_GLOBAL_DTORS_BODY
2811 DO_GLOBAL_DTORS_BODY;
2812 #else
2813 static func_ptr *p = __DTOR_LIST__ + 1;
2814 while (*p)
2816 p++;
2817 (*(p-1)) ();
2819 #endif
2821 #endif
2823 #ifndef HAS_INIT_SECTION
2824 /* Run all the global constructors on entry to the program. */
2826 #ifndef ON_EXIT
2827 #define ON_EXIT(a, b)
2828 #else
2829 /* Make sure the exit routine is pulled in to define the globals as
2830 bss symbols, just in case the linker does not automatically pull
2831 bss definitions from the library. */
2833 extern int _exit_dummy_decl;
2834 int *_exit_dummy_ref = &_exit_dummy_decl;
2835 #endif /* ON_EXIT */
2837 void
2838 __do_global_ctors ()
2840 DO_GLOBAL_CTORS_BODY;
2841 ON_EXIT (__do_global_dtors, 0);
2843 #endif /* no HAS_INIT_SECTION */
2845 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
2846 /* Subroutine called automatically by `main'.
2847 Compiling a global function named `main'
2848 produces an automatic call to this function at the beginning.
2850 For many systems, this routine calls __do_global_ctors.
2851 For systems which support a .init section we use the .init section
2852 to run __do_global_ctors, so we need not do anything here. */
2854 void
2855 SYMBOL__MAIN ()
2857 /* Support recursive calls to `main': run initializers just once. */
2858 static int initialized;
2859 if (! initialized)
2861 initialized = 1;
2862 __do_global_ctors ();
2865 #endif /* no HAS_INIT_SECTION or INVOKE__main */
2867 #endif /* L__main */
2869 #ifdef L_ctors
2871 #include "gbl-ctors.h"
2873 /* Provide default definitions for the lists of constructors and
2874 destructors, so that we don't get linker errors. These symbols are
2875 intentionally bss symbols, so that gld and/or collect will provide
2876 the right values. */
2878 /* We declare the lists here with two elements each,
2879 so that they are valid empty lists if no other definition is loaded. */
2880 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
2881 #if defined(__NeXT__) || defined(_AIX)
2882 /* After 2.3, try this definition on all systems. */
2883 func_ptr __CTOR_LIST__[2] = {0, 0};
2884 func_ptr __DTOR_LIST__[2] = {0, 0};
2885 #else
2886 func_ptr __CTOR_LIST__[2];
2887 func_ptr __DTOR_LIST__[2];
2888 #endif
2889 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
2890 #endif /* L_ctors */
2892 #ifdef L_exit
2894 #include "gbl-ctors.h"
2896 #ifdef NEED_ATEXIT
2897 # ifdef ON_EXIT
2898 # undef ON_EXIT
2899 # endif
2900 int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */
2901 #endif
2903 #ifndef ON_EXIT
2905 #ifdef NEED_ATEXIT
2906 # include <errno.h>
2908 static func_ptr *atexit_chain = NULL;
2909 static long atexit_chain_length = 0;
2910 static volatile long last_atexit_chain_slot = -1;
2912 int atexit (func_ptr func)
2914 if (++last_atexit_chain_slot == atexit_chain_length)
2916 atexit_chain_length += 32;
2917 if (atexit_chain)
2918 atexit_chain = realloc (atexit_chain,
2919 atexit_chain_length * sizeof (func_ptr));
2920 else
2921 atexit_chain = malloc (atexit_chain_length * sizeof (func_ptr));
2922 if (! atexit_chain)
2924 atexit_chain_length = 0;
2925 last_atexit_chain_slot = -1;
2926 errno = ENOMEM;
2927 return (-1);
2930 atexit_chain[last_atexit_chain_slot] = func;
2931 return (0);
2933 #endif /* NEED_ATEXIT */
2935 /* If we have no known way of registering our own __do_global_dtors
2936 routine so that it will be invoked at program exit time, then we
2937 have to define our own exit routine which will get this to happen. */
2939 extern void __do_global_dtors ();
2940 extern void _cleanup ();
2941 extern void _exit () __attribute__ ((noreturn));
2943 void
2944 exit (int status)
2946 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2947 #ifdef NEED_ATEXIT
2948 if (atexit_chain)
2950 for ( ; last_atexit_chain_slot-- >= 0; )
2952 (*atexit_chain[last_atexit_chain_slot + 1]) ();
2953 atexit_chain[last_atexit_chain_slot + 1] = NULL;
2955 free (atexit_chain);
2956 atexit_chain = NULL;
2958 #else /* No NEED_ATEXIT */
2959 __do_global_dtors ();
2960 #endif /* No NEED_ATEXIT */
2961 #endif
2962 #ifdef EXIT_BODY
2963 EXIT_BODY;
2964 #else
2965 _cleanup ();
2966 #endif
2967 _exit (status);
2970 #else
2971 int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */
2972 #endif
2974 #endif /* L_exit */
2976 #ifdef L_eh
2978 #ifdef EH_TABLE_LOOKUP
2980 EH_TABLE_LOOKUP
2982 #else
2984 typedef struct {
2985 void *start;
2986 void *end;
2987 void *exception_handler;
2988 } exception_table;
2990 struct exception_table_node {
2991 exception_table *table;
2992 void *start;
2993 void *end;
2994 struct exception_table_node *next;
2997 static struct exception_table_node *exception_table_list;
2999 static exception_table *
3000 find_exception_table (void *pc)
3002 register struct exception_table_node *table = exception_table_list;
3003 for ( ; table != 0; table = table->next)
3005 if (table->start <= pc && table->end > pc)
3006 return table->table;
3008 return 0;
3011 /* this routine takes a pc, and the address of the exception handler associated
3012 with the closest exception table handler entry associated with that PC,
3013 or 0 if there are no table entries the PC fits in. The algorithm works
3014 something like this:
3016 while(current_entry exists) {
3017 if(current_entry.start < pc )
3018 current_entry = next_entry;
3019 else {
3020 if(prev_entry.start <= pc && prev_entry.end > pc) {
3021 save pointer to prev_entry;
3022 return prev_entry.exception_handler;
3024 else return 0;
3027 return 0;
3029 Assuming a correctly sorted table (ascending order) this routine should
3030 return the tightest match...
3032 In the advent of a tie, we have to give the last entry, as it represents
3033 an inner block. */
3035 void *
3036 __find_first_exception_table_match (void *pc)
3038 exception_table *table = find_exception_table (pc);
3039 int pos = 0;
3040 int best = 0;
3041 if (table == 0)
3042 return (void *) 0;
3043 #if 0
3044 printf ("find_first_exception_table_match (): pc = %x!\n", pc);
3045 #endif
3047 #if 0
3048 /* We can't do this yet, as we don't know that the table is sorted. */
3049 do {
3050 ++pos;
3051 if (table[pos].start > pc)
3052 /* found the first table[pos].start > pc, so the previous
3053 entry better be the one we want! */
3054 break;
3055 } while (table[pos].exception_handler != (void *) -1);
3057 --pos;
3058 if (table[pos].start <= pc && table[pos].end > pc)
3060 #if 0
3061 printf ("find_first_eh_table_match (): found match: %x\n", table[pos].exception_handler);
3062 #endif
3063 return table[pos].exception_handler;
3065 #else
3066 while (table[++pos].exception_handler != (void *) -1) {
3067 if (table[pos].start <= pc && table[pos].end > pc)
3069 /* This can apply. Make sure it is better or as good as the previous
3070 best. */
3071 /* The best one ends first. */
3072 if (best == 0 || (table[pos].end <= table[best].end
3073 /* The best one starts last. */
3074 && table[pos].start >= table[best].start))
3075 best = pos;
3078 if (best != 0)
3079 return table[best].exception_handler;
3080 #endif
3082 #if 0
3083 printf ("find_first_eh_table_match (): else: returning NULL!\n");
3084 #endif
3085 return (void *) 0;
3088 void
3089 __register_exceptions (exception_table *table)
3091 struct exception_table_node *node;
3092 exception_table *range = table + 1;
3094 if (range->start == (void *) -1)
3095 return;
3097 node = (struct exception_table_node *)
3098 malloc (sizeof (struct exception_table_node));
3099 node->table = table;
3101 /* This look can be optimized away either if the table
3102 is sorted, or if we pass in extra parameters. */
3103 node->start = range->start;
3104 node->end = range->end;
3105 for (range++ ; range->start != (void *) (-1); range++)
3107 if (range->start < node->start)
3108 node->start = range->start;
3109 if (range->end > node->end)
3110 node->end = range->end;
3113 node->next = exception_table_list;
3114 exception_table_list = node;
3116 #endif
3118 void *
3119 __throw_type_match (void *catch_type, void *throw_type, void *obj)
3121 #if 0
3122 printf ("__throw_type_match (): catch_type = %s, throw_type = %s\n",
3123 catch_type, throw_type);
3124 #endif
3125 if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)
3126 return obj;
3127 return 0;
3130 /* Throw stub routine.
3132 This is work in progress, but not completed yet. */
3134 void
3135 __throw ()
3137 abort ();
3140 /* This value identifies the place from which an exception is being
3141 thrown. */
3143 void *__eh_pc;
3145 void
3146 __empty ()
3150 #if #machine(i386)
3151 void
3152 __unwind_function(void *ptr)
3154 asm("movl 8(%esp),%ecx");
3155 /* Undo current frame */
3156 asm("movl %ebp,%esp");
3157 asm("popl %ebp");
3158 /* like ret, but stay here */
3159 asm("addl $4,%esp");
3161 /* Now, undo previous frame. */
3162 /* This is a test routine, as we have to dynamically probe to find out
3163 what to pop for certain, this is just a guess. */
3164 asm("leal -16(%ebp),%esp");
3165 asm("pop %ebx");
3166 asm("pop %esi");
3167 asm("pop %edi");
3168 asm("movl %ebp,%esp");
3169 asm("popl %ebp");
3171 asm("movl %ecx,0(%esp)");
3172 asm("ret");
3174 #elif #machine(rs6000) && !defined _ARCH_PPC
3175 __unwind_function(void *ptr)
3177 asm("mr 31,1");
3178 asm("l 1,0(1)");
3179 asm("l 31,-4(1)");
3180 asm("# br");
3182 asm("mr 31,1");
3183 asm("l 1,0(1)");
3184 /* use 31 as a scratch register to restore the link register. */
3185 asm("l 31, 8(1);mtlr 31 # l lr,8(1)");
3186 asm("l 31,-4(1)");
3187 asm("# br");
3188 asm("mtctr 3;bctr # b 3");
3190 #elif (#machine(rs6000) || #machine(powerpc)) && defined _ARCH_PPC
3191 __unwind_function(void *ptr)
3193 asm("mr 31,1");
3194 asm("lwz 1,0(1)");
3195 asm("lwz 31,-4(1)");
3196 asm("# br");
3198 asm("mr 31,1");
3199 asm("lwz 1,0(1)");
3200 /* use 31 as a scratch register to restore the link register. */
3201 asm("lwz 31, 8(1);mtlr 31 # l lr,8(1)");
3202 asm("lwz 31,-4(1)");
3203 asm("# br");
3204 asm("mtctr 3;bctr # b 3");
3206 #elif #machine(vax)
3207 __unwind_function(void *ptr)
3209 __label__ return_again;
3211 /* Replace our frame's return address with the label below.
3212 During execution, we will first return here instead of to
3213 caller, then second return takes caller's frame off the stack.
3214 Two returns matches two actual calls, so is less likely to
3215 confuse debuggers. `16' corresponds to RETURN_ADDRESS_OFFSET. */
3216 __asm ("movl %0,16(fp)" : : "p" (&& return_again));
3217 return;
3219 return_again:
3220 return;
3222 #else
3223 __unwind_function(void *ptr)
3225 abort ();
3227 #endif /* powerpc */
3228 #endif /* L_eh */
3230 #ifdef L_pure
3231 #ifndef inhibit_libc
3232 /* This gets us __GNU_LIBRARY__. */
3233 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
3234 #include <stdio.h>
3236 #ifdef __GNU_LIBRARY__
3237 /* Avoid forcing the library's meaning of `write' on the user program
3238 by using the "internal" name (for use within the library) */
3239 #define write(fd, buf, n) __write((fd), (buf), (n))
3240 #endif
3241 #endif /* inhibit_libc */
3243 #define MESSAGE "pure virtual method called\n"
3245 void
3246 __pure_virtual ()
3248 #ifndef inhibit_libc
3249 write (2, MESSAGE, sizeof (MESSAGE) - 1);
3250 #endif
3251 _exit (-1);
3253 #endif