* i386.c (notice_update_cc): Remove bogus pentium GCC code.
[official-gcc.git] / gcc / libgcc2.c
blob23181b3e85cb34cd2bb00327fbff424e209f6a76
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"
1441 #include "gcov-io.h"
1443 static struct bb *bb_head;
1445 /* Return the number of digits needed to print a value */
1446 /* __inline__ */ static int num_digits (long value, int base)
1448 int minus = (value < 0 && base != 16);
1449 unsigned long v = (minus) ? -value : value;
1450 int ret = minus;
1454 v /= base;
1455 ret++;
1457 while (v);
1459 return ret;
1462 void
1463 __bb_exit_func (void)
1465 FILE *da_file, *file;
1466 long time_value;
1467 int i;
1469 if (bb_head == 0)
1470 return;
1472 i = strlen (bb_head->filename) - 3;
1474 if (!strcmp (bb_head->filename+i, ".da"))
1476 /* Must be -fprofile-arcs not -a.
1477 Dump data in a form that gcov expects. */
1479 struct bb *ptr;
1481 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1483 /* If the file exists, and the number of counts in it is the same,
1484 then merge them in. */
1486 if ((da_file = fopen (ptr->filename, "r")) != 0)
1488 long n_counts = 0;
1489 unsigned char tmp;
1490 int i;
1491 int ret = 0;
1494 if (__read_long (&n_counts, da_file, 8) != 0)
1496 fprintf (stderr, "arc profiling: Can't read output file %s.\n",
1497 ptr->filename);
1498 continue;
1501 if (n_counts == ptr->ncounts)
1503 int i;
1505 for (i = 0; i < n_counts; i++)
1507 long v = 0;
1508 unsigned char tmp;
1509 int j;
1510 int ret = 0;
1512 if (__read_long (&v, da_file, 8) != 0)
1514 fprintf (stderr, "arc profiling: Can't read output file %s.\n",
1515 ptr->filename);
1516 break;
1518 ptr->counts[i] += v;
1522 if (fclose (da_file) == EOF)
1523 fprintf (stderr, "arc profiling: Error closing output file %s.\n",
1524 ptr->filename);
1526 if ((da_file = fopen (ptr->filename, "w")) < 0)
1528 fprintf (stderr, "arc profiling: Can't open output file %s.\n",
1529 ptr->filename);
1530 continue;
1533 /* ??? Should first write a header to the file. Perferably, a 4 byte
1534 magic number, 4 bytes containing the time the program was
1535 compiled, 4 bytes containing the last modification time of the
1536 source file, and 4 bytes indicating the compiler options used.
1538 That way we can easily verify that the proper source/executable/
1539 data file combination is being used from gcov. */
1541 if (__write_long (ptr->ncounts, da_file, 8) != 0)
1544 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1545 ptr->filename);
1547 else
1549 int j;
1550 long *count_ptr = ptr->counts;
1551 int ret = 0;
1552 for (j = ptr->ncounts; j > 0; j--)
1554 if (__write_long (*count_ptr, da_file, 8) != 0)
1556 ret=1;
1557 break;
1559 count_ptr++;
1561 if (ret)
1562 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1563 ptr->filename);
1566 if (fclose (da_file) == EOF)
1567 fprintf (stderr, "arc profiling: Error closing output file %s.\n",
1568 ptr->filename);
1571 return;
1574 /* Must be basic block profiling. Emit a human readable output file. */
1576 file = fopen ("bb.out", "a");
1578 if (!file)
1579 perror ("bb.out");
1581 else
1583 struct bb *ptr;
1585 /* This is somewhat type incorrect, but it avoids worrying about
1586 exactly where time.h is included from. It should be ok unless
1587 a void * differs from other pointer formats, or if sizeof (long)
1588 is < sizeof (time_t). It would be nice if we could assume the
1589 use of rationale standards here. */
1591 time ((void *) &time_value);
1592 fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value));
1594 /* We check the length field explicitly in order to allow compatibility
1595 with older GCC's which did not provide it. */
1597 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1599 int i;
1600 int func_p = (ptr->nwords >= sizeof (struct bb)
1601 && ptr->nwords <= 1000
1602 && ptr->functions);
1603 int line_p = (func_p && ptr->line_nums);
1604 int file_p = (func_p && ptr->filenames);
1605 int addr_p = (ptr->addresses != 0);
1606 long ncounts = ptr->ncounts;
1607 long cnt_max = 0;
1608 long line_max = 0;
1609 long addr_max = 0;
1610 int file_len = 0;
1611 int func_len = 0;
1612 int blk_len = num_digits (ncounts, 10);
1613 int cnt_len;
1614 int line_len;
1615 int addr_len;
1617 fprintf (file, "File %s, %ld basic blocks \n\n",
1618 ptr->filename, ncounts);
1620 /* Get max values for each field. */
1621 for (i = 0; i < ncounts; i++)
1623 const char *p;
1624 int len;
1626 if (cnt_max < ptr->counts[i])
1627 cnt_max = ptr->counts[i];
1629 if (addr_p && addr_max < ptr->addresses[i])
1630 addr_max = ptr->addresses[i];
1632 if (line_p && line_max < ptr->line_nums[i])
1633 line_max = ptr->line_nums[i];
1635 if (func_p)
1637 p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>";
1638 len = strlen (p);
1639 if (func_len < len)
1640 func_len = len;
1643 if (file_p)
1645 p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>";
1646 len = strlen (p);
1647 if (file_len < len)
1648 file_len = len;
1652 addr_len = num_digits (addr_max, 16);
1653 cnt_len = num_digits (cnt_max, 10);
1654 line_len = num_digits (line_max, 10);
1656 /* Now print out the basic block information. */
1657 for (i = 0; i < ncounts; i++)
1659 fprintf (file,
1660 " Block #%*d: executed %*ld time(s)",
1661 blk_len, i+1,
1662 cnt_len, ptr->counts[i]);
1664 if (addr_p)
1665 fprintf (file, " address= 0x%.*lx", addr_len,
1666 ptr->addresses[i]);
1668 if (func_p)
1669 fprintf (file, " function= %-*s", func_len,
1670 (ptr->functions[i]) ? ptr->functions[i] : "<none>");
1672 if (line_p)
1673 fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]);
1675 if (file_p)
1676 fprintf (file, " file= %s",
1677 (ptr->filenames[i]) ? ptr->filenames[i] : "<none>");
1679 fprintf (file, "\n");
1682 fprintf (file, "\n");
1683 fflush (file);
1686 fprintf (file, "\n\n");
1687 fclose (file);
1691 void
1692 __bb_init_func (struct bb *blocks)
1694 /* User is supposed to check whether the first word is non-0,
1695 but just in case.... */
1697 if (blocks->zero_word)
1698 return;
1700 #ifdef ON_EXIT
1701 /* Initialize destructor. */
1702 if (!bb_head)
1703 ON_EXIT (__bb_exit_func, 0);
1704 #endif
1706 /* Set up linked list. */
1707 blocks->zero_word = 1;
1708 blocks->next = bb_head;
1709 bb_head = blocks;
1712 #ifndef MACHINE_STATE_SAVE
1713 #define MACHINE_STATE_SAVE(ID)
1714 #endif
1715 #ifndef MACHINE_STATE_RESTORE
1716 #define MACHINE_STATE_RESTORE(ID)
1717 #endif
1719 #include <string.h>
1721 /* Number of buckets in hashtable of basic block addresses. */
1723 #define BB_BUCKETS 311
1725 /* Maximum length of string in file bb.in. */
1727 #define BBINBUFSIZE 500
1729 /* BBINBUFSIZE-1 with double quotes. We could use #BBINBUFSIZE or
1730 "BBINBUFSIZE" but want to avoid trouble with preprocessors. */
1732 #define BBINBUFSIZESTR "499"
1734 struct bb_edge
1736 struct bb_edge *next;
1737 unsigned long src_addr;
1738 unsigned long dst_addr;
1739 unsigned long count;
1742 enum bb_func_mode
1744 TRACE_KEEP = 0, TRACE_ON = 1, TRACE_OFF = 2
1747 struct bb_func
1749 struct bb_func *next;
1750 char *funcname;
1751 char *filename;
1752 enum bb_func_mode mode;
1755 /* This is the connection to the outside world.
1756 The BLOCK_PROFILER macro must set __bb.blocks
1757 and __bb.blockno. */
1759 struct {
1760 unsigned long blockno;
1761 struct bb *blocks;
1762 } __bb;
1764 /* Vars to store addrs of source and destination basic blocks
1765 of a jump. */
1767 static unsigned long bb_src = 0;
1768 static unsigned long bb_dst = 0;
1770 static FILE *bb_tracefile = (FILE *) 0;
1771 static struct bb_edge **bb_hashbuckets = (struct bb_edge **) 0;
1772 static struct bb_func *bb_func_head = (struct bb_func *) 0;
1773 static unsigned long bb_callcount = 0;
1774 static int bb_mode = 0;
1776 static unsigned long *bb_stack = (unsigned long *) 0;
1777 static size_t bb_stacksize = 0;
1779 static int reported = 0;
1781 /* Trace modes:
1782 Always : Print execution frequencies of basic blocks
1783 to file bb.out.
1784 bb_mode & 1 != 0 : Dump trace of basic blocks to file bbtrace[.gz]
1785 bb_mode & 2 != 0 : Print jump frequencies to file bb.out.
1786 bb_mode & 4 != 0 : Cut call instructions from basic block flow.
1787 bb_mode & 8 != 0 : Insert return instructions in basic block flow.
1790 #ifdef HAVE_POPEN
1792 /*#include <sys/types.h>*/
1793 #include <sys/stat.h>
1794 /*#include <malloc.h>*/
1796 /* Commands executed by gopen. */
1798 #define GOPENDECOMPRESS "gzip -cd "
1799 #define GOPENCOMPRESS "gzip -c >"
1801 /* Like fopen but pipes through gzip. mode may only be "r" or "w".
1802 If it does not compile, simply replace gopen by fopen and delete
1803 '.gz' from any first parameter to gopen. */
1805 static FILE *
1806 gopen (char *fn, char *mode)
1808 int use_gzip;
1809 char *p;
1811 if (mode[1])
1812 return (FILE *) 0;
1814 if (mode[0] != 'r' && mode[0] != 'w')
1815 return (FILE *) 0;
1817 p = fn + strlen (fn)-1;
1818 use_gzip = ((p[-1] == '.' && (p[0] == 'Z' || p[0] == 'z'))
1819 || (p[-2] == '.' && p[-1] == 'g' && p[0] == 'z'));
1821 if (use_gzip)
1823 if (mode[0]=='r')
1825 FILE *f;
1826 char *s = (char *) malloc (sizeof (char) * strlen (fn)
1827 + sizeof (GOPENDECOMPRESS));
1828 strcpy (s, GOPENDECOMPRESS);
1829 strcpy (s + (sizeof (GOPENDECOMPRESS)-1), fn);
1830 f = popen (s, mode);
1831 free (s);
1832 return f;
1835 else
1837 FILE *f;
1838 char *s = (char *) malloc (sizeof (char) * strlen (fn)
1839 + sizeof (GOPENCOMPRESS));
1840 strcpy (s, GOPENCOMPRESS);
1841 strcpy (s + (sizeof (GOPENCOMPRESS)-1), fn);
1842 if (!(f = popen (s, mode)))
1843 f = fopen (s, mode);
1844 free (s);
1845 return f;
1849 else
1850 return fopen (fn, mode);
1853 static int
1854 gclose (FILE *f)
1856 struct stat buf;
1858 if (f != 0)
1860 if (!fstat (fileno (f), &buf) && S_ISFIFO (buf.st_mode))
1861 return pclose (f);
1863 return fclose (f);
1865 return 0;
1868 #endif /* HAVE_POPEN */
1870 /* Called once per program. */
1872 static void
1873 __bb_exit_trace_func ()
1875 FILE *file = fopen ("bb.out", "a");
1876 struct bb_func *f;
1877 struct bb_edge *e;
1878 struct bb *b;
1880 if (!file)
1881 perror ("bb.out");
1883 if (bb_mode & 1)
1885 if (!bb_tracefile)
1886 perror ("bbtrace");
1887 else
1888 #ifdef HAVE_POPEN
1889 gclose (bb_tracefile);
1890 #else
1891 fclose (bb_tracefile);
1892 #endif /* HAVE_POPEN */
1895 /* Check functions in `bb.in'. */
1897 if (file)
1899 long time_value;
1900 const struct bb_func *p;
1901 int printed_something = 0;
1902 struct bb *ptr;
1903 long blk;
1905 /* This is somewhat type incorrect. */
1906 time ((void *) &time_value);
1908 for (p = bb_func_head; p != (struct bb_func *) 0; p = p->next)
1910 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1912 if (!ptr->filename || p->filename != (char *) 0 && strcmp (p->filename, ptr->filename))
1913 continue;
1914 for (blk = 0; blk < ptr->ncounts; blk++)
1916 if (!strcmp (p->funcname, ptr->functions[blk]))
1917 goto found;
1921 if (!printed_something)
1923 fprintf (file, "Functions in `bb.in' not executed during basic block profiling on %s\n", ctime ((void *) &time_value));
1924 printed_something = 1;
1927 fprintf (file, "\tFunction %s", p->funcname);
1928 if (p->filename)
1929 fprintf (file, " of file %s", p->filename);
1930 fprintf (file, "\n" );
1932 found: ;
1935 if (printed_something)
1936 fprintf (file, "\n");
1940 if (bb_mode & 2)
1942 if (!bb_hashbuckets)
1944 if (!reported)
1946 fprintf (stderr, "Profiler: out of memory\n");
1947 reported = 1;
1949 return;
1952 else if (file)
1954 long time_value;
1955 int i;
1956 unsigned long addr_max = 0;
1957 unsigned long cnt_max = 0;
1958 int cnt_len;
1959 int addr_len;
1961 /* This is somewhat type incorrect, but it avoids worrying about
1962 exactly where time.h is included from. It should be ok unless
1963 a void * differs from other pointer formats, or if sizeof (long)
1964 is < sizeof (time_t). It would be nice if we could assume the
1965 use of rationale standards here. */
1967 time ((void *) &time_value);
1968 fprintf (file, "Basic block jump tracing");
1970 switch (bb_mode & 12)
1972 case 0:
1973 fprintf (file, " (with call)");
1974 break;
1976 case 4:
1977 /* Print nothing. */
1978 break;
1980 case 8:
1981 fprintf (file, " (with call & ret)");
1982 break;
1984 case 12:
1985 fprintf (file, " (with ret)");
1986 break;
1989 fprintf (file, " finished on %s\n", ctime ((void *) &time_value));
1991 for (i = 0; i < BB_BUCKETS; i++)
1993 struct bb_edge *bucket = bb_hashbuckets[i];
1994 for ( ; bucket; bucket = bucket->next )
1996 if (addr_max < bucket->src_addr)
1997 addr_max = bucket->src_addr;
1998 if (addr_max < bucket->dst_addr)
1999 addr_max = bucket->dst_addr;
2000 if (cnt_max < bucket->count)
2001 cnt_max = bucket->count;
2004 addr_len = num_digits (addr_max, 16);
2005 cnt_len = num_digits (cnt_max, 10);
2007 for ( i = 0; i < BB_BUCKETS; i++)
2009 struct bb_edge *bucket = bb_hashbuckets[i];
2010 for ( ; bucket; bucket = bucket->next )
2012 fprintf (file, "Jump from block 0x%.*lx to "
2013 "block 0x%.*lx executed %*d time(s)\n",
2014 addr_len, bucket->src_addr,
2015 addr_len, bucket->dst_addr,
2016 cnt_len, bucket->count);
2020 fprintf (file, "\n");
2025 if (file)
2026 fclose (file);
2028 /* Free allocated memory. */
2030 f = bb_func_head;
2031 while (f)
2033 struct bb_func *old = f;
2035 f = f->next;
2036 if (old->funcname) free (old->funcname);
2037 if (old->filename) free (old->filename);
2038 free (old);
2041 if (bb_stack)
2042 free (bb_stack);
2044 if (bb_hashbuckets)
2046 int i;
2048 for (i = 0; i < BB_BUCKETS; i++)
2050 struct bb_edge *old, *bucket = bb_hashbuckets[i];
2052 while (bucket)
2054 old = bucket;
2055 bucket = bucket->next;
2056 free (old);
2059 free (bb_hashbuckets);
2062 for (b = bb_head; b; b = b->next)
2063 if (b->flags) free (b->flags);
2066 /* Called once per program. */
2068 static void
2069 __bb_init_prg ()
2072 FILE *file;
2073 char buf[BBINBUFSIZE];
2074 const char *p;
2075 const char *pos;
2076 enum bb_func_mode m;
2078 #ifdef ON_EXIT
2079 /* Initialize destructor. */
2080 ON_EXIT (__bb_exit_func, 0);
2081 #endif
2083 if (!(file = fopen ("bb.in", "r")))
2084 return;
2086 while(fscanf (file, " %" BBINBUFSIZESTR "s ", buf) != EOF)
2088 p = buf;
2089 if (*p == '-')
2091 m = TRACE_OFF;
2092 p++;
2094 else
2096 m = TRACE_ON;
2098 if (!strcmp (p, "__bb_trace__"))
2099 bb_mode |= 1;
2100 else if (!strcmp (p, "__bb_jumps__"))
2101 bb_mode |= 2;
2102 else if (!strcmp (p, "__bb_hidecall__"))
2103 bb_mode |= 4;
2104 else if (!strcmp (p, "__bb_showret__"))
2105 bb_mode |= 8;
2106 else
2108 struct bb_func *f = (struct bb_func *) malloc (sizeof (struct bb_func));
2109 if (f)
2111 unsigned long l;
2112 f->next = bb_func_head;
2113 if (pos = strchr (p, ':'))
2115 if (!(f->funcname = (char *) malloc (strlen (pos+1)+1)))
2116 continue;
2117 strcpy (f->funcname, pos+1);
2118 l = pos-p;
2119 if ((f->filename = (char *) malloc (l+1)))
2121 strncpy (f->filename, p, l);
2122 f->filename[l] = '\0';
2124 else
2125 f->filename = (char *) 0;
2127 else
2129 if (!(f->funcname = (char *) malloc (strlen (p)+1)))
2130 continue;
2131 strcpy (f->funcname, p);
2132 f->filename = (char *) 0;
2134 f->mode = m;
2135 bb_func_head = f;
2139 fclose (file);
2141 #ifdef HAVE_POPEN
2143 if (bb_mode & 1)
2144 bb_tracefile = gopen ("bbtrace.gz", "w");
2146 #else
2148 if (bb_mode & 1)
2149 bb_tracefile = fopen ("bbtrace", "w");
2151 #endif /* HAVE_POPEN */
2153 if (bb_mode & 2)
2155 bb_hashbuckets = (struct bb_edge **)
2156 malloc (BB_BUCKETS * sizeof (struct bb_edge *));
2157 if (bb_hashbuckets)
2158 bzero ((char *) bb_hashbuckets, BB_BUCKETS);
2161 if (bb_mode & 12)
2163 bb_stacksize = 10;
2164 bb_stack = (unsigned long *) malloc (bb_stacksize * sizeof (*bb_stack));
2167 #ifdef ON_EXIT
2168 /* Initialize destructor. */
2169 ON_EXIT (__bb_exit_trace_func, 0);
2170 #endif
2174 /* Called upon entering a basic block. */
2176 void
2177 __bb_trace_func ()
2179 struct bb_edge *bucket;
2181 MACHINE_STATE_SAVE("1")
2183 if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2184 goto skip;
2186 bb_dst = __bb.blocks->addresses[__bb.blockno];
2187 __bb.blocks->counts[__bb.blockno]++;
2189 if (bb_tracefile)
2191 fwrite (&bb_dst, sizeof (unsigned long), 1, bb_tracefile);
2194 if (bb_hashbuckets)
2196 struct bb_edge **startbucket, **oldnext;
2198 oldnext = startbucket
2199 = & bb_hashbuckets[ (((int) bb_src*8) ^ (int) bb_dst) % BB_BUCKETS ];
2200 bucket = *startbucket;
2202 for (bucket = *startbucket; bucket;
2203 oldnext = &(bucket->next), bucket = *oldnext)
2205 if (bucket->src_addr == bb_src
2206 && bucket->dst_addr == bb_dst)
2208 bucket->count++;
2209 *oldnext = bucket->next;
2210 bucket->next = *startbucket;
2211 *startbucket = bucket;
2212 goto ret;
2216 bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2218 if (!bucket)
2220 if (!reported)
2222 fprintf (stderr, "Profiler: out of memory\n");
2223 reported = 1;
2227 else
2229 bucket->src_addr = bb_src;
2230 bucket->dst_addr = bb_dst;
2231 bucket->next = *startbucket;
2232 *startbucket = bucket;
2233 bucket->count = 1;
2237 ret:
2238 bb_src = bb_dst;
2240 skip:
2243 MACHINE_STATE_RESTORE("1")
2247 /* Called when returning from a function and `__bb_showret__' is set. */
2249 static void
2250 __bb_trace_func_ret ()
2252 struct bb_edge *bucket;
2254 if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2255 goto skip;
2257 if (bb_hashbuckets)
2259 struct bb_edge **startbucket, **oldnext;
2261 oldnext = startbucket
2262 = & bb_hashbuckets[ (((int) bb_dst * 8) ^ (int) bb_src) % BB_BUCKETS ];
2263 bucket = *startbucket;
2265 for (bucket = *startbucket; bucket;
2266 oldnext = &(bucket->next), bucket = *oldnext)
2268 if (bucket->src_addr == bb_dst
2269 && bucket->dst_addr == bb_src)
2271 bucket->count++;
2272 *oldnext = bucket->next;
2273 bucket->next = *startbucket;
2274 *startbucket = bucket;
2275 goto ret;
2279 bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2281 if (!bucket)
2283 if (!reported)
2285 fprintf (stderr, "Profiler: out of memory\n");
2286 reported = 1;
2290 else
2292 bucket->src_addr = bb_dst;
2293 bucket->dst_addr = bb_src;
2294 bucket->next = *startbucket;
2295 *startbucket = bucket;
2296 bucket->count = 1;
2300 ret:
2301 bb_dst = bb_src;
2303 skip:
2308 /* Called upon entering the first function of a file. */
2310 static void
2311 __bb_init_file (struct bb *blocks)
2314 const struct bb_func *p;
2315 long blk, ncounts = blocks->ncounts;
2316 const char **functions = blocks->functions;
2318 /* Set up linked list. */
2319 blocks->zero_word = 1;
2320 blocks->next = bb_head;
2321 bb_head = blocks;
2323 blocks->flags = 0;
2324 if (!bb_func_head
2325 || !(blocks->flags = (char *) malloc (sizeof (char) * blocks->ncounts)))
2326 return;
2328 for (blk = 0; blk < ncounts; blk++)
2329 blocks->flags[blk] = 0;
2331 for (blk = 0; blk < ncounts; blk++)
2333 for (p = bb_func_head; p; p = p->next)
2335 if (!strcmp (p->funcname, functions[blk])
2336 && (!p->filename || !strcmp (p->filename, blocks->filename)))
2338 blocks->flags[blk] |= p->mode;
2345 /* Called when exiting from a function. */
2347 void
2348 __bb_trace_ret ()
2351 MACHINE_STATE_SAVE("2")
2353 if (bb_callcount)
2355 if ((bb_mode & 12) && bb_stacksize > bb_callcount)
2357 bb_src = bb_stack[bb_callcount];
2358 if (bb_mode & 8)
2359 __bb_trace_func_ret ();
2362 bb_callcount -= 1;
2365 MACHINE_STATE_RESTORE("2")
2369 /* Called when entering a function. */
2371 void
2372 __bb_init_trace_func (struct bb *blocks, unsigned long blockno)
2374 static int trace_init = 0;
2376 MACHINE_STATE_SAVE("3")
2378 if (!blocks->zero_word)
2380 if (!trace_init)
2382 trace_init = 1;
2383 __bb_init_prg ();
2385 __bb_init_file (blocks);
2388 if (bb_callcount)
2391 bb_callcount += 1;
2393 if (bb_mode & 12)
2395 if (bb_callcount >= bb_stacksize)
2397 size_t newsize = bb_callcount + 100;
2399 bb_stack = (unsigned long *) realloc (bb_stack, newsize);
2400 if (! bb_stack)
2402 if (!reported)
2404 fprintf (stderr, "Profiler: out of memory\n");
2405 reported = 1;
2407 bb_stacksize = 0;
2408 goto stack_overflow;
2410 bb_stacksize = newsize;
2412 bb_stack[bb_callcount] = bb_src;
2414 if (bb_mode & 4)
2415 bb_src = 0;
2419 stack_overflow:;
2423 else if (blocks->flags && (blocks->flags[blockno] & TRACE_ON))
2425 bb_callcount = 1;
2426 bb_src = 0;
2428 if (bb_stack)
2429 bb_stack[bb_callcount] = bb_src;
2432 MACHINE_STATE_RESTORE("3")
2435 #endif /* not inhibit_libc */
2436 #endif /* not BLOCK_PROFILER_CODE */
2437 #endif /* L_bb */
2439 /* Default free-store management functions for C++, per sections 12.5 and
2440 17.3.3 of the Working Paper. */
2442 #ifdef L_op_new
2443 /* operator new (size_t), described in 17.3.3.5. This function is used by
2444 C++ programs to allocate a block of memory to hold a single object. */
2446 typedef void (*vfp)(void);
2447 extern vfp __new_handler;
2448 extern void __default_new_handler (void);
2450 #ifdef WEAK_ALIAS
2451 void * __builtin_new (size_t sz)
2452 __attribute__ ((weak, alias ("___builtin_new")));
2453 void *
2454 ___builtin_new (size_t sz)
2455 #else
2456 void *
2457 __builtin_new (size_t sz)
2458 #endif
2460 void *p;
2461 vfp handler = (__new_handler) ? __new_handler : __default_new_handler;
2463 /* malloc (0) is unpredictable; avoid it. */
2464 if (sz == 0)
2465 sz = 1;
2466 p = (void *) malloc (sz);
2467 while (p == 0)
2469 (*handler) ();
2470 p = (void *) malloc (sz);
2473 return p;
2475 #endif /* L_op_new */
2477 #ifdef L_op_vnew
2478 /* void * operator new [] (size_t), described in 17.3.3.6. This function
2479 is used by C++ programs to allocate a block of memory for an array. */
2481 extern void * __builtin_new (size_t);
2483 #ifdef WEAK_ALIAS
2484 void * __builtin_vec_new (size_t sz)
2485 __attribute__ ((weak, alias ("___builtin_vec_new")));
2486 void *
2487 ___builtin_vec_new (size_t sz)
2488 #else
2489 void *
2490 __builtin_vec_new (size_t sz)
2491 #endif
2493 return __builtin_new (sz);
2495 #endif /* L_op_vnew */
2497 #ifdef L_new_handler
2498 /* set_new_handler (fvoid_t *) and the default new handler, described in
2499 17.3.3.2 and 17.3.3.5. These functions define the result of a failure
2500 to allocate the amount of memory requested from operator new or new []. */
2502 #ifndef inhibit_libc
2503 /* This gets us __GNU_LIBRARY__. */
2504 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2505 #include <stdio.h>
2507 #ifdef __GNU_LIBRARY__
2508 /* Avoid forcing the library's meaning of `write' on the user program
2509 by using the "internal" name (for use within the library) */
2510 #define write(fd, buf, n) __write((fd), (buf), (n))
2511 #endif
2512 #endif /* inhibit_libc */
2514 typedef void (*vfp)(void);
2515 void __default_new_handler (void);
2517 vfp __new_handler = (vfp) 0;
2520 set_new_handler (vfp handler)
2522 vfp prev_handler;
2524 prev_handler = __new_handler;
2525 if (handler == 0) handler = __default_new_handler;
2526 __new_handler = handler;
2527 return prev_handler;
2530 #define MESSAGE "Virtual memory exceeded in `new'\n"
2532 void
2533 __default_new_handler ()
2535 #ifndef inhibit_libc
2536 /* don't use fprintf (stderr, ...) because it may need to call malloc. */
2537 /* This should really print the name of the program, but that is hard to
2538 do. We need a standard, clean way to get at the name. */
2539 write (2, MESSAGE, sizeof (MESSAGE));
2540 #endif
2541 /* don't call exit () because that may call global destructors which
2542 may cause a loop. */
2543 _exit (-1);
2545 #endif
2547 #ifdef L_op_delete
2548 /* operator delete (void *), described in 17.3.3.3. This function is used
2549 by C++ programs to return to the free store a block of memory allocated
2550 as a single object. */
2552 #ifdef WEAK_ALIAS
2553 void __builtin_delete (void *ptr)
2554 __attribute__ ((weak, alias ("___builtin_delete")));
2555 void
2556 ___builtin_delete (void *ptr)
2557 #else
2558 void
2559 __builtin_delete (void *ptr)
2560 #endif
2562 if (ptr)
2563 free (ptr);
2565 #endif
2567 #ifdef L_op_vdel
2568 /* operator delete [] (void *), described in 17.3.3.4. This function is
2569 used by C++ programs to return to the free store a block of memory
2570 allocated as an array. */
2572 extern void __builtin_delete (void *);
2574 #ifdef WEAK_ALIAS
2575 void __builtin_vec_delete (void *ptr)
2576 __attribute__ ((weak, alias ("___builtin_vec_delete")));
2577 void
2578 ___builtin_vec_delete (void *ptr)
2579 #else
2580 void
2581 __builtin_vec_delete (void *ptr)
2582 #endif
2584 __builtin_delete (ptr);
2586 #endif
2588 /* End of C++ free-store management functions */
2590 #ifdef L_shtab
2591 unsigned int __shtab[] = {
2592 0x00000001, 0x00000002, 0x00000004, 0x00000008,
2593 0x00000010, 0x00000020, 0x00000040, 0x00000080,
2594 0x00000100, 0x00000200, 0x00000400, 0x00000800,
2595 0x00001000, 0x00002000, 0x00004000, 0x00008000,
2596 0x00010000, 0x00020000, 0x00040000, 0x00080000,
2597 0x00100000, 0x00200000, 0x00400000, 0x00800000,
2598 0x01000000, 0x02000000, 0x04000000, 0x08000000,
2599 0x10000000, 0x20000000, 0x40000000, 0x80000000
2601 #endif
2603 #ifdef L_clear_cache
2604 /* Clear part of an instruction cache. */
2606 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
2608 void
2609 __clear_cache (char *beg, char *end)
2611 #ifdef CLEAR_INSN_CACHE
2612 CLEAR_INSN_CACHE (beg, end);
2613 #else
2614 #ifdef INSN_CACHE_SIZE
2615 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
2616 static int initialized;
2617 int offset;
2618 void *start_addr
2619 void *end_addr;
2620 typedef (*function_ptr) ();
2622 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
2623 /* It's cheaper to clear the whole cache.
2624 Put in a series of jump instructions so that calling the beginning
2625 of the cache will clear the whole thing. */
2627 if (! initialized)
2629 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2630 & -INSN_CACHE_LINE_WIDTH);
2631 int end_ptr = ptr + INSN_CACHE_SIZE;
2633 while (ptr < end_ptr)
2635 *(INSTRUCTION_TYPE *)ptr
2636 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
2637 ptr += INSN_CACHE_LINE_WIDTH;
2639 *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
2641 initialized = 1;
2644 /* Call the beginning of the sequence. */
2645 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2646 & -INSN_CACHE_LINE_WIDTH))
2647 ());
2649 #else /* Cache is large. */
2651 if (! initialized)
2653 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2654 & -INSN_CACHE_LINE_WIDTH);
2656 while (ptr < (int) array + sizeof array)
2658 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
2659 ptr += INSN_CACHE_LINE_WIDTH;
2662 initialized = 1;
2665 /* Find the location in array that occupies the same cache line as BEG. */
2667 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
2668 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
2669 & -INSN_CACHE_PLANE_SIZE)
2670 + offset);
2672 /* Compute the cache alignment of the place to stop clearing. */
2673 #if 0 /* This is not needed for gcc's purposes. */
2674 /* If the block to clear is bigger than a cache plane,
2675 we clear the entire cache, and OFFSET is already correct. */
2676 if (end < beg + INSN_CACHE_PLANE_SIZE)
2677 #endif
2678 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
2679 & -INSN_CACHE_LINE_WIDTH)
2680 & (INSN_CACHE_PLANE_SIZE - 1));
2682 #if INSN_CACHE_DEPTH > 1
2683 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
2684 if (end_addr <= start_addr)
2685 end_addr += INSN_CACHE_PLANE_SIZE;
2687 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
2689 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
2690 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
2692 while (addr != stop)
2694 /* Call the return instruction at ADDR. */
2695 ((function_ptr) addr) ();
2697 addr += INSN_CACHE_LINE_WIDTH;
2700 #else /* just one plane */
2703 /* Call the return instruction at START_ADDR. */
2704 ((function_ptr) start_addr) ();
2706 start_addr += INSN_CACHE_LINE_WIDTH;
2708 while ((start_addr % INSN_CACHE_SIZE) != offset);
2709 #endif /* just one plane */
2710 #endif /* Cache is large */
2711 #endif /* Cache exists */
2712 #endif /* CLEAR_INSN_CACHE */
2715 #endif /* L_clear_cache */
2717 #ifdef L_trampoline
2719 /* Jump to a trampoline, loading the static chain address. */
2721 #if defined(WINNT) && ! defined(__CYGWIN32__)
2723 long getpagesize()
2725 #ifdef _ALPHA_
2726 return 8192;
2727 #else
2728 return 4096;
2729 #endif
2732 #ifdef i386
2733 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
2734 #endif
2737 mprotect (char *addr, int len, int prot)
2739 int np, op;
2741 if (prot == 7)
2742 np = 0x40;
2743 else if (prot == 5)
2744 np = 0x20;
2745 else if (prot == 4)
2746 np = 0x10;
2747 else if (prot == 3)
2748 np = 0x04;
2749 else if (prot == 1)
2750 np = 0x02;
2751 else if (prot == 0)
2752 np = 0x01;
2754 if (VirtualProtect (addr, len, np, &op))
2755 return 0;
2756 else
2757 return -1;
2760 #endif
2762 #ifdef TRANSFER_FROM_TRAMPOLINE
2763 TRANSFER_FROM_TRAMPOLINE
2764 #endif
2766 #if defined (NeXT) && defined (__MACH__)
2768 /* Make stack executable so we can call trampolines on stack.
2769 This is called from INITIALIZE_TRAMPOLINE in next.h. */
2770 #ifdef NeXTStep21
2771 #include <mach.h>
2772 #else
2773 #include <mach/mach.h>
2774 #endif
2776 void
2777 __enable_execute_stack (char *addr)
2779 kern_return_t r;
2780 char *eaddr = addr + TRAMPOLINE_SIZE;
2781 vm_address_t a = (vm_address_t) addr;
2783 /* turn on execute access on stack */
2784 r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
2785 if (r != KERN_SUCCESS)
2787 mach_error("vm_protect VM_PROT_ALL", r);
2788 exit(1);
2791 /* We inline the i-cache invalidation for speed */
2793 #ifdef CLEAR_INSN_CACHE
2794 CLEAR_INSN_CACHE (addr, eaddr);
2795 #else
2796 __clear_cache ((int) addr, (int) eaddr);
2797 #endif
2800 #endif /* defined (NeXT) && defined (__MACH__) */
2802 #ifdef __convex__
2804 /* Make stack executable so we can call trampolines on stack.
2805 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
2807 #include <sys/mman.h>
2808 #include <sys/vmparam.h>
2809 #include <machine/machparam.h>
2811 void
2812 __enable_execute_stack ()
2814 int fp;
2815 static unsigned lowest = USRSTACK;
2816 unsigned current = (unsigned) &fp & -NBPG;
2818 if (lowest > current)
2820 unsigned len = lowest - current;
2821 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
2822 lowest = current;
2825 /* Clear instruction cache in case an old trampoline is in it. */
2826 asm ("pich");
2828 #endif /* __convex__ */
2830 #ifdef __sysV88__
2832 /* Modified from the convex -code above. */
2834 #include <sys/param.h>
2835 #include <errno.h>
2836 #include <sys/m88kbcs.h>
2838 void
2839 __enable_execute_stack ()
2841 int save_errno;
2842 static unsigned long lowest = USRSTACK;
2843 unsigned long current = (unsigned long) &save_errno & -NBPC;
2845 /* Ignore errno being set. memctl sets errno to EINVAL whenever the
2846 address is seen as 'negative'. That is the case with the stack. */
2848 save_errno=errno;
2849 if (lowest > current)
2851 unsigned len=lowest-current;
2852 memctl(current,len,MCT_TEXT);
2853 lowest = current;
2855 else
2856 memctl(current,NBPC,MCT_TEXT);
2857 errno=save_errno;
2860 #endif /* __sysV88__ */
2862 #ifdef __pyr__
2864 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2865 #include <stdio.h>
2866 #include <sys/mman.h>
2867 #include <sys/types.h>
2868 #include <sys/param.h>
2869 #include <sys/vmmac.h>
2871 /* Modified from the convex -code above.
2872 mremap promises to clear the i-cache. */
2874 void
2875 __enable_execute_stack ()
2877 int fp;
2878 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
2879 PROT_READ|PROT_WRITE|PROT_EXEC))
2881 perror ("mprotect in __enable_execute_stack");
2882 fflush (stderr);
2883 abort ();
2886 #endif /* __pyr__ */
2888 #if defined (sony_news) && defined (SYSTYPE_BSD)
2890 #include <stdio.h>
2891 #include <sys/types.h>
2892 #include <sys/param.h>
2893 #include <syscall.h>
2894 #include <machine/sysnews.h>
2896 /* cacheflush function for NEWS-OS 4.2.
2897 This function is called from trampoline-initialize code
2898 defined in config/mips/mips.h. */
2900 void
2901 cacheflush (char *beg, int size, int flag)
2903 if (syscall (SYS_sysnews, NEWS_CACHEFLUSH, beg, size, FLUSH_BCACHE))
2905 perror ("cache_flush");
2906 fflush (stderr);
2907 abort ();
2911 #endif /* sony_news */
2912 #endif /* L_trampoline */
2914 #ifdef L__main
2916 #include "gbl-ctors.h"
2917 /* Some systems use __main in a way incompatible with its use in gcc, in these
2918 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2919 give the same symbol without quotes for an alternative entry point. You
2920 must define both, or neither. */
2921 #ifndef NAME__MAIN
2922 #define NAME__MAIN "__main"
2923 #define SYMBOL__MAIN __main
2924 #endif
2926 #ifdef INIT_SECTION_ASM_OP
2927 #undef HAS_INIT_SECTION
2928 #define HAS_INIT_SECTION
2929 #endif
2931 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
2932 /* Run all the global destructors on exit from the program. */
2934 void
2935 __do_global_dtors ()
2937 #ifdef DO_GLOBAL_DTORS_BODY
2938 DO_GLOBAL_DTORS_BODY;
2939 #else
2940 static func_ptr *p = __DTOR_LIST__ + 1;
2941 while (*p)
2943 p++;
2944 (*(p-1)) ();
2946 #endif
2948 #endif
2950 #ifndef HAS_INIT_SECTION
2951 /* Run all the global constructors on entry to the program. */
2953 #ifndef ON_EXIT
2954 #define ON_EXIT(a, b)
2955 #else
2956 /* Make sure the exit routine is pulled in to define the globals as
2957 bss symbols, just in case the linker does not automatically pull
2958 bss definitions from the library. */
2960 extern int _exit_dummy_decl;
2961 int *_exit_dummy_ref = &_exit_dummy_decl;
2962 #endif /* ON_EXIT */
2964 void
2965 __do_global_ctors ()
2967 DO_GLOBAL_CTORS_BODY;
2968 ON_EXIT (__do_global_dtors, 0);
2970 #endif /* no HAS_INIT_SECTION */
2972 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
2973 /* Subroutine called automatically by `main'.
2974 Compiling a global function named `main'
2975 produces an automatic call to this function at the beginning.
2977 For many systems, this routine calls __do_global_ctors.
2978 For systems which support a .init section we use the .init section
2979 to run __do_global_ctors, so we need not do anything here. */
2981 void
2982 SYMBOL__MAIN ()
2984 /* Support recursive calls to `main': run initializers just once. */
2985 static int initialized;
2986 if (! initialized)
2988 initialized = 1;
2989 __do_global_ctors ();
2992 #endif /* no HAS_INIT_SECTION or INVOKE__main */
2994 #endif /* L__main */
2996 #ifdef L_ctors
2998 #include "gbl-ctors.h"
3000 /* Provide default definitions for the lists of constructors and
3001 destructors, so that we don't get linker errors. These symbols are
3002 intentionally bss symbols, so that gld and/or collect will provide
3003 the right values. */
3005 /* We declare the lists here with two elements each,
3006 so that they are valid empty lists if no other definition is loaded. */
3007 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
3008 #if defined(__NeXT__) || defined(_AIX)
3009 /* After 2.3, try this definition on all systems. */
3010 func_ptr __CTOR_LIST__[2] = {0, 0};
3011 func_ptr __DTOR_LIST__[2] = {0, 0};
3012 #else
3013 func_ptr __CTOR_LIST__[2];
3014 func_ptr __DTOR_LIST__[2];
3015 #endif
3016 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
3017 #endif /* L_ctors */
3019 #ifdef L_exit
3021 #include "gbl-ctors.h"
3023 #ifdef NEED_ATEXIT
3024 # ifdef ON_EXIT
3025 # undef ON_EXIT
3026 # endif
3027 int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */
3028 #endif
3030 #ifndef ON_EXIT
3032 #ifdef NEED_ATEXIT
3033 # include <errno.h>
3035 static func_ptr *atexit_chain = 0;
3036 static long atexit_chain_length = 0;
3037 static volatile long last_atexit_chain_slot = -1;
3039 int atexit (func_ptr func)
3041 if (++last_atexit_chain_slot == atexit_chain_length)
3043 atexit_chain_length += 32;
3044 if (atexit_chain)
3045 atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
3046 * sizeof (func_ptr));
3047 else
3048 atexit_chain = (func_ptr *) malloc (atexit_chain_length
3049 * sizeof (func_ptr));
3050 if (! atexit_chain)
3052 atexit_chain_length = 0;
3053 last_atexit_chain_slot = -1;
3054 errno = ENOMEM;
3055 return (-1);
3058 atexit_chain[last_atexit_chain_slot] = func;
3059 return (0);
3061 #endif /* NEED_ATEXIT */
3063 /* If we have no known way of registering our own __do_global_dtors
3064 routine so that it will be invoked at program exit time, then we
3065 have to define our own exit routine which will get this to happen. */
3067 extern void __do_global_dtors ();
3068 extern void __bb_exit_func ();
3069 extern void _cleanup ();
3070 extern void _exit () __attribute__ ((noreturn));
3072 void
3073 exit (int status)
3075 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
3076 #ifdef NEED_ATEXIT
3077 if (atexit_chain)
3079 for ( ; last_atexit_chain_slot-- >= 0; )
3081 (*atexit_chain[last_atexit_chain_slot + 1]) ();
3082 atexit_chain[last_atexit_chain_slot + 1] = 0;
3084 free (atexit_chain);
3085 atexit_chain = 0;
3087 #else /* No NEED_ATEXIT */
3088 __do_global_dtors ();
3089 #endif /* No NEED_ATEXIT */
3090 #endif
3091 #ifndef inhibit_libc
3092 __bb_exit_func ();
3093 #endif
3094 #ifdef EXIT_BODY
3095 EXIT_BODY;
3096 #else
3097 _cleanup ();
3098 #endif
3099 _exit (status);
3102 #else
3103 int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */
3104 #endif
3106 #endif /* L_exit */
3108 #ifdef L_eh
3110 /* Shared exception handling support routines. */
3112 /* Language-specific information about the active exception(s). If there
3113 are no active exceptions, it is set to 0. */
3114 void *__eh_info;
3116 void
3117 __default_terminate ()
3119 abort ();
3122 void (*__terminate_func)() = __default_terminate;
3124 void
3125 __terminate ()
3127 (*__terminate_func)();
3130 void *
3131 __throw_type_match (void *catch_type, void *throw_type, void *obj)
3133 #if 0
3134 printf ("__throw_type_match (): catch_type = %s, throw_type = %s\n",
3135 catch_type, throw_type);
3136 #endif
3137 if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)
3138 return obj;
3139 return 0;
3142 void
3143 __empty ()
3147 /* Support routines for setjmp/longjmp exception handling. */
3149 /* Calls to __sjthrow are generated by the compiler when an exception
3150 is raised when using the setjmp/longjmp exception handling codegen
3151 method. */
3153 extern void longjmp (void *, int);
3155 static void *top_elt[2];
3156 void **__dynamic_handler_chain = top_elt;
3158 /* Routine to get the head of the current thread's dynamic handler chain
3159 use for exception handling.
3161 TODO: make thread safe. */
3163 void ***
3164 __get_dynamic_handler_chain ()
3166 return &__dynamic_handler_chain;
3169 /* This is used to throw an exception when the setjmp/longjmp codegen
3170 method is used for exception handling.
3172 We call __terminate if there are no handlers left (we know this
3173 when the dynamic handler chain is top_elt). Otherwise we run the
3174 cleanup actions off the dynamic cleanup stack, and pop the top of
3175 the dynamic handler chain, and use longjmp to transfer back to the
3176 associated handler. */
3178 void
3179 __sjthrow ()
3181 void ***dhc = __get_dynamic_handler_chain ();
3182 void *jmpbuf;
3183 void (*func)(void *, int);
3184 void *arg;
3185 void ***cleanup;
3187 /* The cleanup chain is one word into the buffer. Get the cleanup
3188 chain. */
3189 cleanup = (void***)&(*dhc)[1];
3191 /* If there are any cleanups in the chain, run them now. */
3192 if (cleanup[0])
3194 double store[200];
3195 void **buf = (void**)store;
3196 buf[1] = 0;
3197 buf[0] = (*dhc);
3199 /* try { */
3200 #ifdef DONT_USE_BUILTIN_SETJMP
3201 if (! setjmp (&buf[2]))
3202 #else
3203 if (! __builtin_setjmp (&buf[2]))
3204 #endif
3206 *dhc = buf;
3207 while (cleanup[0])
3209 func = (void(*)(void*, int))cleanup[0][1];
3210 arg = (void*)cleanup[0][2];
3212 /* Update this before running the cleanup. */
3213 cleanup[0] = (void **)cleanup[0][0];
3215 (*func)(arg, 2);
3217 *dhc = buf[0];
3219 /* catch (...) */
3220 else
3222 __terminate ();
3226 /* We must call terminate if we try and rethrow an exception, when
3227 there is no exception currently active and when there are no
3228 handlers left. */
3229 if (! __eh_info || (*dhc) == top_elt)
3230 __terminate ();
3232 /* Find the jmpbuf associated with the top element of the dynamic
3233 handler chain. The jumpbuf starts two words into the buffer. */
3234 jmpbuf = &(*dhc)[2];
3236 /* Then we pop the top element off the dynamic handler chain. */
3237 *dhc = (void**)(*dhc)[0];
3239 /* And then we jump to the handler. */
3241 #ifdef DONT_USE_BUILTIN_SETJMP
3242 longjmp (jmpbuf, 1);
3243 #else
3244 __builtin_longjmp (jmpbuf, 1);
3245 #endif
3248 /* Run cleanups on the dynamic cleanup stack for the current dynamic
3249 handler, then pop the handler off the dynamic handler stack, and
3250 then throw. This is used to skip the first handler, and transfer
3251 control to the next handler in the dynamic handler stack. */
3253 void
3254 __sjpopnthrow ()
3256 void ***dhc = __get_dynamic_handler_chain ();
3257 void *jmpbuf;
3258 void (*func)(void *, int);
3259 void *arg;
3260 void ***cleanup;
3262 /* The cleanup chain is one word into the buffer. Get the cleanup
3263 chain. */
3264 cleanup = (void***)&(*dhc)[1];
3266 /* If there are any cleanups in the chain, run them now. */
3267 if (cleanup[0])
3269 double store[200];
3270 void **buf = (void**)store;
3271 buf[1] = 0;
3272 buf[0] = (*dhc);
3274 /* try { */
3275 #ifdef DONT_USE_BUILTIN_SETJMP
3276 if (! setjmp (&buf[2]))
3277 #else
3278 if (! __builtin_setjmp (&buf[2]))
3279 #endif
3281 *dhc = buf;
3282 while (cleanup[0])
3284 func = (void(*)(void*, int))cleanup[0][1];
3285 arg = (void*)cleanup[0][2];
3287 /* Update this before running the cleanup. */
3288 cleanup[0] = (void **)cleanup[0][0];
3290 (*func)(arg, 2);
3292 *dhc = buf[0];
3294 /* catch (...) */
3295 else
3297 __terminate ();
3301 /* Then we pop the top element off the dynamic handler chain. */
3302 *dhc = (void**)(*dhc)[0];
3304 __sjthrow ();
3307 /* Support code for all exception region-based exception handling. */
3309 /* This value identifies the place from which an exception is being
3310 thrown. */
3312 void *__eh_pc;
3314 #ifdef EH_TABLE_LOOKUP
3316 EH_TABLE_LOOKUP
3318 #else
3320 typedef struct exception_table {
3321 void *start;
3322 void *end;
3323 void *exception_handler;
3324 } exception_table;
3326 /* This routine takes a PC and a pointer to the exception region TABLE for
3327 its translation unit, and returns the address of the exception handler
3328 associated with the closest exception table handler entry associated
3329 with that PC, or 0 if there are no table entries the PC fits in.
3331 In the advent of a tie, we have to give the last entry, as it represents
3332 an inner block. */
3334 static void *
3335 find_exception_handler (void *pc, exception_table *table)
3337 if (table)
3339 int pos;
3340 int best = -1;
3342 /* We can't do a binary search because the table isn't guaranteed
3343 to be sorted from function to function. */
3344 for (pos = 0; table[pos].exception_handler != (void *) -1; ++pos)
3346 if (table[pos].start <= pc && table[pos].end > pc)
3348 /* This can apply. Make sure it is at least as small as
3349 the previous best. */
3350 if (best == -1 || (table[pos].end <= table[best].end
3351 && table[pos].start >= table[best].start))
3352 best = pos;
3354 /* But it is sorted by starting PC within a function. */
3355 else if (best >= 0 && table[pos].start > pc)
3356 break;
3358 if (best != -1)
3359 return table[best].exception_handler;
3362 return (void *) 0;
3364 #endif /* EH_TABLE_LOOKUP */
3366 #ifndef DWARF2_UNWIND_INFO
3367 /* Support code for exception handling using inline unwinders or
3368 __unwind_function. */
3370 #ifndef EH_TABLE_LOOKUP
3371 typedef struct exception_table_node {
3372 exception_table *table;
3373 void *start;
3374 void *end;
3375 struct exception_table_node *next;
3376 } exception_table_node;
3378 static struct exception_table_node *exception_table_list;
3380 void *
3381 __find_first_exception_table_match (void *pc)
3383 register exception_table_node *tnp;
3385 for (tnp = exception_table_list; tnp != 0; tnp = tnp->next)
3387 if (tnp->start <= pc && tnp->end >= pc)
3388 return find_exception_handler (pc, tnp->table);
3391 return (void *) 0;
3394 void
3395 __register_exceptions (exception_table *table)
3397 exception_table_node *node;
3398 exception_table *range = table + 1;
3400 if (range->start == (void *) -1)
3401 return;
3403 node = (exception_table_node *) malloc (sizeof (exception_table_node));
3404 node->table = table;
3406 /* This look can be optimized away either if the table
3407 is sorted, or if we pass in extra parameters. */
3408 node->start = range->start;
3409 node->end = range->end;
3410 for (range++ ; range->start != (void *) (-1); range++)
3412 if (range->start < node->start)
3413 node->start = range->start;
3414 if (range->end > node->end)
3415 node->end = range->end;
3418 node->next = exception_table_list;
3419 exception_table_list = node;
3421 #endif /* !EH_TABLE_LOOKUP */
3423 /* Throw stub routine.
3425 This is work in progress, but not completed yet. */
3427 void
3428 __throw ()
3430 abort ();
3433 /* See expand_builtin_throw for details. */
3435 void **__eh_pcnthrow () {
3436 static void *buf[2] = {
3437 &__eh_pc,
3438 &__throw
3440 return buf;
3443 #if #machine(i386)
3444 void
3445 __unwind_function(void *ptr)
3447 asm("movl 8(%esp),%ecx");
3448 /* Undo current frame */
3449 asm("movl %ebp,%esp");
3450 asm("popl %ebp");
3451 /* like ret, but stay here */
3452 asm("addl $4,%esp");
3454 /* Now, undo previous frame. */
3455 /* This is a test routine, as we have to dynamically probe to find out
3456 what to pop for certain, this is just a guess. */
3457 asm("leal -16(%ebp),%esp");
3458 asm("pop %ebx");
3459 asm("pop %esi");
3460 asm("pop %edi");
3461 asm("movl %ebp,%esp");
3462 asm("popl %ebp");
3464 asm("movl %ecx,0(%esp)");
3465 asm("ret");
3467 #elif #machine(rs6000) && !defined _ARCH_PPC
3468 __unwind_function(void *ptr)
3470 asm("mr 31,1");
3471 asm("l 1,0(1)");
3472 asm("l 31,-4(1)");
3473 asm("# br");
3475 asm("mr 31,1");
3476 asm("l 1,0(1)");
3477 /* use 31 as a scratch register to restore the link register. */
3478 asm("l 31, 8(1);mtlr 31 # l lr,8(1)");
3479 asm("l 31,-4(1)");
3480 asm("# br");
3481 asm("mtctr 3;bctr # b 3");
3483 #elif (#machine(rs6000) || #machine(powerpc)) && defined _ARCH_PPC
3484 __unwind_function(void *ptr)
3486 asm("mr 31,1");
3487 asm("lwz 1,0(1)");
3488 asm("lwz 31,-4(1)");
3489 asm("# br");
3491 asm("mr 31,1");
3492 asm("lwz 1,0(1)");
3493 /* use 31 as a scratch register to restore the link register. */
3494 asm("lwz 31, 8(1);mtlr 31 # l lr,8(1)");
3495 asm("lwz 31,-4(1)");
3496 asm("# br");
3497 asm("mtctr 3;bctr # b 3");
3499 #elif #machine(vax)
3500 __unwind_function(void *ptr)
3502 __label__ return_again;
3504 /* Replace our frame's return address with the label below.
3505 During execution, we will first return here instead of to
3506 caller, then second return takes caller's frame off the stack.
3507 Two returns matches two actual calls, so is less likely to
3508 confuse debuggers. `16' corresponds to RETURN_ADDRESS_OFFSET. */
3509 __asm ("movl %0,16(fp)" : : "p" (&& return_again));
3510 return;
3512 return_again:
3513 return;
3515 #else
3516 __unwind_function(void *ptr)
3518 abort ();
3520 #endif /* powerpc */
3522 #else /* DWARF2_UNWIND_INFO */
3523 /* Support code for exception handling using static unwind information. */
3525 #include "frame.h"
3527 /* This type is used in get_reg and put_reg to deal with ABIs where a void*
3528 is smaller than a word, such as the Irix 6 n32 ABI. We cast twice to
3529 avoid a warning about casting between int and pointer of different
3530 sizes. */
3532 typedef int ptr_type __attribute__ ((mode (pointer)));
3534 /* Get the value of register REG as saved in UDATA, where SUB_UDATA is a
3535 frame called by UDATA or 0. */
3537 static void*
3538 get_reg (unsigned reg, frame_state *udata, frame_state *sub_udata)
3540 if (udata->saved[reg] == REG_SAVED_OFFSET)
3541 return (void *)(ptr_type)
3542 *(word_type *)(udata->cfa + udata->reg_or_offset[reg]);
3543 else if (udata->saved[reg] == REG_SAVED_REG && sub_udata)
3544 return get_reg (udata->reg_or_offset[reg], sub_udata, 0);
3545 else
3546 abort ();
3549 /* Overwrite the saved value for register REG in frame UDATA with VAL. */
3551 static void
3552 put_reg (unsigned reg, void *val, frame_state *udata)
3554 if (udata->saved[reg] == REG_SAVED_OFFSET)
3555 *(word_type *)(udata->cfa + udata->reg_or_offset[reg])
3556 = (word_type)(ptr_type) val;
3557 else
3558 abort ();
3561 /* Copy the saved value for register REG from frame UDATA to frame
3562 TARGET_UDATA. Unlike the previous two functions, this can handle
3563 registers that are not one word large. */
3565 static void
3566 copy_reg (unsigned reg, frame_state *udata, frame_state *target_udata)
3568 if (udata->saved[reg] == REG_SAVED_OFFSET
3569 && target_udata->saved[reg] == REG_SAVED_OFFSET)
3570 memcpy (target_udata->cfa + target_udata->reg_or_offset[reg],
3571 udata->cfa + udata->reg_or_offset[reg],
3572 __builtin_dwarf_reg_size (reg));
3573 else
3574 abort ();
3577 /* Retrieve the return address for frame UDATA, where SUB_UDATA is a
3578 frame called by UDATA or 0. */
3580 static inline void *
3581 get_return_addr (frame_state *udata, frame_state *sub_udata)
3583 return __builtin_extract_return_addr
3584 (get_reg (udata->retaddr_column, udata, sub_udata));
3587 /* Overwrite the return address for frame UDATA with VAL. */
3589 static inline void
3590 put_return_addr (void *val, frame_state *udata)
3592 val = __builtin_frob_return_addr (val);
3593 put_reg (udata->retaddr_column, val, udata);
3596 /* Given the current frame UDATA and its return address PC, return the
3597 information about the calling frame in CALLER_UDATA. */
3599 static void *
3600 next_stack_level (void *pc, frame_state *udata, frame_state *caller_udata)
3602 caller_udata = __frame_state_for (pc, caller_udata);
3603 if (! caller_udata)
3604 return 0;
3606 /* Now go back to our caller's stack frame. If our caller's CFA register
3607 was saved in our stack frame, restore it; otherwise, assume the CFA
3608 register is SP and restore it to our CFA value. */
3609 if (udata->saved[caller_udata->cfa_reg])
3610 caller_udata->cfa = get_reg (caller_udata->cfa_reg, udata, 0);
3611 else
3612 caller_udata->cfa = udata->cfa;
3613 caller_udata->cfa += caller_udata->cfa_offset;
3615 return caller_udata;
3618 #ifdef INCOMING_REGNO
3619 /* Is the saved value for register REG in frame UDATA stored in a register
3620 window in the previous frame? */
3622 static int
3623 in_reg_window (int reg, frame_state *udata)
3625 if (udata->saved[reg] != REG_SAVED_OFFSET)
3626 return 0;
3628 #ifdef STACK_GROWS_DOWNWARD
3629 return udata->reg_or_offset[reg] > 0;
3630 #else
3631 return udata->reg_or_offset[reg] < 0;
3632 #endif
3634 #endif /* INCOMING_REGNO */
3636 /* We first search for an exception handler, and if we don't find
3637 it, we call __terminate on the current stack frame so that we may
3638 use the debugger to walk the stack and understand why no handler
3639 was found.
3641 If we find one, then we unwind the frames down to the one that
3642 has the handler and transfer control into the handler. */
3644 void
3645 __throw ()
3647 void *pc, *handler, *retaddr;
3648 frame_state ustruct, ustruct2;
3649 frame_state *udata = &ustruct;
3650 frame_state *sub_udata = &ustruct2;
3651 frame_state my_ustruct, *my_udata = &my_ustruct;
3652 long args_size;
3654 /* This is required for C++ semantics. We must call terminate if we
3655 try and rethrow an exception, when there is no exception currently
3656 active. */
3657 if (! __eh_info)
3658 __terminate ();
3660 /* Start at our stack frame. */
3661 label:
3662 udata = __frame_state_for (&&label, udata);
3663 if (! udata)
3664 __terminate ();
3666 /* We need to get the value from the CFA register. At this point in
3667 compiling __throw we don't know whether or not we will use the frame
3668 pointer register for the CFA, so we check our unwind info. */
3669 if (udata->cfa_reg == __builtin_dwarf_fp_regnum ())
3670 udata->cfa = __builtin_fp ();
3671 else
3672 udata->cfa = __builtin_sp ();
3673 udata->cfa += udata->cfa_offset;
3675 memcpy (my_udata, udata, sizeof (*udata));
3677 /* Do any necessary initialization to access arbitrary stack frames.
3678 On the SPARC, this means flushing the register windows. */
3679 __builtin_unwind_init ();
3681 /* Now reset pc to the right throw point. */
3682 pc = __eh_pc;
3684 handler = 0;
3685 for (;;)
3687 frame_state *p = udata;
3688 udata = next_stack_level (pc, udata, sub_udata);
3689 sub_udata = p;
3691 /* If we couldn't find the next frame, we lose. */
3692 if (! udata)
3693 break;
3695 handler = find_exception_handler (pc, udata->eh_ptr);
3697 /* If we found one, we can stop searching. */
3698 if (handler)
3700 args_size = udata->args_size;
3701 break;
3704 /* Otherwise, we continue searching. We subtract 1 from PC to avoid
3705 hitting the beginning of the next region. */
3706 pc = get_return_addr (udata, sub_udata) - 1;
3709 /* If we haven't found a handler by now, this is an unhandled
3710 exception. */
3711 if (! handler)
3712 __terminate ();
3714 if (pc == __eh_pc)
3715 /* We found a handler in the throw context, no need to unwind. */
3716 udata = my_udata;
3717 else
3719 int i;
3720 void *val;
3722 /* Unwind all the frames between this one and the handler by copying
3723 their saved register values into our register save slots. */
3725 /* Remember the PC where we found the handler. */
3726 void *handler_pc = pc;
3728 /* Start from the throw context again. */
3729 pc = __eh_pc;
3730 memcpy (udata, my_udata, sizeof (*udata));
3732 while (pc != handler_pc)
3734 frame_state *p = udata;
3735 udata = next_stack_level (pc, udata, sub_udata);
3736 sub_udata = p;
3738 for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
3739 if (i != udata->retaddr_column && udata->saved[i])
3741 #ifdef INCOMING_REGNO
3742 /* If you modify the saved value of the return address
3743 register on the SPARC, you modify the return address for
3744 your caller's frame. Don't do that here, as it will
3745 confuse get_return_addr. */
3746 if (in_reg_window (i, udata)
3747 && udata->saved[udata->retaddr_column] == REG_SAVED_REG
3748 && udata->reg_or_offset[udata->retaddr_column] == i)
3749 continue;
3750 #endif
3751 copy_reg (i, udata, my_udata);
3754 pc = get_return_addr (udata, sub_udata) - 1;
3757 #ifdef INCOMING_REGNO
3758 /* But we do need to update the saved return address register from
3759 the last frame we unwind, or the handler frame will have the wrong
3760 return address. */
3761 if (udata->saved[udata->retaddr_column] == REG_SAVED_REG)
3763 i = udata->reg_or_offset[udata->retaddr_column];
3764 if (in_reg_window (i, udata))
3765 copy_reg (i, udata, my_udata);
3767 #endif
3769 /* udata now refers to the frame called by the handler frame. */
3771 /* Emit the stub to adjust sp and jump to the handler. */
3772 retaddr = __builtin_eh_stub ();
3774 /* And then set our return address to point to the stub. */
3775 if (my_udata->saved[my_udata->retaddr_column] == REG_SAVED_OFFSET)
3776 put_return_addr (retaddr, my_udata);
3777 else
3778 __builtin_set_return_addr_reg (retaddr);
3780 /* Set up the registers we use to communicate with the stub.
3781 We check STACK_GROWS_DOWNWARD so the stub can use adjust_stack. */
3782 __builtin_set_eh_regs (handler,
3783 #ifdef STACK_GROWS_DOWNWARD
3784 udata->cfa - my_udata->cfa
3785 #else
3786 my_udata->cfa - udata->cfa
3787 #endif
3788 + args_size
3791 /* Epilogue: restore the handler frame's register values and return
3792 to the stub. */
3794 #endif /* !DWARF2_UNWIND_INFO */
3796 #endif /* L_eh */
3798 #ifdef L_pure
3799 #ifndef inhibit_libc
3800 /* This gets us __GNU_LIBRARY__. */
3801 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
3802 #include <stdio.h>
3804 #ifdef __GNU_LIBRARY__
3805 /* Avoid forcing the library's meaning of `write' on the user program
3806 by using the "internal" name (for use within the library) */
3807 #define write(fd, buf, n) __write((fd), (buf), (n))
3808 #endif
3809 #endif /* inhibit_libc */
3811 #define MESSAGE "pure virtual method called\n"
3813 void
3814 __pure_virtual ()
3816 #ifndef inhibit_libc
3817 write (2, MESSAGE, sizeof (MESSAGE) - 1);
3818 #endif
3819 _exit (-1);
3821 #endif