* rtl.h (rtunion_def): Constify member `rtstr'.
[official-gcc.git] / gcc / libgcc2.c
blob368b5c6dd5b4e2501cffbd3b76eb44596d4694c0
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, 97, 98, 1999, 2000
4 Free Software Foundation, Inc.
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* As a special exception, if you link this library with other files,
24 some of which are compiled with GCC, to produce an executable,
25 this library does not by itself cause the resulting executable
26 to be covered by the GNU General Public License.
27 This exception does not however invalidate any other reasons why
28 the executable file might be covered by the GNU General Public License. */
30 /* It is incorrect to include config.h here, because this file is being
31 compiled for the target, and hence definitions concerning only the host
32 do not apply. */
34 #include "tconfig.h"
35 #include "tsystem.h"
37 #include "machmode.h"
38 #include "defaults.h"
40 /* Don't use `fancy_abort' here even if config.h says to use it. */
41 #ifdef abort
42 #undef abort
43 #endif
45 /* In a cross-compilation situation, default to inhibiting compilation
46 of routines that use libc. */
48 #if defined(CROSS_COMPILE) && !defined(inhibit_libc)
49 #define inhibit_libc
50 #endif
52 /* Permit the tm.h file to select the endianness to use just for this
53 file. This is used when the endianness is determined when the
54 compiler is run. */
56 #ifndef LIBGCC2_WORDS_BIG_ENDIAN
57 #define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
58 #endif
60 #ifndef LIBGCC2_LONG_DOUBLE_TYPE_SIZE
61 #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE LONG_DOUBLE_TYPE_SIZE
62 #endif
64 /* In the first part of this file, we are interfacing to calls generated
65 by the compiler itself. These calls pass values into these routines
66 which have very specific modes (rather than very specific types), and
67 these compiler-generated calls also expect any return values to have
68 very specific modes (rather than very specific types). Thus, we need
69 to avoid using regular C language type names in this part of the file
70 because the sizes for those types can be configured to be anything.
71 Instead we use the following special type names. */
73 typedef int QItype __attribute__ ((mode (QI)));
74 typedef unsigned int UQItype __attribute__ ((mode (QI)));
75 typedef int HItype __attribute__ ((mode (HI)));
76 typedef unsigned int UHItype __attribute__ ((mode (HI)));
77 #if UNITS_PER_WORD > 1
78 /* These typedefs are usually forbidden on dsp's with UNITS_PER_WORD 1 */
79 typedef int SItype __attribute__ ((mode (SI)));
80 typedef unsigned int USItype __attribute__ ((mode (SI)));
81 #if UNITS_PER_WORD > 2
82 /* These typedefs are usually forbidden on archs with UNITS_PER_WORD 2 */
83 typedef int DItype __attribute__ ((mode (DI)));
84 typedef unsigned int UDItype __attribute__ ((mode (DI)));
85 #endif
86 #endif
88 #if BITS_PER_UNIT == 8
90 typedef float SFtype __attribute__ ((mode (SF)));
91 typedef float DFtype __attribute__ ((mode (DF)));
93 #if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
94 typedef float XFtype __attribute__ ((mode (XF)));
95 #endif
96 #if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128
97 typedef float TFtype __attribute__ ((mode (TF)));
98 #endif
100 #else /* BITS_PER_UNIT != 8 */
102 /* On dsp's there are usually qf/hf/tqf modes used instead of the above.
103 For now we don't support them in libgcc2.c. */
105 #undef L_fixdfdi
106 #undef L_fixsfdi
107 #undef L_fixtfdi
108 #undef L_fixunsdfdi
109 #undef L_fixunsdfsi
110 #undef L_fixunssfdi
111 #undef L_fixunssfsi
112 #undef L_fixunstfdi
113 #undef L_fixunsxfdi
114 #undef L_fixunsxfsi
115 #undef L_fixxfdi
116 #undef L_floatdidf
117 #undef L_floatdisf
118 #undef L_floatditf
119 #undef L_floatdixf
121 #endif /* BITS_PER_UNIT != 8 */
123 typedef int word_type __attribute__ ((mode (__word__)));
125 /* Make sure that we don't accidentally use any normal C language built-in
126 type names in the first part of this file. Instead we want to use *only*
127 the type names defined above. The following macro definitions insure
128 that if we *do* accidentally use some normal C language built-in type name,
129 we will get a syntax error. */
131 #define char bogus_type
132 #define short bogus_type
133 #define int bogus_type
134 #define long bogus_type
135 #define unsigned bogus_type
136 #define float bogus_type
137 #define double bogus_type
139 #if UNITS_PER_WORD > 2
140 #define W_TYPE_SIZE (4 * BITS_PER_UNIT)
141 #define Wtype SItype
142 #define UWtype USItype
143 #define HWtype SItype
144 #define UHWtype USItype
145 #define DWtype DItype
146 #define UDWtype UDItype
147 #define __NW(a,b) __ ## a ## si ## b
148 #define __NDW(a,b) __ ## a ## di ## b
149 #elif UNITS_PER_WORD > 1
150 #define W_TYPE_SIZE (2 * BITS_PER_UNIT)
151 #define Wtype HItype
152 #define UWtype UHItype
153 #define HWtype HItype
154 #define UHWtype UHItype
155 #define DWtype SItype
156 #define UDWtype USItype
157 #define __NW(a,b) __ ## a ## hi ## b
158 #define __NDW(a,b) __ ## a ## si ## b
159 #else
160 #define W_TYPE_SIZE BITS_PER_UNIT
161 #define Wtype QItype
162 #define UWtype UQItype
163 #define HWtype QItype
164 #define UHWtype UQItype
165 #define DWtype HItype
166 #define UDWtype UHItype
167 #define __NW(a,b) __ ## a ## qi ## b
168 #define __NDW(a,b) __ ## a ## hi ## b
169 #endif
171 #define __muldi3 __NDW(mul,3)
172 #define __divdi3 __NDW(div,3)
173 #define __udivdi3 __NDW(udiv,3)
174 #define __moddi3 __NDW(mod,3)
175 #define __umoddi3 __NDW(umod,3)
176 #define __negdi2 __NDW(neg,2)
177 #define __lshrdi3 __NDW(lshr,3)
178 #define __ashldi3 __NDW(ashl,3)
179 #define __ashrdi3 __NDW(ashr,3)
180 #define __ffsdi2 __NDW(ffs,2)
181 #define __cmpdi2 __NDW(cmp,2)
182 #define __ucmpdi2 __NDW(ucmp,2)
183 #define __udivmoddi4 __NDW(udivmod,4)
184 #define __fixunstfdi __NDW(fixunstf,)
185 #define __fixtfdi __NDW(fixtf,)
186 #define __fixunsxfdi __NDW(fixunsxf,)
187 #define __fixxfdi __NDW(fixxf,)
188 #define __fixunsdfdi __NDW(fixunsdf,)
189 #define __fixdfdi __NDW(fixdf,)
190 #define __fixunssfdi __NDW(fixunssf,)
191 #define __fixsfdi __NDW(fixsf,)
192 #define __floatdixf __NDW(float,xf)
193 #define __floatditf __NDW(float,tf)
194 #define __floatdidf __NDW(float,df)
195 #define __floatdisf __NDW(float,sf)
196 #define __fixunsxfsi __NW(fixunsxf,)
197 #define __fixunstfsi __NW(fixunstf,)
198 #define __fixunsdfsi __NW(fixunsdf,)
199 #define __fixunssfsi __NW(fixunssf,)
201 /* DWstructs are pairs of Wtype values in the order determined by
202 LIBGCC2_WORDS_BIG_ENDIAN. */
204 #if LIBGCC2_WORDS_BIG_ENDIAN
205 struct DWstruct {Wtype high, low;};
206 #else
207 struct DWstruct {Wtype low, high;};
208 #endif
210 /* We need this union to unpack/pack DImode values, since we don't have
211 any arithmetic yet. Incoming DImode parameters are stored into the
212 `ll' field, and the unpacked result is read from the struct `s'. */
214 typedef union
216 struct DWstruct s;
217 DWtype ll;
218 } DWunion;
220 #if (defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_w_sdiv)\
221 || defined (L_divdi3) || defined (L_udivdi3) \
222 || defined (L_moddi3) || defined (L_umoddi3))
224 #include "longlong.h"
226 #endif /* udiv or mul */
229 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
230 #if defined (L_divdi3) || defined (L_moddi3)
231 static inline
232 #endif
233 DWtype
234 __negdi2 (DWtype u)
236 DWunion w;
237 DWunion uu;
239 uu.ll = u;
241 w.s.low = -uu.s.low;
242 w.s.high = -uu.s.high - ((UWtype) w.s.low > 0);
244 return w.ll;
246 #endif
248 /* Unless shift functions are defined whith full ANSI prototypes,
249 parameter b will be promoted to int if word_type is smaller than an int. */
250 #ifdef L_lshrdi3
251 DWtype
252 __lshrdi3 (DWtype u, word_type b)
254 DWunion w;
255 word_type bm;
256 DWunion uu;
258 if (b == 0)
259 return u;
261 uu.ll = u;
263 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
264 if (bm <= 0)
266 w.s.high = 0;
267 w.s.low = (UWtype)uu.s.high >> -bm;
269 else
271 UWtype carries = (UWtype)uu.s.high << bm;
272 w.s.high = (UWtype)uu.s.high >> b;
273 w.s.low = ((UWtype)uu.s.low >> b) | carries;
276 return w.ll;
278 #endif
280 #ifdef L_ashldi3
281 DWtype
282 __ashldi3 (DWtype u, word_type b)
284 DWunion w;
285 word_type bm;
286 DWunion uu;
288 if (b == 0)
289 return u;
291 uu.ll = u;
293 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
294 if (bm <= 0)
296 w.s.low = 0;
297 w.s.high = (UWtype)uu.s.low << -bm;
299 else
301 UWtype carries = (UWtype)uu.s.low >> bm;
302 w.s.low = (UWtype)uu.s.low << b;
303 w.s.high = ((UWtype)uu.s.high << b) | carries;
306 return w.ll;
308 #endif
310 #ifdef L_ashrdi3
311 DWtype
312 __ashrdi3 (DWtype u, word_type b)
314 DWunion w;
315 word_type bm;
316 DWunion uu;
318 if (b == 0)
319 return u;
321 uu.ll = u;
323 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
324 if (bm <= 0)
326 /* w.s.high = 1..1 or 0..0 */
327 w.s.high = uu.s.high >> (sizeof (Wtype) * BITS_PER_UNIT - 1);
328 w.s.low = uu.s.high >> -bm;
330 else
332 UWtype carries = (UWtype)uu.s.high << bm;
333 w.s.high = uu.s.high >> b;
334 w.s.low = ((UWtype)uu.s.low >> b) | carries;
337 return w.ll;
339 #endif
341 #ifdef L_ffsdi2
342 DWtype
343 __ffsdi2 (DWtype u)
345 DWunion uu, w;
346 uu.ll = u;
347 w.s.high = 0;
348 w.s.low = ffs (uu.s.low);
349 if (w.s.low != 0)
350 return w.ll;
351 w.s.low = ffs (uu.s.high);
352 if (w.s.low != 0)
354 w.s.low += BITS_PER_UNIT * sizeof (Wtype);
355 return w.ll;
357 return w.ll;
359 #endif
361 #ifdef L_muldi3
362 DWtype
363 __muldi3 (DWtype u, DWtype v)
365 DWunion w;
366 DWunion uu, vv;
368 uu.ll = u,
369 vv.ll = v;
371 w.ll = __umulsidi3 (uu.s.low, vv.s.low);
372 w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
373 + (UWtype) uu.s.high * (UWtype) vv.s.low);
375 return w.ll;
377 #endif
379 #ifdef L_udiv_w_sdiv
380 #if defined (sdiv_qrnnd)
381 UWtype
382 __udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d)
384 UWtype q, r;
385 UWtype c0, c1, b1;
387 if ((Wtype) d >= 0)
389 if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1)))
391 /* dividend, divisor, and quotient are nonnegative */
392 sdiv_qrnnd (q, r, a1, a0, d);
394 else
396 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
397 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1));
398 /* Divide (c1*2^32 + c0) by d */
399 sdiv_qrnnd (q, r, c1, c0, d);
400 /* Add 2^31 to quotient */
401 q += (UWtype) 1 << (W_TYPE_SIZE - 1);
404 else
406 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
407 c1 = a1 >> 1; /* A/2 */
408 c0 = (a1 << (W_TYPE_SIZE - 1)) + (a0 >> 1);
410 if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
412 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
414 r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
415 if ((d & 1) != 0)
417 if (r >= q)
418 r = r - q;
419 else if (q - r <= d)
421 r = r - q + d;
422 q--;
424 else
426 r = r - q + 2*d;
427 q -= 2;
431 else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
433 c1 = (b1 - 1) - c1;
434 c0 = ~c0; /* logical NOT */
436 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
438 q = ~q; /* (A/2)/b1 */
439 r = (b1 - 1) - r;
441 r = 2*r + (a0 & 1); /* A/(2*b1) */
443 if ((d & 1) != 0)
445 if (r >= q)
446 r = r - q;
447 else if (q - r <= d)
449 r = r - q + d;
450 q--;
452 else
454 r = r - q + 2*d;
455 q -= 2;
459 else /* Implies c1 = b1 */
460 { /* Hence a1 = d - 1 = 2*b1 - 1 */
461 if (a0 >= -d)
463 q = -1;
464 r = a0 + d;
466 else
468 q = -2;
469 r = a0 + 2*d;
474 *rp = r;
475 return q;
477 #else
478 /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */
479 UWtype
480 __udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)),
481 UWtype a1 __attribute__ ((__unused__)),
482 UWtype a0 __attribute__ ((__unused__)),
483 UWtype d __attribute__ ((__unused__)))
485 return 0;
487 #endif
488 #endif
490 #if (defined (L_udivdi3) || defined (L_divdi3) || \
491 defined (L_umoddi3) || defined (L_moddi3))
492 #define L_udivmoddi4
493 #endif
495 #ifdef L_udivmoddi4
496 static const UQItype __clz_tab[] =
498 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,
499 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,
500 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,
501 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,
502 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,
503 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,
504 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,
505 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,
508 #if (defined (L_udivdi3) || defined (L_divdi3) || \
509 defined (L_umoddi3) || defined (L_moddi3))
510 static inline
511 #endif
512 UDWtype
513 __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
515 DWunion ww;
516 DWunion nn, dd;
517 DWunion rr;
518 UWtype d0, d1, n0, n1, n2;
519 UWtype q0, q1;
520 UWtype b, bm;
522 nn.ll = n;
523 dd.ll = d;
525 d0 = dd.s.low;
526 d1 = dd.s.high;
527 n0 = nn.s.low;
528 n1 = nn.s.high;
530 #if !UDIV_NEEDS_NORMALIZATION
531 if (d1 == 0)
533 if (d0 > n1)
535 /* 0q = nn / 0D */
537 udiv_qrnnd (q0, n0, n1, n0, d0);
538 q1 = 0;
540 /* Remainder in n0. */
542 else
544 /* qq = NN / 0d */
546 if (d0 == 0)
547 d0 = 1 / d0; /* Divide intentionally by zero. */
549 udiv_qrnnd (q1, n1, 0, n1, d0);
550 udiv_qrnnd (q0, n0, n1, n0, d0);
552 /* Remainder in n0. */
555 if (rp != 0)
557 rr.s.low = n0;
558 rr.s.high = 0;
559 *rp = rr.ll;
563 #else /* UDIV_NEEDS_NORMALIZATION */
565 if (d1 == 0)
567 if (d0 > n1)
569 /* 0q = nn / 0D */
571 count_leading_zeros (bm, d0);
573 if (bm != 0)
575 /* Normalize, i.e. make the most significant bit of the
576 denominator set. */
578 d0 = d0 << bm;
579 n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
580 n0 = n0 << bm;
583 udiv_qrnnd (q0, n0, n1, n0, d0);
584 q1 = 0;
586 /* Remainder in n0 >> bm. */
588 else
590 /* qq = NN / 0d */
592 if (d0 == 0)
593 d0 = 1 / d0; /* Divide intentionally by zero. */
595 count_leading_zeros (bm, d0);
597 if (bm == 0)
599 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
600 conclude (the most significant bit of n1 is set) /\ (the
601 leading quotient digit q1 = 1).
603 This special case is necessary, not an optimization.
604 (Shifts counts of W_TYPE_SIZE are undefined.) */
606 n1 -= d0;
607 q1 = 1;
609 else
611 /* Normalize. */
613 b = W_TYPE_SIZE - bm;
615 d0 = d0 << bm;
616 n2 = n1 >> b;
617 n1 = (n1 << bm) | (n0 >> b);
618 n0 = n0 << bm;
620 udiv_qrnnd (q1, n1, n2, n1, d0);
623 /* n1 != d0... */
625 udiv_qrnnd (q0, n0, n1, n0, d0);
627 /* Remainder in n0 >> bm. */
630 if (rp != 0)
632 rr.s.low = n0 >> bm;
633 rr.s.high = 0;
634 *rp = rr.ll;
637 #endif /* UDIV_NEEDS_NORMALIZATION */
639 else
641 if (d1 > n1)
643 /* 00 = nn / DD */
645 q0 = 0;
646 q1 = 0;
648 /* Remainder in n1n0. */
649 if (rp != 0)
651 rr.s.low = n0;
652 rr.s.high = n1;
653 *rp = rr.ll;
656 else
658 /* 0q = NN / dd */
660 count_leading_zeros (bm, d1);
661 if (bm == 0)
663 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
664 conclude (the most significant bit of n1 is set) /\ (the
665 quotient digit q0 = 0 or 1).
667 This special case is necessary, not an optimization. */
669 /* The condition on the next line takes advantage of that
670 n1 >= d1 (true due to program flow). */
671 if (n1 > d1 || n0 >= d0)
673 q0 = 1;
674 sub_ddmmss (n1, n0, n1, n0, d1, d0);
676 else
677 q0 = 0;
679 q1 = 0;
681 if (rp != 0)
683 rr.s.low = n0;
684 rr.s.high = n1;
685 *rp = rr.ll;
688 else
690 UWtype m1, m0;
691 /* Normalize. */
693 b = W_TYPE_SIZE - bm;
695 d1 = (d1 << bm) | (d0 >> b);
696 d0 = d0 << bm;
697 n2 = n1 >> b;
698 n1 = (n1 << bm) | (n0 >> b);
699 n0 = n0 << bm;
701 udiv_qrnnd (q0, n1, n2, n1, d1);
702 umul_ppmm (m1, m0, q0, d0);
704 if (m1 > n1 || (m1 == n1 && m0 > n0))
706 q0--;
707 sub_ddmmss (m1, m0, m1, m0, d1, d0);
710 q1 = 0;
712 /* Remainder in (n1n0 - m1m0) >> bm. */
713 if (rp != 0)
715 sub_ddmmss (n1, n0, n1, n0, m1, m0);
716 rr.s.low = (n1 << b) | (n0 >> bm);
717 rr.s.high = n1 >> bm;
718 *rp = rr.ll;
724 ww.s.low = q0;
725 ww.s.high = q1;
726 return ww.ll;
728 #endif
730 #ifdef L_divdi3
731 DWtype
732 __divdi3 (DWtype u, DWtype v)
734 word_type c = 0;
735 DWunion uu, vv;
736 DWtype w;
738 uu.ll = u;
739 vv.ll = v;
741 if (uu.s.high < 0)
742 c = ~c,
743 uu.ll = __negdi2 (uu.ll);
744 if (vv.s.high < 0)
745 c = ~c,
746 vv.ll = __negdi2 (vv.ll);
748 w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
749 if (c)
750 w = __negdi2 (w);
752 return w;
754 #endif
756 #ifdef L_moddi3
757 DWtype
758 __moddi3 (DWtype u, DWtype v)
760 word_type c = 0;
761 DWunion uu, vv;
762 DWtype w;
764 uu.ll = u;
765 vv.ll = v;
767 if (uu.s.high < 0)
768 c = ~c,
769 uu.ll = __negdi2 (uu.ll);
770 if (vv.s.high < 0)
771 vv.ll = __negdi2 (vv.ll);
773 (void) __udivmoddi4 (uu.ll, vv.ll, &w);
774 if (c)
775 w = __negdi2 (w);
777 return w;
779 #endif
781 #ifdef L_umoddi3
782 UDWtype
783 __umoddi3 (UDWtype u, UDWtype v)
785 UDWtype w;
787 (void) __udivmoddi4 (u, v, &w);
789 return w;
791 #endif
793 #ifdef L_udivdi3
794 UDWtype
795 __udivdi3 (UDWtype n, UDWtype d)
797 return __udivmoddi4 (n, d, (UDWtype *) 0);
799 #endif
801 #ifdef L_cmpdi2
802 word_type
803 __cmpdi2 (DWtype a, DWtype b)
805 DWunion au, bu;
807 au.ll = a, bu.ll = b;
809 if (au.s.high < bu.s.high)
810 return 0;
811 else if (au.s.high > bu.s.high)
812 return 2;
813 if ((UWtype) au.s.low < (UWtype) bu.s.low)
814 return 0;
815 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
816 return 2;
817 return 1;
819 #endif
821 #ifdef L_ucmpdi2
822 word_type
823 __ucmpdi2 (DWtype a, DWtype b)
825 DWunion au, bu;
827 au.ll = a, bu.ll = b;
829 if ((UWtype) au.s.high < (UWtype) bu.s.high)
830 return 0;
831 else if ((UWtype) au.s.high > (UWtype) bu.s.high)
832 return 2;
833 if ((UWtype) au.s.low < (UWtype) bu.s.low)
834 return 0;
835 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
836 return 2;
837 return 1;
839 #endif
841 #if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
842 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
843 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
845 DWtype
846 __fixunstfdi (TFtype a)
848 TFtype b;
849 UDWtype v;
851 if (a < 0)
852 return 0;
854 /* Compute high word of result, as a flonum. */
855 b = (a / HIGH_WORD_COEFF);
856 /* Convert that to fixed (but not to DWtype!),
857 and shift it into the high word. */
858 v = (UWtype) b;
859 v <<= WORD_SIZE;
860 /* Remove high part from the TFtype, leaving the low part as flonum. */
861 a -= (TFtype)v;
862 /* Convert that to fixed (but not to DWtype!) and add it in.
863 Sometimes A comes out negative. This is significant, since
864 A has more bits than a long int does. */
865 if (a < 0)
866 v -= (UWtype) (- a);
867 else
868 v += (UWtype) a;
869 return v;
871 #endif
873 #if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
874 extern DWtype __fixunstfdi (TFtype a);
876 DWtype
877 __fixtfdi (TFtype a)
879 if (a < 0)
880 return - __fixunstfdi (-a);
881 return __fixunstfdi (a);
883 #endif
885 #if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
886 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
887 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
889 DWtype
890 __fixunsxfdi (XFtype a)
892 XFtype b;
893 UDWtype v;
895 if (a < 0)
896 return 0;
898 /* Compute high word of result, as a flonum. */
899 b = (a / HIGH_WORD_COEFF);
900 /* Convert that to fixed (but not to DWtype!),
901 and shift it into the high word. */
902 v = (UWtype) b;
903 v <<= WORD_SIZE;
904 /* Remove high part from the XFtype, leaving the low part as flonum. */
905 a -= (XFtype)v;
906 /* Convert that to fixed (but not to DWtype!) and add it in.
907 Sometimes A comes out negative. This is significant, since
908 A has more bits than a long int does. */
909 if (a < 0)
910 v -= (UWtype) (- a);
911 else
912 v += (UWtype) a;
913 return v;
915 #endif
917 #if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
918 extern DWtype __fixunsxfdi (XFtype a);
920 DWtype
921 __fixxfdi (XFtype a)
923 if (a < 0)
924 return - __fixunsxfdi (-a);
925 return __fixunsxfdi (a);
927 #endif
929 #ifdef L_fixunsdfdi
930 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
931 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
933 DWtype
934 __fixunsdfdi (DFtype a)
936 DFtype b;
937 UDWtype v;
939 if (a < 0)
940 return 0;
942 /* Compute high word of result, as a flonum. */
943 b = (a / HIGH_WORD_COEFF);
944 /* Convert that to fixed (but not to DWtype!),
945 and shift it into the high word. */
946 v = (UWtype) b;
947 v <<= WORD_SIZE;
948 /* Remove high part from the DFtype, leaving the low part as flonum. */
949 a -= (DFtype)v;
950 /* Convert that to fixed (but not to DWtype!) and add it in.
951 Sometimes A comes out negative. This is significant, since
952 A has more bits than a long int does. */
953 if (a < 0)
954 v -= (UWtype) (- a);
955 else
956 v += (UWtype) a;
957 return v;
959 #endif
961 #ifdef L_fixdfdi
962 extern DWtype __fixunsdfdi (DFtype a);
964 DWtype
965 __fixdfdi (DFtype a)
967 if (a < 0)
968 return - __fixunsdfdi (-a);
969 return __fixunsdfdi (a);
971 #endif
973 #ifdef L_fixunssfdi
974 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
975 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
977 DWtype
978 __fixunssfdi (SFtype original_a)
980 /* Convert the SFtype to a DFtype, because that is surely not going
981 to lose any bits. Some day someone else can write a faster version
982 that avoids converting to DFtype, and verify it really works right. */
983 DFtype a = original_a;
984 DFtype b;
985 UDWtype v;
987 if (a < 0)
988 return 0;
990 /* Compute high word of result, as a flonum. */
991 b = (a / HIGH_WORD_COEFF);
992 /* Convert that to fixed (but not to DWtype!),
993 and shift it into the high word. */
994 v = (UWtype) b;
995 v <<= WORD_SIZE;
996 /* Remove high part from the DFtype, leaving the low part as flonum. */
997 a -= (DFtype)v;
998 /* Convert that to fixed (but not to DWtype!) and add it in.
999 Sometimes A comes out negative. This is significant, since
1000 A has more bits than a long int does. */
1001 if (a < 0)
1002 v -= (UWtype) (- a);
1003 else
1004 v += (UWtype) a;
1005 return v;
1007 #endif
1009 #ifdef L_fixsfdi
1010 extern DWtype __fixunssfdi (SFtype a);
1012 DWtype
1013 __fixsfdi (SFtype a)
1015 if (a < 0)
1016 return - __fixunssfdi (-a);
1017 return __fixunssfdi (a);
1019 #endif
1021 #if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
1022 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1023 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1024 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1026 XFtype
1027 __floatdixf (DWtype u)
1029 XFtype d;
1031 d = (Wtype) (u >> WORD_SIZE);
1032 d *= HIGH_HALFWORD_COEFF;
1033 d *= HIGH_HALFWORD_COEFF;
1034 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1036 return d;
1038 #endif
1040 #if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
1041 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1042 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1043 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1045 TFtype
1046 __floatditf (DWtype u)
1048 TFtype d;
1050 d = (Wtype) (u >> WORD_SIZE);
1051 d *= HIGH_HALFWORD_COEFF;
1052 d *= HIGH_HALFWORD_COEFF;
1053 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1055 return d;
1057 #endif
1059 #ifdef L_floatdidf
1060 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1061 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1062 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1064 DFtype
1065 __floatdidf (DWtype u)
1067 DFtype d;
1069 d = (Wtype) (u >> WORD_SIZE);
1070 d *= HIGH_HALFWORD_COEFF;
1071 d *= HIGH_HALFWORD_COEFF;
1072 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1074 return d;
1076 #endif
1078 #ifdef L_floatdisf
1079 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1080 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1081 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1082 #define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT)
1084 /* Define codes for all the float formats that we know of. Note
1085 that this is copied from real.h. */
1087 #define UNKNOWN_FLOAT_FORMAT 0
1088 #define IEEE_FLOAT_FORMAT 1
1089 #define VAX_FLOAT_FORMAT 2
1090 #define IBM_FLOAT_FORMAT 3
1092 /* Default to IEEE float if not specified. Nearly all machines use it. */
1093 #ifndef HOST_FLOAT_FORMAT
1094 #define HOST_FLOAT_FORMAT IEEE_FLOAT_FORMAT
1095 #endif
1097 #if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1098 #define DF_SIZE 53
1099 #define SF_SIZE 24
1100 #endif
1102 #if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
1103 #define DF_SIZE 56
1104 #define SF_SIZE 24
1105 #endif
1107 #if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
1108 #define DF_SIZE 56
1109 #define SF_SIZE 24
1110 #endif
1112 SFtype
1113 __floatdisf (DWtype u)
1115 /* Do the calculation in DFmode
1116 so that we don't lose any of the precision of the high word
1117 while multiplying it. */
1118 DFtype f;
1120 /* Protect against double-rounding error.
1121 Represent any low-order bits, that might be truncated in DFmode,
1122 by a bit that won't be lost. The bit can go in anywhere below the
1123 rounding position of the SFmode. A fixed mask and bit position
1124 handles all usual configurations. It doesn't handle the case
1125 of 128-bit DImode, however. */
1126 if (DF_SIZE < DI_SIZE
1127 && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1129 #define REP_BIT ((UWtype) 1 << (DI_SIZE - DF_SIZE))
1130 if (! (- ((DWtype) 1 << DF_SIZE) < u
1131 && u < ((DWtype) 1 << DF_SIZE)))
1133 if ((UWtype) u & (REP_BIT - 1))
1134 u |= REP_BIT;
1137 f = (Wtype) (u >> WORD_SIZE);
1138 f *= HIGH_HALFWORD_COEFF;
1139 f *= HIGH_HALFWORD_COEFF;
1140 f += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1142 return (SFtype) f;
1144 #endif
1146 #if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
1147 /* Reenable the normal types, in case limits.h needs them. */
1148 #undef char
1149 #undef short
1150 #undef int
1151 #undef long
1152 #undef unsigned
1153 #undef float
1154 #undef double
1155 #undef MIN
1156 #undef MAX
1157 #include <limits.h>
1159 UWtype
1160 __fixunsxfsi (XFtype a)
1162 if (a >= - (DFtype) LONG_MIN)
1163 return (Wtype) (a + LONG_MIN) - LONG_MIN;
1164 return (Wtype) a;
1166 #endif
1168 #ifdef L_fixunsdfsi
1169 /* Reenable the normal types, in case limits.h needs them. */
1170 #undef char
1171 #undef short
1172 #undef int
1173 #undef long
1174 #undef unsigned
1175 #undef float
1176 #undef double
1177 #undef MIN
1178 #undef MAX
1179 #include <limits.h>
1181 UWtype
1182 __fixunsdfsi (DFtype a)
1184 if (a >= - (DFtype) LONG_MIN)
1185 return (Wtype) (a + LONG_MIN) - LONG_MIN;
1186 return (Wtype) a;
1188 #endif
1190 #ifdef L_fixunssfsi
1191 /* Reenable the normal types, in case limits.h needs them. */
1192 #undef char
1193 #undef short
1194 #undef int
1195 #undef long
1196 #undef unsigned
1197 #undef float
1198 #undef double
1199 #undef MIN
1200 #undef MAX
1201 #include <limits.h>
1203 UWtype
1204 __fixunssfsi (SFtype a)
1206 if (a >= - (SFtype) LONG_MIN)
1207 return (Wtype) (a + LONG_MIN) - LONG_MIN;
1208 return (Wtype) a;
1210 #endif
1212 /* From here on down, the routines use normal data types. */
1214 #define SItype bogus_type
1215 #define USItype bogus_type
1216 #define DItype bogus_type
1217 #define UDItype bogus_type
1218 #define SFtype bogus_type
1219 #define DFtype bogus_type
1220 #undef Wtype
1221 #undef UWtype
1222 #undef HWtype
1223 #undef UHWtype
1224 #undef DWtype
1225 #undef UDWtype
1227 #undef char
1228 #undef short
1229 #undef int
1230 #undef long
1231 #undef unsigned
1232 #undef float
1233 #undef double
1235 #ifdef L__gcc_bcmp
1237 /* Like bcmp except the sign is meaningful.
1238 Result is negative if S1 is less than S2,
1239 positive if S1 is greater, 0 if S1 and S2 are equal. */
1242 __gcc_bcmp (unsigned char *s1, unsigned char *s2, size_t size)
1244 while (size > 0)
1246 unsigned char c1 = *s1++, c2 = *s2++;
1247 if (c1 != c2)
1248 return c1 - c2;
1249 size--;
1251 return 0;
1254 #endif
1255 \f\f
1256 #ifdef L__dummy
1257 void
1258 __dummy (void) {}
1259 #endif
1261 #ifdef L_varargs
1262 #ifdef __i860__
1263 #if defined(__svr4__) || defined(__alliant__)
1264 asm (" .text");
1265 asm (" .align 4");
1267 /* The Alliant needs the added underscore. */
1268 asm (".globl __builtin_saveregs");
1269 asm ("__builtin_saveregs:");
1270 asm (".globl ___builtin_saveregs");
1271 asm ("___builtin_saveregs:");
1273 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
1274 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
1275 area and also for a new va_list
1276 structure */
1277 /* Save all argument registers in the arg reg save area. The
1278 arg reg save area must have the following layout (according
1279 to the svr4 ABI):
1281 struct {
1282 union {
1283 float freg[8];
1284 double dreg[4];
1285 } float_regs;
1286 long ireg[12];
1290 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
1291 asm (" fst.q %f12,16(%sp)");
1293 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
1294 asm (" st.l %r17,36(%sp)");
1295 asm (" st.l %r18,40(%sp)");
1296 asm (" st.l %r19,44(%sp)");
1297 asm (" st.l %r20,48(%sp)");
1298 asm (" st.l %r21,52(%sp)");
1299 asm (" st.l %r22,56(%sp)");
1300 asm (" st.l %r23,60(%sp)");
1301 asm (" st.l %r24,64(%sp)");
1302 asm (" st.l %r25,68(%sp)");
1303 asm (" st.l %r26,72(%sp)");
1304 asm (" st.l %r27,76(%sp)");
1306 asm (" adds 80,%sp,%r16"); /* compute the address of the new
1307 va_list structure. Put in into
1308 r16 so that it will be returned
1309 to the caller. */
1311 /* Initialize all fields of the new va_list structure. This
1312 structure looks like:
1314 typedef struct {
1315 unsigned long ireg_used;
1316 unsigned long freg_used;
1317 long *reg_base;
1318 long *mem_ptr;
1319 } va_list;
1322 asm (" st.l %r0, 0(%r16)"); /* nfixed */
1323 asm (" st.l %r0, 4(%r16)"); /* nfloating */
1324 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
1325 asm (" bri %r1"); /* delayed return */
1326 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
1328 #else /* not __svr4__ */
1329 #if defined(__PARAGON__)
1331 * we'll use SVR4-ish varargs but need SVR3.2 assembler syntax,
1332 * and we stand a better chance of hooking into libraries
1333 * compiled by PGI. [andyp@ssd.intel.com]
1335 asm (" .text");
1336 asm (" .align 4");
1337 asm (".globl __builtin_saveregs");
1338 asm ("__builtin_saveregs:");
1339 asm (".globl ___builtin_saveregs");
1340 asm ("___builtin_saveregs:");
1342 asm (" andnot 0x0f,sp,sp"); /* round down to 16-byte boundary */
1343 asm (" adds -96,sp,sp"); /* allocate stack space for reg save
1344 area and also for a new va_list
1345 structure */
1346 /* Save all argument registers in the arg reg save area. The
1347 arg reg save area must have the following layout (according
1348 to the svr4 ABI):
1350 struct {
1351 union {
1352 float freg[8];
1353 double dreg[4];
1354 } float_regs;
1355 long ireg[12];
1359 asm (" fst.q f8, 0(sp)");
1360 asm (" fst.q f12,16(sp)");
1361 asm (" st.l r16,32(sp)");
1362 asm (" st.l r17,36(sp)");
1363 asm (" st.l r18,40(sp)");
1364 asm (" st.l r19,44(sp)");
1365 asm (" st.l r20,48(sp)");
1366 asm (" st.l r21,52(sp)");
1367 asm (" st.l r22,56(sp)");
1368 asm (" st.l r23,60(sp)");
1369 asm (" st.l r24,64(sp)");
1370 asm (" st.l r25,68(sp)");
1371 asm (" st.l r26,72(sp)");
1372 asm (" st.l r27,76(sp)");
1374 asm (" adds 80,sp,r16"); /* compute the address of the new
1375 va_list structure. Put in into
1376 r16 so that it will be returned
1377 to the caller. */
1379 /* Initialize all fields of the new va_list structure. This
1380 structure looks like:
1382 typedef struct {
1383 unsigned long ireg_used;
1384 unsigned long freg_used;
1385 long *reg_base;
1386 long *mem_ptr;
1387 } va_list;
1390 asm (" st.l r0, 0(r16)"); /* nfixed */
1391 asm (" st.l r0, 4(r16)"); /* nfloating */
1392 asm (" st.l sp, 8(r16)"); /* __va_ctl points to __va_struct. */
1393 asm (" bri r1"); /* delayed return */
1394 asm (" st.l r28,12(r16)"); /* pointer to overflow args */
1395 #else /* not __PARAGON__ */
1396 asm (" .text");
1397 asm (" .align 4");
1399 asm (".globl ___builtin_saveregs");
1400 asm ("___builtin_saveregs:");
1401 asm (" mov sp,r30");
1402 asm (" andnot 0x0f,sp,sp");
1403 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
1405 /* Fill in the __va_struct. */
1406 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
1407 asm (" st.l r17, 4(sp)"); /* int fixed[12] */
1408 asm (" st.l r18, 8(sp)");
1409 asm (" st.l r19,12(sp)");
1410 asm (" st.l r20,16(sp)");
1411 asm (" st.l r21,20(sp)");
1412 asm (" st.l r22,24(sp)");
1413 asm (" st.l r23,28(sp)");
1414 asm (" st.l r24,32(sp)");
1415 asm (" st.l r25,36(sp)");
1416 asm (" st.l r26,40(sp)");
1417 asm (" st.l r27,44(sp)");
1419 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
1420 asm (" fst.q f12,64(sp)"); /* int floating[8] */
1422 /* Fill in the __va_ctl. */
1423 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
1424 asm (" st.l r28,84(sp)"); /* pointer to more args */
1425 asm (" st.l r0, 88(sp)"); /* nfixed */
1426 asm (" st.l r0, 92(sp)"); /* nfloating */
1428 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
1429 asm (" bri r1");
1430 asm (" mov r30,sp");
1431 /* recover stack and pass address to start
1432 of data. */
1433 #endif /* not __PARAGON__ */
1434 #endif /* not __svr4__ */
1435 #else /* not __i860__ */
1436 #ifdef __sparc__
1437 asm (".global __builtin_saveregs");
1438 asm ("__builtin_saveregs:");
1439 asm (".global ___builtin_saveregs");
1440 asm ("___builtin_saveregs:");
1441 #ifdef NEED_PROC_COMMAND
1442 asm (".proc 020");
1443 #endif
1444 asm ("st %i0,[%fp+68]");
1445 asm ("st %i1,[%fp+72]");
1446 asm ("st %i2,[%fp+76]");
1447 asm ("st %i3,[%fp+80]");
1448 asm ("st %i4,[%fp+84]");
1449 asm ("retl");
1450 asm ("st %i5,[%fp+88]");
1451 #ifdef NEED_TYPE_COMMAND
1452 asm (".type __builtin_saveregs,#function");
1453 asm (".size __builtin_saveregs,.-__builtin_saveregs");
1454 #endif
1455 #else /* not __sparc__ */
1456 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1458 asm (" .text");
1459 #ifdef __mips16
1460 asm (" .set nomips16");
1461 #endif
1462 asm (" .ent __builtin_saveregs");
1463 asm (" .globl __builtin_saveregs");
1464 asm ("__builtin_saveregs:");
1465 asm (" sw $4,0($30)");
1466 asm (" sw $5,4($30)");
1467 asm (" sw $6,8($30)");
1468 asm (" sw $7,12($30)");
1469 asm (" j $31");
1470 asm (" .end __builtin_saveregs");
1471 #else /* not __mips__, etc. */
1473 void *
1474 __builtin_saveregs (void)
1476 abort ();
1479 #endif /* not __mips__ */
1480 #endif /* not __sparc__ */
1481 #endif /* not __i860__ */
1482 #endif
1484 #ifdef L_eprintf
1485 #ifndef inhibit_libc
1487 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1488 #include <stdio.h>
1489 /* This is used by the `assert' macro. */
1490 extern void __eprintf (const char *, const char *, unsigned int, const char *)
1491 __attribute__ ((__noreturn__));
1493 void
1494 __eprintf (const char *string, const char *expression,
1495 unsigned int line, const char *filename)
1497 fprintf (stderr, string, expression, line, filename);
1498 fflush (stderr);
1499 abort ();
1502 #endif
1503 #endif
1505 #ifdef L_bb
1507 /* Structure emitted by -a */
1508 struct bb
1510 long zero_word;
1511 const char *filename;
1512 long *counts;
1513 long ncounts;
1514 struct bb *next;
1515 const unsigned long *addresses;
1517 /* Older GCC's did not emit these fields. */
1518 long nwords;
1519 const char **functions;
1520 const long *line_nums;
1521 const char **filenames;
1522 char *flags;
1525 #ifdef BLOCK_PROFILER_CODE
1526 BLOCK_PROFILER_CODE
1527 #else
1528 #ifndef inhibit_libc
1530 /* Simple minded basic block profiling output dumper for
1531 systems that don't provide tcov support. At present,
1532 it requires atexit and stdio. */
1534 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1535 #include <stdio.h>
1536 char *ctime ();
1538 #include "gbl-ctors.h"
1539 #include "gcov-io.h"
1540 #include <string.h>
1541 #ifdef TARGET_HAS_F_SETLKW
1542 #include <fcntl.h>
1543 #include <errno.h>
1544 #endif
1546 static struct bb *bb_head;
1548 static int num_digits (long value, int base) __attribute__ ((const));
1550 /* Return the number of digits needed to print a value */
1551 /* __inline__ */ static int num_digits (long value, int base)
1553 int minus = (value < 0 && base != 16);
1554 unsigned long v = (minus) ? -value : value;
1555 int ret = minus;
1559 v /= base;
1560 ret++;
1562 while (v);
1564 return ret;
1567 void
1568 __bb_exit_func (void)
1570 FILE *da_file, *file;
1571 long time_value;
1572 int i;
1574 if (bb_head == 0)
1575 return;
1577 i = strlen (bb_head->filename) - 3;
1579 if (!strcmp (bb_head->filename+i, ".da"))
1581 /* Must be -fprofile-arcs not -a.
1582 Dump data in a form that gcov expects. */
1584 struct bb *ptr;
1586 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1588 int firstchar;
1590 /* Make sure the output file exists -
1591 but don't clobber exiting data. */
1592 if ((da_file = fopen (ptr->filename, "a")) != 0)
1593 fclose (da_file);
1595 /* Need to re-open in order to be able to write from the start. */
1596 da_file = fopen (ptr->filename, "r+b");
1597 /* Some old systems might not allow the 'b' mode modifier.
1598 Therefore, try to open without it. This can lead to a race
1599 condition so that when you delete and re-create the file, the
1600 file might be opened in text mode, but then, you shouldn't
1601 delete the file in the first place. */
1602 if (da_file == 0)
1603 da_file = fopen (ptr->filename, "r+");
1604 if (da_file == 0)
1606 fprintf (stderr, "arc profiling: Can't open output file %s.\n",
1607 ptr->filename);
1608 continue;
1611 /* After a fork, another process might try to read and/or write
1612 the same file simultanously. So if we can, lock the file to
1613 avoid race conditions. */
1614 #if defined (TARGET_HAS_F_SETLKW)
1616 struct flock s_flock;
1618 s_flock.l_type = F_WRLCK;
1619 s_flock.l_whence = SEEK_SET;
1620 s_flock.l_start = 0;
1621 s_flock.l_len = 1;
1622 s_flock.l_pid = getpid ();
1624 while (fcntl (fileno (da_file), F_SETLKW, &s_flock)
1625 && errno == EINTR);
1627 #endif
1629 /* If the file is not empty, and the number of counts in it is the
1630 same, then merge them in. */
1631 firstchar = fgetc (da_file);
1632 if (firstchar == EOF)
1634 if (ferror (da_file))
1636 fprintf (stderr, "arc profiling: Can't read output file ");
1637 perror (ptr->filename);
1640 else
1642 long n_counts = 0;
1644 if (ungetc (firstchar, da_file) == EOF)
1645 rewind (da_file);
1646 if (__read_long (&n_counts, da_file, 8) != 0)
1648 fprintf (stderr, "arc profiling: Can't read output file %s.\n",
1649 ptr->filename);
1650 continue;
1653 if (n_counts == ptr->ncounts)
1655 int i;
1657 for (i = 0; i < n_counts; i++)
1659 long v = 0;
1661 if (__read_long (&v, da_file, 8) != 0)
1663 fprintf (stderr, "arc profiling: Can't read output file %s.\n",
1664 ptr->filename);
1665 break;
1667 ptr->counts[i] += v;
1673 rewind (da_file);
1675 /* ??? Should first write a header to the file. Preferably, a 4 byte
1676 magic number, 4 bytes containing the time the program was
1677 compiled, 4 bytes containing the last modification time of the
1678 source file, and 4 bytes indicating the compiler options used.
1680 That way we can easily verify that the proper source/executable/
1681 data file combination is being used from gcov. */
1683 if (__write_long (ptr->ncounts, da_file, 8) != 0)
1686 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1687 ptr->filename);
1689 else
1691 int j;
1692 long *count_ptr = ptr->counts;
1693 int ret = 0;
1694 for (j = ptr->ncounts; j > 0; j--)
1696 if (__write_long (*count_ptr, da_file, 8) != 0)
1698 ret=1;
1699 break;
1701 count_ptr++;
1703 if (ret)
1704 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1705 ptr->filename);
1708 if (fclose (da_file) == EOF)
1709 fprintf (stderr, "arc profiling: Error closing output file %s.\n",
1710 ptr->filename);
1713 return;
1716 /* Must be basic block profiling. Emit a human readable output file. */
1718 file = fopen ("bb.out", "a");
1720 if (!file)
1721 perror ("bb.out");
1723 else
1725 struct bb *ptr;
1727 /* This is somewhat type incorrect, but it avoids worrying about
1728 exactly where time.h is included from. It should be ok unless
1729 a void * differs from other pointer formats, or if sizeof (long)
1730 is < sizeof (time_t). It would be nice if we could assume the
1731 use of rationale standards here. */
1733 time ((void *) &time_value);
1734 fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value));
1736 /* We check the length field explicitly in order to allow compatibility
1737 with older GCC's which did not provide it. */
1739 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1741 int i;
1742 int func_p = (ptr->nwords >= (long) sizeof (struct bb)
1743 && ptr->nwords <= 1000
1744 && ptr->functions);
1745 int line_p = (func_p && ptr->line_nums);
1746 int file_p = (func_p && ptr->filenames);
1747 int addr_p = (ptr->addresses != 0);
1748 long ncounts = ptr->ncounts;
1749 long cnt_max = 0;
1750 long line_max = 0;
1751 long addr_max = 0;
1752 int file_len = 0;
1753 int func_len = 0;
1754 int blk_len = num_digits (ncounts, 10);
1755 int cnt_len;
1756 int line_len;
1757 int addr_len;
1759 fprintf (file, "File %s, %ld basic blocks \n\n",
1760 ptr->filename, ncounts);
1762 /* Get max values for each field. */
1763 for (i = 0; i < ncounts; i++)
1765 const char *p;
1766 int len;
1768 if (cnt_max < ptr->counts[i])
1769 cnt_max = ptr->counts[i];
1771 if (addr_p && (unsigned long) addr_max < ptr->addresses[i])
1772 addr_max = ptr->addresses[i];
1774 if (line_p && line_max < ptr->line_nums[i])
1775 line_max = ptr->line_nums[i];
1777 if (func_p)
1779 p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>";
1780 len = strlen (p);
1781 if (func_len < len)
1782 func_len = len;
1785 if (file_p)
1787 p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>";
1788 len = strlen (p);
1789 if (file_len < len)
1790 file_len = len;
1794 addr_len = num_digits (addr_max, 16);
1795 cnt_len = num_digits (cnt_max, 10);
1796 line_len = num_digits (line_max, 10);
1798 /* Now print out the basic block information. */
1799 for (i = 0; i < ncounts; i++)
1801 fprintf (file,
1802 " Block #%*d: executed %*ld time(s)",
1803 blk_len, i+1,
1804 cnt_len, ptr->counts[i]);
1806 if (addr_p)
1807 fprintf (file, " address= 0x%.*lx", addr_len,
1808 ptr->addresses[i]);
1810 if (func_p)
1811 fprintf (file, " function= %-*s", func_len,
1812 (ptr->functions[i]) ? ptr->functions[i] : "<none>");
1814 if (line_p)
1815 fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]);
1817 if (file_p)
1818 fprintf (file, " file= %s",
1819 (ptr->filenames[i]) ? ptr->filenames[i] : "<none>");
1821 fprintf (file, "\n");
1824 fprintf (file, "\n");
1825 fflush (file);
1828 fprintf (file, "\n\n");
1829 fclose (file);
1833 void
1834 __bb_init_func (struct bb *blocks)
1836 /* User is supposed to check whether the first word is non-0,
1837 but just in case.... */
1839 if (blocks->zero_word)
1840 return;
1842 /* Initialize destructor. */
1843 if (!bb_head)
1844 atexit (__bb_exit_func);
1846 /* Set up linked list. */
1847 blocks->zero_word = 1;
1848 blocks->next = bb_head;
1849 bb_head = blocks;
1852 /* Called before fork or exec - write out profile information gathered so
1853 far and reset it to zero. This avoids duplication or loss of the
1854 profile information gathered so far. */
1855 void
1856 __bb_fork_func (void)
1858 struct bb *ptr;
1860 __bb_exit_func ();
1861 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1863 long i;
1864 for (i = ptr->ncounts - 1; i >= 0; i--)
1865 ptr->counts[i] = 0;
1869 #ifndef MACHINE_STATE_SAVE
1870 #define MACHINE_STATE_SAVE(ID)
1871 #endif
1872 #ifndef MACHINE_STATE_RESTORE
1873 #define MACHINE_STATE_RESTORE(ID)
1874 #endif
1876 /* Number of buckets in hashtable of basic block addresses. */
1878 #define BB_BUCKETS 311
1880 /* Maximum length of string in file bb.in. */
1882 #define BBINBUFSIZE 500
1884 struct bb_edge
1886 struct bb_edge *next;
1887 unsigned long src_addr;
1888 unsigned long dst_addr;
1889 unsigned long count;
1892 enum bb_func_mode
1894 TRACE_KEEP = 0, TRACE_ON = 1, TRACE_OFF = 2
1897 struct bb_func
1899 struct bb_func *next;
1900 char *funcname;
1901 char *filename;
1902 enum bb_func_mode mode;
1905 /* This is the connection to the outside world.
1906 The BLOCK_PROFILER macro must set __bb.blocks
1907 and __bb.blockno. */
1909 struct {
1910 unsigned long blockno;
1911 struct bb *blocks;
1912 } __bb;
1914 /* Vars to store addrs of source and destination basic blocks
1915 of a jump. */
1917 static unsigned long bb_src = 0;
1918 static unsigned long bb_dst = 0;
1920 static FILE *bb_tracefile = (FILE *) 0;
1921 static struct bb_edge **bb_hashbuckets = (struct bb_edge **) 0;
1922 static struct bb_func *bb_func_head = (struct bb_func *) 0;
1923 static unsigned long bb_callcount = 0;
1924 static int bb_mode = 0;
1926 static unsigned long *bb_stack = (unsigned long *) 0;
1927 static size_t bb_stacksize = 0;
1929 static int reported = 0;
1931 /* Trace modes:
1932 Always : Print execution frequencies of basic blocks
1933 to file bb.out.
1934 bb_mode & 1 != 0 : Dump trace of basic blocks to file bbtrace[.gz]
1935 bb_mode & 2 != 0 : Print jump frequencies to file bb.out.
1936 bb_mode & 4 != 0 : Cut call instructions from basic block flow.
1937 bb_mode & 8 != 0 : Insert return instructions in basic block flow.
1940 #ifdef HAVE_POPEN
1942 /*#include <sys/types.h>*/
1943 #include <sys/stat.h>
1944 /*#include <malloc.h>*/
1946 /* Commands executed by gopen. */
1948 #define GOPENDECOMPRESS "gzip -cd "
1949 #define GOPENCOMPRESS "gzip -c >"
1951 /* Like fopen but pipes through gzip. mode may only be "r" or "w".
1952 If it does not compile, simply replace gopen by fopen and delete
1953 '.gz' from any first parameter to gopen. */
1955 static FILE *
1956 gopen (char *fn, char *mode)
1958 int use_gzip;
1959 char *p;
1961 if (mode[1])
1962 return (FILE *) 0;
1964 if (mode[0] != 'r' && mode[0] != 'w')
1965 return (FILE *) 0;
1967 p = fn + strlen (fn)-1;
1968 use_gzip = ((p[-1] == '.' && (p[0] == 'Z' || p[0] == 'z'))
1969 || (p[-2] == '.' && p[-1] == 'g' && p[0] == 'z'));
1971 if (use_gzip)
1973 if (mode[0]=='r')
1975 FILE *f;
1976 char *s = (char *) malloc (sizeof (char) * strlen (fn)
1977 + sizeof (GOPENDECOMPRESS));
1978 strcpy (s, GOPENDECOMPRESS);
1979 strcpy (s + (sizeof (GOPENDECOMPRESS)-1), fn);
1980 f = popen (s, mode);
1981 free (s);
1982 return f;
1985 else
1987 FILE *f;
1988 char *s = (char *) malloc (sizeof (char) * strlen (fn)
1989 + sizeof (GOPENCOMPRESS));
1990 strcpy (s, GOPENCOMPRESS);
1991 strcpy (s + (sizeof (GOPENCOMPRESS)-1), fn);
1992 if (!(f = popen (s, mode)))
1993 f = fopen (s, mode);
1994 free (s);
1995 return f;
1999 else
2000 return fopen (fn, mode);
2003 static int
2004 gclose (FILE *f)
2006 struct stat buf;
2008 if (f != 0)
2010 if (!fstat (fileno (f), &buf) && S_ISFIFO (buf.st_mode))
2011 return pclose (f);
2013 return fclose (f);
2015 return 0;
2018 #endif /* HAVE_POPEN */
2020 /* Called once per program. */
2022 static void
2023 __bb_exit_trace_func (void)
2025 FILE *file = fopen ("bb.out", "a");
2026 struct bb_func *f;
2027 struct bb *b;
2029 if (!file)
2030 perror ("bb.out");
2032 if (bb_mode & 1)
2034 if (!bb_tracefile)
2035 perror ("bbtrace");
2036 else
2037 #ifdef HAVE_POPEN
2038 gclose (bb_tracefile);
2039 #else
2040 fclose (bb_tracefile);
2041 #endif /* HAVE_POPEN */
2044 /* Check functions in `bb.in'. */
2046 if (file)
2048 long time_value;
2049 const struct bb_func *p;
2050 int printed_something = 0;
2051 struct bb *ptr;
2052 long blk;
2054 /* This is somewhat type incorrect. */
2055 time ((void *) &time_value);
2057 for (p = bb_func_head; p != (struct bb_func *) 0; p = p->next)
2059 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
2061 if (!ptr->filename || (p->filename != (char *) 0 && strcmp (p->filename, ptr->filename)))
2062 continue;
2063 for (blk = 0; blk < ptr->ncounts; blk++)
2065 if (!strcmp (p->funcname, ptr->functions[blk]))
2066 goto found;
2070 if (!printed_something)
2072 fprintf (file, "Functions in `bb.in' not executed during basic block profiling on %s\n", ctime ((void *) &time_value));
2073 printed_something = 1;
2076 fprintf (file, "\tFunction %s", p->funcname);
2077 if (p->filename)
2078 fprintf (file, " of file %s", p->filename);
2079 fprintf (file, "\n" );
2081 found: ;
2084 if (printed_something)
2085 fprintf (file, "\n");
2089 if (bb_mode & 2)
2091 if (!bb_hashbuckets)
2093 if (!reported)
2095 fprintf (stderr, "Profiler: out of memory\n");
2096 reported = 1;
2098 return;
2101 else if (file)
2103 long time_value;
2104 int i;
2105 unsigned long addr_max = 0;
2106 unsigned long cnt_max = 0;
2107 int cnt_len;
2108 int addr_len;
2110 /* This is somewhat type incorrect, but it avoids worrying about
2111 exactly where time.h is included from. It should be ok unless
2112 a void * differs from other pointer formats, or if sizeof (long)
2113 is < sizeof (time_t). It would be nice if we could assume the
2114 use of rationale standards here. */
2116 time ((void *) &time_value);
2117 fprintf (file, "Basic block jump tracing");
2119 switch (bb_mode & 12)
2121 case 0:
2122 fprintf (file, " (with call)");
2123 break;
2125 case 4:
2126 /* Print nothing. */
2127 break;
2129 case 8:
2130 fprintf (file, " (with call & ret)");
2131 break;
2133 case 12:
2134 fprintf (file, " (with ret)");
2135 break;
2138 fprintf (file, " finished on %s\n", ctime ((void *) &time_value));
2140 for (i = 0; i < BB_BUCKETS; i++)
2142 struct bb_edge *bucket = bb_hashbuckets[i];
2143 for ( ; bucket; bucket = bucket->next )
2145 if (addr_max < bucket->src_addr)
2146 addr_max = bucket->src_addr;
2147 if (addr_max < bucket->dst_addr)
2148 addr_max = bucket->dst_addr;
2149 if (cnt_max < bucket->count)
2150 cnt_max = bucket->count;
2153 addr_len = num_digits (addr_max, 16);
2154 cnt_len = num_digits (cnt_max, 10);
2156 for ( i = 0; i < BB_BUCKETS; i++)
2158 struct bb_edge *bucket = bb_hashbuckets[i];
2159 for ( ; bucket; bucket = bucket->next )
2161 fprintf (file,
2162 "Jump from block 0x%.*lx to block 0x%.*lx executed %*lu time(s)\n",
2163 addr_len, bucket->src_addr,
2164 addr_len, bucket->dst_addr,
2165 cnt_len, bucket->count);
2169 fprintf (file, "\n");
2174 if (file)
2175 fclose (file);
2177 /* Free allocated memory. */
2179 f = bb_func_head;
2180 while (f)
2182 struct bb_func *old = f;
2184 f = f->next;
2185 if (old->funcname) free (old->funcname);
2186 if (old->filename) free (old->filename);
2187 free (old);
2190 if (bb_stack)
2191 free (bb_stack);
2193 if (bb_hashbuckets)
2195 int i;
2197 for (i = 0; i < BB_BUCKETS; i++)
2199 struct bb_edge *old, *bucket = bb_hashbuckets[i];
2201 while (bucket)
2203 old = bucket;
2204 bucket = bucket->next;
2205 free (old);
2208 free (bb_hashbuckets);
2211 for (b = bb_head; b; b = b->next)
2212 if (b->flags) free (b->flags);
2215 /* Called once per program. */
2217 static void
2218 __bb_init_prg (void)
2220 FILE *file;
2221 char buf[BBINBUFSIZE];
2222 const char *p;
2223 const char *pos;
2224 enum bb_func_mode m;
2225 int i;
2227 /* Initialize destructor. */
2228 atexit (__bb_exit_func);
2230 if (!(file = fopen ("bb.in", "r")))
2231 return;
2233 while(fgets (buf, BBINBUFSIZE, file) != 0)
2235 i = strlen (buf);
2236 if (buf[i] == '\n')
2237 buf[i--] = '\0';
2239 p = buf;
2240 if (*p == '-')
2242 m = TRACE_OFF;
2243 p++;
2245 else
2247 m = TRACE_ON;
2249 if (!strcmp (p, "__bb_trace__"))
2250 bb_mode |= 1;
2251 else if (!strcmp (p, "__bb_jumps__"))
2252 bb_mode |= 2;
2253 else if (!strcmp (p, "__bb_hidecall__"))
2254 bb_mode |= 4;
2255 else if (!strcmp (p, "__bb_showret__"))
2256 bb_mode |= 8;
2257 else
2259 struct bb_func *f = (struct bb_func *) malloc (sizeof (struct bb_func));
2260 if (f)
2262 unsigned long l;
2263 f->next = bb_func_head;
2264 if ((pos = strchr (p, ':')))
2266 if (!(f->funcname = (char *) malloc (strlen (pos+1)+1)))
2267 continue;
2268 strcpy (f->funcname, pos+1);
2269 l = pos-p;
2270 if ((f->filename = (char *) malloc (l+1)))
2272 strncpy (f->filename, p, l);
2273 f->filename[l] = '\0';
2275 else
2276 f->filename = (char *) 0;
2278 else
2280 if (!(f->funcname = (char *) malloc (strlen (p)+1)))
2281 continue;
2282 strcpy (f->funcname, p);
2283 f->filename = (char *) 0;
2285 f->mode = m;
2286 bb_func_head = f;
2290 fclose (file);
2292 #ifdef HAVE_POPEN
2294 if (bb_mode & 1)
2295 bb_tracefile = gopen ("bbtrace.gz", "w");
2297 #else
2299 if (bb_mode & 1)
2300 bb_tracefile = fopen ("bbtrace", "w");
2302 #endif /* HAVE_POPEN */
2304 if (bb_mode & 2)
2306 bb_hashbuckets = (struct bb_edge **)
2307 malloc (BB_BUCKETS * sizeof (struct bb_edge *));
2308 if (bb_hashbuckets)
2309 /* Use a loop here rather than calling bzero to avoid having to
2310 conditionalize its existance. */
2311 for (i = 0; i < BB_BUCKETS; i++)
2312 bb_hashbuckets[i] = 0;
2315 if (bb_mode & 12)
2317 bb_stacksize = 10;
2318 bb_stack = (unsigned long *) malloc (bb_stacksize * sizeof (*bb_stack));
2321 /* Initialize destructor. */
2322 atexit (__bb_exit_trace_func);
2325 /* Called upon entering a basic block. */
2327 void
2328 __bb_trace_func (void)
2330 struct bb_edge *bucket;
2332 MACHINE_STATE_SAVE("1")
2334 if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2335 goto skip;
2337 bb_dst = __bb.blocks->addresses[__bb.blockno];
2338 __bb.blocks->counts[__bb.blockno]++;
2340 if (bb_tracefile)
2342 fwrite (&bb_dst, sizeof (unsigned long), 1, bb_tracefile);
2345 if (bb_hashbuckets)
2347 struct bb_edge **startbucket, **oldnext;
2349 oldnext = startbucket
2350 = & bb_hashbuckets[ (((int) bb_src*8) ^ (int) bb_dst) % BB_BUCKETS ];
2351 bucket = *startbucket;
2353 for (bucket = *startbucket; bucket;
2354 oldnext = &(bucket->next), bucket = *oldnext)
2356 if (bucket->src_addr == bb_src
2357 && bucket->dst_addr == bb_dst)
2359 bucket->count++;
2360 *oldnext = bucket->next;
2361 bucket->next = *startbucket;
2362 *startbucket = bucket;
2363 goto ret;
2367 bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2369 if (!bucket)
2371 if (!reported)
2373 fprintf (stderr, "Profiler: out of memory\n");
2374 reported = 1;
2378 else
2380 bucket->src_addr = bb_src;
2381 bucket->dst_addr = bb_dst;
2382 bucket->next = *startbucket;
2383 *startbucket = bucket;
2384 bucket->count = 1;
2388 ret:
2389 bb_src = bb_dst;
2391 skip:
2394 MACHINE_STATE_RESTORE("1")
2398 /* Called when returning from a function and `__bb_showret__' is set. */
2400 static void
2401 __bb_trace_func_ret (void)
2403 struct bb_edge *bucket;
2405 if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2406 goto skip;
2408 if (bb_hashbuckets)
2410 struct bb_edge **startbucket, **oldnext;
2412 oldnext = startbucket
2413 = & bb_hashbuckets[ (((int) bb_dst * 8) ^ (int) bb_src) % BB_BUCKETS ];
2414 bucket = *startbucket;
2416 for (bucket = *startbucket; bucket;
2417 oldnext = &(bucket->next), bucket = *oldnext)
2419 if (bucket->src_addr == bb_dst
2420 && bucket->dst_addr == bb_src)
2422 bucket->count++;
2423 *oldnext = bucket->next;
2424 bucket->next = *startbucket;
2425 *startbucket = bucket;
2426 goto ret;
2430 bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2432 if (!bucket)
2434 if (!reported)
2436 fprintf (stderr, "Profiler: out of memory\n");
2437 reported = 1;
2441 else
2443 bucket->src_addr = bb_dst;
2444 bucket->dst_addr = bb_src;
2445 bucket->next = *startbucket;
2446 *startbucket = bucket;
2447 bucket->count = 1;
2451 ret:
2452 bb_dst = bb_src;
2454 skip:
2459 /* Called upon entering the first function of a file. */
2461 static void
2462 __bb_init_file (struct bb *blocks)
2465 const struct bb_func *p;
2466 long blk, ncounts = blocks->ncounts;
2467 const char **functions = blocks->functions;
2469 /* Set up linked list. */
2470 blocks->zero_word = 1;
2471 blocks->next = bb_head;
2472 bb_head = blocks;
2474 blocks->flags = 0;
2475 if (!bb_func_head
2476 || !(blocks->flags = (char *) malloc (sizeof (char) * blocks->ncounts)))
2477 return;
2479 for (blk = 0; blk < ncounts; blk++)
2480 blocks->flags[blk] = 0;
2482 for (blk = 0; blk < ncounts; blk++)
2484 for (p = bb_func_head; p; p = p->next)
2486 if (!strcmp (p->funcname, functions[blk])
2487 && (!p->filename || !strcmp (p->filename, blocks->filename)))
2489 blocks->flags[blk] |= p->mode;
2496 /* Called when exiting from a function. */
2498 void
2499 __bb_trace_ret (void)
2502 MACHINE_STATE_SAVE("2")
2504 if (bb_callcount)
2506 if ((bb_mode & 12) && bb_stacksize > bb_callcount)
2508 bb_src = bb_stack[bb_callcount];
2509 if (bb_mode & 8)
2510 __bb_trace_func_ret ();
2513 bb_callcount -= 1;
2516 MACHINE_STATE_RESTORE("2")
2520 /* Called when entering a function. */
2522 void
2523 __bb_init_trace_func (struct bb *blocks, unsigned long blockno)
2525 static int trace_init = 0;
2527 MACHINE_STATE_SAVE("3")
2529 if (!blocks->zero_word)
2531 if (!trace_init)
2533 trace_init = 1;
2534 __bb_init_prg ();
2536 __bb_init_file (blocks);
2539 if (bb_callcount)
2542 bb_callcount += 1;
2544 if (bb_mode & 12)
2546 if (bb_callcount >= bb_stacksize)
2548 size_t newsize = bb_callcount + 100;
2550 bb_stack = (unsigned long *) realloc (bb_stack, newsize);
2551 if (! bb_stack)
2553 if (!reported)
2555 fprintf (stderr, "Profiler: out of memory\n");
2556 reported = 1;
2558 bb_stacksize = 0;
2559 goto stack_overflow;
2561 bb_stacksize = newsize;
2563 bb_stack[bb_callcount] = bb_src;
2565 if (bb_mode & 4)
2566 bb_src = 0;
2570 stack_overflow:;
2574 else if (blocks->flags && (blocks->flags[blockno] & TRACE_ON))
2576 bb_callcount = 1;
2577 bb_src = 0;
2579 if (bb_stack)
2580 bb_stack[bb_callcount] = bb_src;
2583 MACHINE_STATE_RESTORE("3")
2586 #endif /* not inhibit_libc */
2587 #endif /* not BLOCK_PROFILER_CODE */
2588 #endif /* L_bb */
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 __attribute__((__unused__)),
2610 char *end __attribute__((__unused__)))
2612 #ifdef CLEAR_INSN_CACHE
2613 CLEAR_INSN_CACHE (beg, end);
2614 #else
2615 #ifdef INSN_CACHE_SIZE
2616 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
2617 static int initialized;
2618 int offset;
2619 void *start_addr
2620 void *end_addr;
2621 typedef (*function_ptr) (void);
2623 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
2624 /* It's cheaper to clear the whole cache.
2625 Put in a series of jump instructions so that calling the beginning
2626 of the cache will clear the whole thing. */
2628 if (! initialized)
2630 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2631 & -INSN_CACHE_LINE_WIDTH);
2632 int end_ptr = ptr + INSN_CACHE_SIZE;
2634 while (ptr < end_ptr)
2636 *(INSTRUCTION_TYPE *)ptr
2637 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
2638 ptr += INSN_CACHE_LINE_WIDTH;
2640 *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
2642 initialized = 1;
2645 /* Call the beginning of the sequence. */
2646 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2647 & -INSN_CACHE_LINE_WIDTH))
2648 ());
2650 #else /* Cache is large. */
2652 if (! initialized)
2654 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2655 & -INSN_CACHE_LINE_WIDTH);
2657 while (ptr < (int) array + sizeof array)
2659 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
2660 ptr += INSN_CACHE_LINE_WIDTH;
2663 initialized = 1;
2666 /* Find the location in array that occupies the same cache line as BEG. */
2668 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
2669 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
2670 & -INSN_CACHE_PLANE_SIZE)
2671 + offset);
2673 /* Compute the cache alignment of the place to stop clearing. */
2674 #if 0 /* This is not needed for gcc's purposes. */
2675 /* If the block to clear is bigger than a cache plane,
2676 we clear the entire cache, and OFFSET is already correct. */
2677 if (end < beg + INSN_CACHE_PLANE_SIZE)
2678 #endif
2679 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
2680 & -INSN_CACHE_LINE_WIDTH)
2681 & (INSN_CACHE_PLANE_SIZE - 1));
2683 #if INSN_CACHE_DEPTH > 1
2684 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
2685 if (end_addr <= start_addr)
2686 end_addr += INSN_CACHE_PLANE_SIZE;
2688 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
2690 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
2691 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
2693 while (addr != stop)
2695 /* Call the return instruction at ADDR. */
2696 ((function_ptr) addr) ();
2698 addr += INSN_CACHE_LINE_WIDTH;
2701 #else /* just one plane */
2704 /* Call the return instruction at START_ADDR. */
2705 ((function_ptr) start_addr) ();
2707 start_addr += INSN_CACHE_LINE_WIDTH;
2709 while ((start_addr % INSN_CACHE_SIZE) != offset);
2710 #endif /* just one plane */
2711 #endif /* Cache is large */
2712 #endif /* Cache exists */
2713 #endif /* CLEAR_INSN_CACHE */
2716 #endif /* L_clear_cache */
2718 #ifdef L_trampoline
2720 /* Jump to a trampoline, loading the static chain address. */
2722 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
2724 long
2725 getpagesize (void)
2727 #ifdef _ALPHA_
2728 return 8192;
2729 #else
2730 return 4096;
2731 #endif
2734 #ifdef __i386__
2735 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
2736 #endif
2739 mprotect (char *addr, int len, int prot)
2741 int np, op;
2743 if (prot == 7)
2744 np = 0x40;
2745 else if (prot == 5)
2746 np = 0x20;
2747 else if (prot == 4)
2748 np = 0x10;
2749 else if (prot == 3)
2750 np = 0x04;
2751 else if (prot == 1)
2752 np = 0x02;
2753 else if (prot == 0)
2754 np = 0x01;
2756 if (VirtualProtect (addr, len, np, &op))
2757 return 0;
2758 else
2759 return -1;
2762 #endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
2764 #ifdef TRANSFER_FROM_TRAMPOLINE
2765 TRANSFER_FROM_TRAMPOLINE
2766 #endif
2768 #if defined (NeXT) && defined (__MACH__)
2770 /* Make stack executable so we can call trampolines on stack.
2771 This is called from INITIALIZE_TRAMPOLINE in next.h. */
2772 #ifdef NeXTStep21
2773 #include <mach.h>
2774 #else
2775 #include <mach/mach.h>
2776 #endif
2778 void
2779 __enable_execute_stack (char *addr)
2781 kern_return_t r;
2782 char *eaddr = addr + TRAMPOLINE_SIZE;
2783 vm_address_t a = (vm_address_t) addr;
2785 /* turn on execute access on stack */
2786 r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
2787 if (r != KERN_SUCCESS)
2789 mach_error("vm_protect VM_PROT_ALL", r);
2790 exit(1);
2793 /* We inline the i-cache invalidation for speed */
2795 #ifdef CLEAR_INSN_CACHE
2796 CLEAR_INSN_CACHE (addr, eaddr);
2797 #else
2798 __clear_cache ((int) addr, (int) eaddr);
2799 #endif
2802 #endif /* defined (NeXT) && defined (__MACH__) */
2804 #ifdef __convex__
2806 /* Make stack executable so we can call trampolines on stack.
2807 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
2809 #include <sys/mman.h>
2810 #include <sys/vmparam.h>
2811 #include <machine/machparam.h>
2813 void
2814 __enable_execute_stack (void)
2816 int fp;
2817 static unsigned lowest = USRSTACK;
2818 unsigned current = (unsigned) &fp & -NBPG;
2820 if (lowest > current)
2822 unsigned len = lowest - current;
2823 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
2824 lowest = current;
2827 /* Clear instruction cache in case an old trampoline is in it. */
2828 asm ("pich");
2830 #endif /* __convex__ */
2832 #ifdef __sysV88__
2834 /* Modified from the convex -code above. */
2836 #include <sys/param.h>
2837 #include <errno.h>
2838 #include <sys/m88kbcs.h>
2840 void
2841 __enable_execute_stack (void)
2843 int save_errno;
2844 static unsigned long lowest = USRSTACK;
2845 unsigned long current = (unsigned long) &save_errno & -NBPC;
2847 /* Ignore errno being set. memctl sets errno to EINVAL whenever the
2848 address is seen as 'negative'. That is the case with the stack. */
2850 save_errno=errno;
2851 if (lowest > current)
2853 unsigned len=lowest-current;
2854 memctl(current,len,MCT_TEXT);
2855 lowest = current;
2857 else
2858 memctl(current,NBPC,MCT_TEXT);
2859 errno=save_errno;
2862 #endif /* __sysV88__ */
2864 #ifdef __sysV68__
2866 #include <sys/signal.h>
2867 #include <errno.h>
2869 /* Motorola forgot to put memctl.o in the libp version of libc881.a,
2870 so define it here, because we need it in __clear_insn_cache below */
2871 /* On older versions of this OS, no memctl or MCT_TEXT are defined;
2872 hence we enable this stuff only if MCT_TEXT is #define'd. */
2874 #ifdef MCT_TEXT
2875 asm("\n\
2876 global memctl\n\
2877 memctl:\n\
2878 movq &75,%d0\n\
2879 trap &0\n\
2880 bcc.b noerror\n\
2881 jmp cerror%\n\
2882 noerror:\n\
2883 movq &0,%d0\n\
2884 rts");
2885 #endif
2887 /* Clear instruction cache so we can call trampolines on stack.
2888 This is called from FINALIZE_TRAMPOLINE in mot3300.h. */
2890 void
2891 __clear_insn_cache (void)
2893 #ifdef MCT_TEXT
2894 int save_errno;
2896 /* Preserve errno, because users would be surprised to have
2897 errno changing without explicitly calling any system-call. */
2898 save_errno = errno;
2900 /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache.
2901 No need to use an address derived from _start or %sp, as 0 works also. */
2902 memctl(0, 4096, MCT_TEXT);
2903 errno = save_errno;
2904 #endif
2907 #endif /* __sysV68__ */
2909 #ifdef __pyr__
2911 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2912 #include <stdio.h>
2913 #include <sys/mman.h>
2914 #include <sys/types.h>
2915 #include <sys/param.h>
2916 #include <sys/vmmac.h>
2918 /* Modified from the convex -code above.
2919 mremap promises to clear the i-cache. */
2921 void
2922 __enable_execute_stack (void)
2924 int fp;
2925 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
2926 PROT_READ|PROT_WRITE|PROT_EXEC))
2928 perror ("mprotect in __enable_execute_stack");
2929 fflush (stderr);
2930 abort ();
2933 #endif /* __pyr__ */
2935 #if defined (sony_news) && defined (SYSTYPE_BSD)
2937 #include <stdio.h>
2938 #include <sys/types.h>
2939 #include <sys/param.h>
2940 #include <syscall.h>
2941 #include <machine/sysnews.h>
2943 /* cacheflush function for NEWS-OS 4.2.
2944 This function is called from trampoline-initialize code
2945 defined in config/mips/mips.h. */
2947 void
2948 cacheflush (char *beg, int size, int flag)
2950 if (syscall (SYS_sysnews, NEWS_CACHEFLUSH, beg, size, FLUSH_BCACHE))
2952 perror ("cache_flush");
2953 fflush (stderr);
2954 abort ();
2958 #endif /* sony_news */
2959 #endif /* L_trampoline */
2961 #ifndef __CYGWIN__
2962 #ifdef L__main
2964 #include "gbl-ctors.h"
2965 /* Some systems use __main in a way incompatible with its use in gcc, in these
2966 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2967 give the same symbol without quotes for an alternative entry point. You
2968 must define both, or neither. */
2969 #ifndef NAME__MAIN
2970 #define NAME__MAIN "__main"
2971 #define SYMBOL__MAIN __main
2972 #endif
2974 #ifdef INIT_SECTION_ASM_OP
2975 #undef HAS_INIT_SECTION
2976 #define HAS_INIT_SECTION
2977 #endif
2979 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
2981 /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
2982 code to run constructors. In that case, we need to handle EH here, too. */
2984 #ifdef EH_FRAME_SECTION
2985 #include "frame.h"
2986 extern unsigned char __EH_FRAME_BEGIN__[];
2987 #endif
2989 /* Run all the global destructors on exit from the program. */
2991 void
2992 __do_global_dtors (void)
2994 #ifdef DO_GLOBAL_DTORS_BODY
2995 DO_GLOBAL_DTORS_BODY;
2996 #else
2997 static func_ptr *p = __DTOR_LIST__ + 1;
2998 while (*p)
3000 p++;
3001 (*(p-1)) ();
3003 #endif
3004 #if defined (EH_FRAME_SECTION) && !defined (HAS_INIT_SECTION)
3006 static int completed = 0;
3007 if (! completed)
3009 completed = 1;
3010 __deregister_frame_info (__EH_FRAME_BEGIN__);
3013 #endif
3015 #endif
3017 #ifndef HAS_INIT_SECTION
3018 /* Run all the global constructors on entry to the program. */
3020 void
3021 __do_global_ctors (void)
3023 #ifdef EH_FRAME_SECTION
3025 static struct object object;
3026 __register_frame_info (__EH_FRAME_BEGIN__, &object);
3028 #endif
3029 DO_GLOBAL_CTORS_BODY;
3030 atexit (__do_global_dtors);
3032 #endif /* no HAS_INIT_SECTION */
3034 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
3035 /* Subroutine called automatically by `main'.
3036 Compiling a global function named `main'
3037 produces an automatic call to this function at the beginning.
3039 For many systems, this routine calls __do_global_ctors.
3040 For systems which support a .init section we use the .init section
3041 to run __do_global_ctors, so we need not do anything here. */
3043 void
3044 SYMBOL__MAIN ()
3046 /* Support recursive calls to `main': run initializers just once. */
3047 static int initialized;
3048 if (! initialized)
3050 initialized = 1;
3051 __do_global_ctors ();
3054 #endif /* no HAS_INIT_SECTION or INVOKE__main */
3056 #endif /* L__main */
3057 #endif /* __CYGWIN__ */
3059 #ifdef L_ctors
3061 #include "gbl-ctors.h"
3063 /* Provide default definitions for the lists of constructors and
3064 destructors, so that we don't get linker errors. These symbols are
3065 intentionally bss symbols, so that gld and/or collect will provide
3066 the right values. */
3068 /* We declare the lists here with two elements each,
3069 so that they are valid empty lists if no other definition is loaded.
3071 If we are using the old "set" extensions to have the gnu linker
3072 collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
3073 must be in the bss/common section.
3075 Long term no port should use those extensions. But many still do. */
3076 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
3077 #if defined (ASM_OUTPUT_CONSTRUCTOR) || defined (USE_COLLECT2)
3078 func_ptr __CTOR_LIST__[2] = {0, 0};
3079 func_ptr __DTOR_LIST__[2] = {0, 0};
3080 #else
3081 func_ptr __CTOR_LIST__[2];
3082 func_ptr __DTOR_LIST__[2];
3083 #endif
3084 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
3085 #endif /* L_ctors */
3087 #ifdef L_exit
3089 #include "gbl-ctors.h"
3091 #ifdef NEED_ATEXIT
3093 #ifndef ON_EXIT
3095 # include <errno.h>
3097 static func_ptr *atexit_chain = 0;
3098 static long atexit_chain_length = 0;
3099 static volatile long last_atexit_chain_slot = -1;
3102 atexit (func_ptr func)
3104 if (++last_atexit_chain_slot == atexit_chain_length)
3106 atexit_chain_length += 32;
3107 if (atexit_chain)
3108 atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
3109 * sizeof (func_ptr));
3110 else
3111 atexit_chain = (func_ptr *) malloc (atexit_chain_length
3112 * sizeof (func_ptr));
3113 if (! atexit_chain)
3115 atexit_chain_length = 0;
3116 last_atexit_chain_slot = -1;
3117 errno = ENOMEM;
3118 return (-1);
3121 atexit_chain[last_atexit_chain_slot] = func;
3122 return (0);
3125 extern void _cleanup (void);
3126 extern void _exit (int) __attribute__ ((__noreturn__));
3128 void
3129 exit (int status)
3131 if (atexit_chain)
3133 for ( ; last_atexit_chain_slot-- >= 0; )
3135 (*atexit_chain[last_atexit_chain_slot + 1]) ();
3136 atexit_chain[last_atexit_chain_slot + 1] = 0;
3138 free (atexit_chain);
3139 atexit_chain = 0;
3141 #ifdef EXIT_BODY
3142 EXIT_BODY;
3143 #else
3144 _cleanup ();
3145 #endif
3146 _exit (status);
3149 #else /* ON_EXIT */
3151 /* Simple; we just need a wrapper for ON_EXIT. */
3153 atexit (func_ptr func)
3155 return ON_EXIT (func);
3158 #endif /* ON_EXIT */
3159 #endif /* NEED_ATEXIT */
3161 #endif /* L_exit */
3163 #ifdef L_eh
3165 #include "gthr.h"
3167 /* Shared exception handling support routines. */
3169 extern void __default_terminate (void) __attribute__ ((__noreturn__));
3171 void
3172 __default_terminate (void)
3174 abort ();
3177 void (*__terminate_func)(void) __attribute__ ((__noreturn__)) =
3178 __default_terminate;
3180 void
3181 __terminate (void)
3183 (*__terminate_func)();
3186 void *
3187 __throw_type_match (void *catch_type, void *throw_type, void *obj)
3189 #if 0
3190 printf ("__throw_type_match (): catch_type = %s, throw_type = %s\n",
3191 catch_type, throw_type);
3192 #endif
3193 if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)
3194 return obj;
3195 return 0;
3198 void
3199 __empty (void)
3204 /* Include definitions of EH context and table layout */
3206 #include "eh-common.h"
3207 #ifndef inhibit_libc
3208 #include <stdio.h>
3209 #endif
3211 /* Allocate and return a new EH context structure. */
3213 extern void __throw (void);
3215 #if __GTHREADS
3216 static void *
3217 new_eh_context (void)
3219 struct eh_full_context {
3220 struct eh_context c;
3221 void *top_elt[2];
3222 } *ehfc = (struct eh_full_context *) malloc (sizeof *ehfc);
3224 if (! ehfc)
3225 __terminate ();
3227 memset (ehfc, 0, sizeof *ehfc);
3229 ehfc->c.dynamic_handler_chain = (void **) ehfc->top_elt;
3231 /* This should optimize out entirely. This should always be true,
3232 but just in case it ever isn't, don't allow bogus code to be
3233 generated. */
3235 if ((void*)(&ehfc->c) != (void*)ehfc)
3236 __terminate ();
3238 return &ehfc->c;
3241 static __gthread_key_t eh_context_key;
3243 /* Destructor for struct eh_context. */
3244 static void
3245 eh_context_free (void *ptr)
3247 __gthread_key_dtor (eh_context_key, ptr);
3248 if (ptr)
3249 free (ptr);
3251 #endif
3253 /* Pointer to function to return EH context. */
3255 static struct eh_context *eh_context_initialize (void);
3256 static struct eh_context *eh_context_static (void);
3257 #if __GTHREADS
3258 static struct eh_context *eh_context_specific (void);
3259 #endif
3261 static struct eh_context *(*get_eh_context) (void) = &eh_context_initialize;
3263 /* Routine to get EH context.
3264 This one will simply call the function pointer. */
3266 void *
3267 __get_eh_context (void)
3269 return (void *) (*get_eh_context) ();
3272 /* Get and set the language specific info pointer. */
3274 void **
3275 __get_eh_info (void)
3277 struct eh_context *eh = (*get_eh_context) ();
3278 return &eh->info;
3281 #ifdef DWARF2_UNWIND_INFO
3282 static int dwarf_reg_size_table_initialized = 0;
3283 static char dwarf_reg_size_table[DWARF_FRAME_REGISTERS];
3285 static void
3286 init_reg_size_table (void)
3288 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
3289 dwarf_reg_size_table_initialized = 1;
3291 #endif
3293 #if __GTHREADS
3294 static void
3295 eh_threads_initialize (void)
3297 /* Try to create the key. If it fails, revert to static method,
3298 otherwise start using thread specific EH contexts. */
3299 if (__gthread_key_create (&eh_context_key, &eh_context_free) == 0)
3300 get_eh_context = &eh_context_specific;
3301 else
3302 get_eh_context = &eh_context_static;
3304 #endif /* no __GTHREADS */
3306 /* Initialize EH context.
3307 This will be called only once, since we change GET_EH_CONTEXT
3308 pointer to another routine. */
3310 static struct eh_context *
3311 eh_context_initialize (void)
3313 #if __GTHREADS
3315 static __gthread_once_t once = __GTHREAD_ONCE_INIT;
3316 /* Make sure that get_eh_context does not point to us anymore.
3317 Some systems have dummy thread routines in their libc that
3318 return a success (Solaris 2.6 for example). */
3319 if (__gthread_once (&once, eh_threads_initialize) != 0
3320 || get_eh_context == &eh_context_initialize)
3322 /* Use static version of EH context. */
3323 get_eh_context = &eh_context_static;
3325 #ifdef DWARF2_UNWIND_INFO
3327 static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
3328 if (__gthread_once (&once_regsizes, init_reg_size_table) != 0
3329 || ! dwarf_reg_size_table_initialized)
3330 init_reg_size_table ();
3332 #endif
3334 #else /* no __GTHREADS */
3336 /* Use static version of EH context. */
3337 get_eh_context = &eh_context_static;
3339 #ifdef DWARF2_UNWIND_INFO
3340 init_reg_size_table ();
3341 #endif
3343 #endif /* no __GTHREADS */
3345 return (*get_eh_context) ();
3348 /* Return a static EH context. */
3350 static struct eh_context *
3351 eh_context_static (void)
3353 static struct eh_context eh;
3354 static int initialized;
3355 static void *top_elt[2];
3357 if (! initialized)
3359 initialized = 1;
3360 memset (&eh, 0, sizeof eh);
3361 eh.dynamic_handler_chain = top_elt;
3363 return &eh;
3366 #if __GTHREADS
3367 /* Return a thread specific EH context. */
3369 static struct eh_context *
3370 eh_context_specific (void)
3372 struct eh_context *eh;
3373 eh = (struct eh_context *) __gthread_getspecific (eh_context_key);
3374 if (! eh)
3376 eh = new_eh_context ();
3377 if (__gthread_setspecific (eh_context_key, (void *) eh) != 0)
3378 __terminate ();
3381 return eh;
3383 #endif __GTHREADS
3385 /* Support routines for setjmp/longjmp exception handling. */
3387 /* Calls to __sjthrow are generated by the compiler when an exception
3388 is raised when using the setjmp/longjmp exception handling codegen
3389 method. */
3391 #ifdef DONT_USE_BUILTIN_SETJMP
3392 extern void longjmp (void *, int);
3393 #endif
3395 /* Routine to get the head of the current thread's dynamic handler chain
3396 use for exception handling. */
3398 void ***
3399 __get_dynamic_handler_chain (void)
3401 struct eh_context *eh = (*get_eh_context) ();
3402 return &eh->dynamic_handler_chain;
3405 /* This is used to throw an exception when the setjmp/longjmp codegen
3406 method is used for exception handling.
3408 We call __terminate if there are no handlers left. Otherwise we run the
3409 cleanup actions off the dynamic cleanup stack, and pop the top of the
3410 dynamic handler chain, and use longjmp to transfer back to the associated
3411 handler. */
3413 extern void __sjthrow (void) __attribute__ ((__noreturn__));
3415 void
3416 __sjthrow (void)
3418 struct eh_context *eh = (*get_eh_context) ();
3419 void ***dhc = &eh->dynamic_handler_chain;
3420 void *jmpbuf;
3421 void (*func)(void *, int);
3422 void *arg;
3423 /* The cleanup chain is one word into the buffer. Get the cleanup chain. */
3424 void ***cleanup = (void***)&(*dhc)[1];
3426 /* If there are any cleanups in the chain, run them now. */
3427 if (cleanup[0])
3429 double store[200];
3430 void **buf = (void**)store;
3431 buf[1] = 0;
3432 buf[0] = (*dhc);
3434 /* try { */
3435 #ifdef DONT_USE_BUILTIN_SETJMP
3436 if (! setjmp (&buf[2]))
3437 #else
3438 if (! __builtin_setjmp (&buf[2]))
3439 #endif
3441 *dhc = buf;
3442 while (cleanup[0])
3444 func = (void(*)(void*, int))cleanup[0][1];
3445 arg = (void*)cleanup[0][2];
3447 /* Update this before running the cleanup. */
3448 cleanup[0] = (void **)cleanup[0][0];
3450 (*func)(arg, 2);
3452 *dhc = buf[0];
3454 /* catch (...) */
3455 else
3457 __terminate ();
3461 /* We must call terminate if we try and rethrow an exception, when
3462 there is no exception currently active and when there are no
3463 handlers left. */
3464 if (! eh->info || (*dhc)[0] == 0)
3465 __terminate ();
3467 /* Find the jmpbuf associated with the top element of the dynamic
3468 handler chain. The jumpbuf starts two words into the buffer. */
3469 jmpbuf = &(*dhc)[2];
3471 /* Then we pop the top element off the dynamic handler chain. */
3472 *dhc = (void**)(*dhc)[0];
3474 /* And then we jump to the handler. */
3476 #ifdef DONT_USE_BUILTIN_SETJMP
3477 longjmp (jmpbuf, 1);
3478 #else
3479 __builtin_longjmp (jmpbuf, 1);
3480 #endif
3483 /* Run cleanups on the dynamic cleanup stack for the current dynamic
3484 handler, then pop the handler off the dynamic handler stack, and
3485 then throw. This is used to skip the first handler, and transfer
3486 control to the next handler in the dynamic handler stack. */
3488 extern void __sjpopnthrow (void) __attribute__ ((__noreturn__));
3490 void
3491 __sjpopnthrow (void)
3493 struct eh_context *eh = (*get_eh_context) ();
3494 void ***dhc = &eh->dynamic_handler_chain;
3495 void (*func)(void *, int);
3496 void *arg;
3497 /* The cleanup chain is one word into the buffer. Get the cleanup chain. */
3498 void ***cleanup = (void***)&(*dhc)[1];
3500 /* If there are any cleanups in the chain, run them now. */
3501 if (cleanup[0])
3503 double store[200];
3504 void **buf = (void**)store;
3505 buf[1] = 0;
3506 buf[0] = (*dhc);
3508 /* try { */
3509 #ifdef DONT_USE_BUILTIN_SETJMP
3510 if (! setjmp (&buf[2]))
3511 #else
3512 if (! __builtin_setjmp (&buf[2]))
3513 #endif
3515 *dhc = buf;
3516 while (cleanup[0])
3518 func = (void(*)(void*, int))cleanup[0][1];
3519 arg = (void*)cleanup[0][2];
3521 /* Update this before running the cleanup. */
3522 cleanup[0] = (void **)cleanup[0][0];
3524 (*func)(arg, 2);
3526 *dhc = buf[0];
3528 /* catch (...) */
3529 else
3531 __terminate ();
3535 /* Then we pop the top element off the dynamic handler chain. */
3536 *dhc = (void**)(*dhc)[0];
3538 __sjthrow ();
3541 /* Support code for all exception region-based exception handling. */
3544 __eh_rtime_match (void *rtime)
3546 void *info;
3547 __eh_matcher matcher;
3548 void *ret;
3550 info = *(__get_eh_info ());
3551 matcher = ((__eh_info *)info)->match_function;
3552 if (! matcher)
3554 #ifndef inhibit_libc
3555 fprintf (stderr, "Internal Compiler Bug: No runtime type matcher.");
3556 #endif
3557 return 0;
3559 ret = (*matcher) (info, rtime, (void *)0);
3560 return (ret != NULL);
3563 /* This value identifies the place from which an exception is being
3564 thrown. */
3566 #ifdef EH_TABLE_LOOKUP
3568 EH_TABLE_LOOKUP
3570 #else
3572 #ifdef DWARF2_UNWIND_INFO
3574 /* Return the table version of an exception descriptor */
3576 short
3577 __get_eh_table_version (exception_descriptor *table)
3579 return table->lang.version;
3582 /* Return the originating table language of an exception descriptor */
3584 short
3585 __get_eh_table_language (exception_descriptor *table)
3587 return table->lang.language;
3590 /* This routine takes a PC and a pointer to the exception region TABLE for
3591 its translation unit, and returns the address of the exception handler
3592 associated with the closest exception table handler entry associated
3593 with that PC, or 0 if there are no table entries the PC fits in.
3595 In the advent of a tie, we have to give the last entry, as it represents
3596 an inner block. */
3598 static void *
3599 old_find_exception_handler (void *pc, old_exception_table *table)
3601 if (table)
3603 int pos;
3604 int best = -1;
3606 /* We can't do a binary search because the table isn't guaranteed
3607 to be sorted from function to function. */
3608 for (pos = 0; table[pos].start_region != (void *) -1; ++pos)
3610 if (table[pos].start_region <= pc && table[pos].end_region > pc)
3612 /* This can apply. Make sure it is at least as small as
3613 the previous best. */
3614 if (best == -1 || (table[pos].end_region <= table[best].end_region
3615 && table[pos].start_region >= table[best].start_region))
3616 best = pos;
3618 /* But it is sorted by starting PC within a function. */
3619 else if (best >= 0 && table[pos].start_region > pc)
3620 break;
3622 if (best != -1)
3623 return table[best].exception_handler;
3626 return (void *) 0;
3629 /* find_exception_handler finds the correct handler, if there is one, to
3630 handle an exception.
3631 returns a pointer to the handler which controlled should be transferred
3632 to, or NULL if there is nothing left.
3633 Parameters:
3634 PC - pc where the exception originates. If this is a rethrow,
3635 then this starts out as a pointer to the exception table
3636 entry we wish to rethrow out of.
3637 TABLE - exception table for the current module.
3638 EH_INFO - eh info pointer for this exception.
3639 RETHROW - 1 if this is a rethrow. (see incoming value of PC).
3640 CLEANUP - returned flag indicating whether this is a cleanup handler.
3642 static void *
3643 find_exception_handler (void *pc, exception_descriptor *table,
3644 __eh_info *eh_info, int rethrow, int *cleanup)
3647 void *retval = NULL;
3648 *cleanup = 1;
3649 if (table)
3651 int pos = 0;
3652 /* The new model assumed the table is sorted inner-most out so the
3653 first region we find which matches is the correct one */
3655 exception_table *tab = &(table->table[0]);
3657 /* Subtract 1 from the PC to avoid hitting the next region */
3658 if (rethrow)
3660 /* pc is actually the region table entry to rethrow out of */
3661 pos = ((exception_table *) pc) - tab;
3662 pc = ((exception_table *) pc)->end_region - 1;
3664 /* The label is always on the LAST handler entry for a region,
3665 so we know the next entry is a different region, even if the
3666 addresses are the same. Make sure its not end of table tho. */
3667 if (tab[pos].start_region != (void *) -1)
3668 pos++;
3670 else
3671 pc--;
3673 /* We can't do a binary search because the table is in inner-most
3674 to outermost address ranges within functions */
3675 for ( ; tab[pos].start_region != (void *) -1; pos++)
3677 if (tab[pos].start_region <= pc && tab[pos].end_region > pc)
3679 if (tab[pos].match_info)
3681 __eh_matcher matcher = eh_info->match_function;
3682 /* match info but no matcher is NOT a match */
3683 if (matcher)
3685 void *ret = (*matcher)((void *) eh_info,
3686 tab[pos].match_info, table);
3687 if (ret)
3689 if (retval == NULL)
3690 retval = tab[pos].exception_handler;
3691 *cleanup = 0;
3692 break;
3696 else
3698 if (retval == NULL)
3699 retval = tab[pos].exception_handler;
3704 return retval;
3706 #endif /* DWARF2_UNWIND_INFO */
3707 #endif /* EH_TABLE_LOOKUP */
3709 #ifdef DWARF2_UNWIND_INFO
3710 /* Support code for exception handling using static unwind information. */
3712 #include "frame.h"
3714 /* This type is used in get_reg and put_reg to deal with ABIs where a void*
3715 is smaller than a word, such as the Irix 6 n32 ABI. We cast twice to
3716 avoid a warning about casting between int and pointer of different
3717 sizes. */
3719 typedef int ptr_type __attribute__ ((mode (pointer)));
3721 #ifdef INCOMING_REGNO
3722 /* Is the saved value for register REG in frame UDATA stored in a register
3723 window in the previous frame? */
3725 /* ??? The Sparc INCOMING_REGNO references TARGET_FLAT. This allows us
3726 to use the macro here. One wonders, though, that perhaps TARGET_FLAT
3727 compiled functions won't work with the frame-unwind stuff here.
3728 Perhaps the entireity of in_reg_window should be conditional on having
3729 seen a DW_CFA_GNU_window_save? */
3730 #define target_flags 0
3732 static int
3733 in_reg_window (int reg, frame_state *udata)
3735 if (udata->saved[reg] == REG_SAVED_REG)
3736 return INCOMING_REGNO (reg) == reg;
3737 if (udata->saved[reg] != REG_SAVED_OFFSET)
3738 return 0;
3740 #ifdef STACK_GROWS_DOWNWARD
3741 return udata->reg_or_offset[reg] > 0;
3742 #else
3743 return udata->reg_or_offset[reg] < 0;
3744 #endif
3746 #else
3747 static inline int
3748 in_reg_window (int reg __attribute__ ((__unused__)),
3749 frame_state *udata __attribute__ ((__unused__)))
3751 return 0;
3753 #endif /* INCOMING_REGNO */
3755 /* Get the address of register REG as saved in UDATA, where SUB_UDATA is a
3756 frame called by UDATA or 0. */
3758 static word_type *
3759 get_reg_addr (unsigned reg, frame_state *udata, frame_state *sub_udata)
3761 while (udata->saved[reg] == REG_SAVED_REG)
3763 reg = udata->reg_or_offset[reg];
3764 if (in_reg_window (reg, udata))
3766 udata = sub_udata;
3767 sub_udata = NULL;
3770 if (udata->saved[reg] == REG_SAVED_OFFSET)
3771 return (word_type *)(udata->cfa + udata->reg_or_offset[reg]);
3772 else
3773 abort ();
3776 /* Get the value of register REG as saved in UDATA, where SUB_UDATA is a
3777 frame called by UDATA or 0. */
3779 static inline void *
3780 get_reg (unsigned reg, frame_state *udata, frame_state *sub_udata)
3782 return (void *)(ptr_type) *get_reg_addr (reg, udata, sub_udata);
3785 /* Overwrite the saved value for register REG in frame UDATA with VAL. */
3787 static inline void
3788 put_reg (unsigned reg, void *val, frame_state *udata)
3790 *get_reg_addr (reg, udata, NULL) = (word_type)(ptr_type) val;
3793 /* Copy the saved value for register REG from frame UDATA to frame
3794 TARGET_UDATA. Unlike the previous two functions, this can handle
3795 registers that are not one word large. */
3797 static void
3798 copy_reg (unsigned reg, frame_state *udata, frame_state *target_udata)
3800 word_type *preg = get_reg_addr (reg, udata, NULL);
3801 word_type *ptreg = get_reg_addr (reg, target_udata, NULL);
3803 memcpy (ptreg, preg, dwarf_reg_size_table [reg]);
3806 /* Retrieve the return address for frame UDATA. */
3808 static inline void *
3809 get_return_addr (frame_state *udata, frame_state *sub_udata)
3811 return __builtin_extract_return_addr
3812 (get_reg (udata->retaddr_column, udata, sub_udata));
3815 /* Overwrite the return address for frame UDATA with VAL. */
3817 static inline void
3818 put_return_addr (void *val, frame_state *udata)
3820 val = __builtin_frob_return_addr (val);
3821 put_reg (udata->retaddr_column, val, udata);
3824 /* Given the current frame UDATA and its return address PC, return the
3825 information about the calling frame in CALLER_UDATA. */
3827 static void *
3828 next_stack_level (void *pc, frame_state *udata, frame_state *caller_udata)
3830 caller_udata = __frame_state_for (pc, caller_udata);
3831 if (! caller_udata)
3832 return 0;
3834 /* Now go back to our caller's stack frame. If our caller's CFA register
3835 was saved in our stack frame, restore it; otherwise, assume the CFA
3836 register is SP and restore it to our CFA value. */
3837 if (udata->saved[caller_udata->cfa_reg])
3838 caller_udata->cfa = get_reg (caller_udata->cfa_reg, udata, 0);
3839 else
3840 caller_udata->cfa = udata->cfa;
3841 caller_udata->cfa += caller_udata->cfa_offset;
3843 return caller_udata;
3846 /* Hook to call before __terminate if only cleanup handlers remain. */
3847 void
3848 __unwinding_cleanup (void)
3852 /* throw_helper performs some of the common grunt work for a throw. This
3853 routine is called by throw and rethrows. This is pretty much split
3854 out from the old __throw routine. An addition has been added which allows
3855 for a dummy call to a routine __unwinding_cleanup() when there are nothing
3856 but cleanups remaining. This allows a debugger to examine the state
3857 at which the throw was executed, before any cleanups, rather than
3858 at the terminate point after the stack has been unwound.
3860 EH is the current eh_context structure.
3861 PC is the address of the call to __throw.
3862 MY_UDATA is the unwind information for __throw.
3863 OFFSET_P is where we return the SP adjustment offset. */
3865 static void *
3866 throw_helper (struct eh_context *eh, void *pc, frame_state *my_udata,
3867 long *offset_p)
3869 frame_state ustruct2, *udata = &ustruct2;
3870 frame_state ustruct;
3871 frame_state *sub_udata = &ustruct;
3872 void *saved_pc = pc;
3873 void *handler;
3874 void *handler_p = 0;
3875 void *pc_p = 0;
3876 frame_state saved_ustruct;
3877 int new_eh_model;
3878 int cleanup = 0;
3879 int only_cleanup = 0;
3880 int rethrow = 0;
3881 int saved_state = 0;
3882 long args_size;
3883 __eh_info *eh_info = (__eh_info *)eh->info;
3885 /* Do we find a handler based on a re-throw PC? */
3886 if (eh->table_index != (void *) 0)
3887 rethrow = 1;
3889 memcpy (udata, my_udata, sizeof (*udata));
3891 handler = (void *) 0;
3892 for (;;)
3894 frame_state *p = udata;
3895 udata = next_stack_level (pc, udata, sub_udata);
3896 sub_udata = p;
3898 /* If we couldn't find the next frame, we lose. */
3899 if (! udata)
3900 break;
3902 if (udata->eh_ptr == NULL)
3903 new_eh_model = 0;
3904 else
3905 new_eh_model = (((exception_descriptor *)(udata->eh_ptr))->
3906 runtime_id_field == NEW_EH_RUNTIME);
3908 if (rethrow)
3910 rethrow = 0;
3911 handler = find_exception_handler (eh->table_index, udata->eh_ptr,
3912 eh_info, 1, &cleanup);
3913 eh->table_index = (void *)0;
3915 else
3916 if (new_eh_model)
3917 handler = find_exception_handler (pc, udata->eh_ptr, eh_info,
3918 0, &cleanup);
3919 else
3920 handler = old_find_exception_handler (pc, udata->eh_ptr);
3922 /* If we found one, we can stop searching, if its not a cleanup.
3923 for cleanups, we save the state, and keep looking. This allows
3924 us to call a debug hook if there are nothing but cleanups left. */
3925 if (handler)
3927 if (cleanup)
3929 if (!saved_state)
3931 saved_ustruct = *udata;
3932 handler_p = handler;
3933 pc_p = pc;
3934 saved_state = 1;
3935 only_cleanup = 1;
3938 else
3940 only_cleanup = 0;
3941 break;
3945 /* Otherwise, we continue searching. We subtract 1 from PC to avoid
3946 hitting the beginning of the next region. */
3947 pc = get_return_addr (udata, sub_udata) - 1;
3950 if (saved_state)
3952 udata = &saved_ustruct;
3953 handler = handler_p;
3954 pc = pc_p;
3955 if (only_cleanup)
3956 __unwinding_cleanup ();
3959 /* If we haven't found a handler by now, this is an unhandled
3960 exception. */
3961 if (! handler)
3962 __terminate();
3964 eh->handler_label = handler;
3966 args_size = udata->args_size;
3968 if (pc == saved_pc)
3969 /* We found a handler in the throw context, no need to unwind. */
3970 udata = my_udata;
3971 else
3973 int i;
3975 /* Unwind all the frames between this one and the handler by copying
3976 their saved register values into our register save slots. */
3978 /* Remember the PC where we found the handler. */
3979 void *handler_pc = pc;
3981 /* Start from the throw context again. */
3982 pc = saved_pc;
3983 memcpy (udata, my_udata, sizeof (*udata));
3985 while (pc != handler_pc)
3987 frame_state *p = udata;
3988 udata = next_stack_level (pc, udata, sub_udata);
3989 sub_udata = p;
3991 for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
3992 if (i != udata->retaddr_column && udata->saved[i])
3994 /* If you modify the saved value of the return address
3995 register on the SPARC, you modify the return address for
3996 your caller's frame. Don't do that here, as it will
3997 confuse get_return_addr. */
3998 if (in_reg_window (i, udata)
3999 && udata->saved[udata->retaddr_column] == REG_SAVED_REG
4000 && udata->reg_or_offset[udata->retaddr_column] == i)
4001 continue;
4002 copy_reg (i, udata, my_udata);
4005 pc = get_return_addr (udata, sub_udata) - 1;
4008 /* But we do need to update the saved return address register from
4009 the last frame we unwind, or the handler frame will have the wrong
4010 return address. */
4011 if (udata->saved[udata->retaddr_column] == REG_SAVED_REG)
4013 i = udata->reg_or_offset[udata->retaddr_column];
4014 if (in_reg_window (i, udata))
4015 copy_reg (i, udata, my_udata);
4018 /* udata now refers to the frame called by the handler frame. */
4020 /* We adjust SP by the difference between __throw's CFA and the CFA for
4021 the frame called by the handler frame, because those CFAs correspond
4022 to the SP values at the two call sites. We need to further adjust by
4023 the args_size of the handler frame itself to get the handler frame's
4024 SP from before the args were pushed for that call. */
4025 #ifdef STACK_GROWS_DOWNWARD
4026 *offset_p = udata->cfa - my_udata->cfa + args_size;
4027 #else
4028 *offset_p = my_udata->cfa - udata->cfa - args_size;
4029 #endif
4031 return handler;
4035 /* We first search for an exception handler, and if we don't find
4036 it, we call __terminate on the current stack frame so that we may
4037 use the debugger to walk the stack and understand why no handler
4038 was found.
4040 If we find one, then we unwind the frames down to the one that
4041 has the handler and transfer control into the handler. */
4043 /*extern void __throw(void) __attribute__ ((__noreturn__));*/
4045 void
4046 __throw (void)
4048 struct eh_context *eh = (*get_eh_context) ();
4049 void *pc, *handler;
4050 long offset;
4052 /* XXX maybe make my_ustruct static so we don't have to look it up for
4053 each throw. */
4054 frame_state my_ustruct, *my_udata = &my_ustruct;
4056 /* This is required for C++ semantics. We must call terminate if we
4057 try and rethrow an exception, when there is no exception currently
4058 active. */
4059 if (! eh->info)
4060 __terminate ();
4062 /* Start at our stack frame. */
4063 label:
4064 my_udata = __frame_state_for (&&label, my_udata);
4065 if (! my_udata)
4066 __terminate ();
4068 /* We need to get the value from the CFA register. */
4069 my_udata->cfa = __builtin_dwarf_cfa ();
4071 /* Do any necessary initialization to access arbitrary stack frames.
4072 On the SPARC, this means flushing the register windows. */
4073 __builtin_unwind_init ();
4075 /* Now reset pc to the right throw point. */
4076 pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
4078 handler = throw_helper (eh, pc, my_udata, &offset);
4080 /* Now go! */
4082 __builtin_eh_return ((void *)eh, offset, handler);
4084 /* Epilogue: restore the handler frame's register values and return
4085 to the stub. */
4088 /*extern void __rethrow(void *) __attribute__ ((__noreturn__));*/
4090 void
4091 __rethrow (void *index)
4093 struct eh_context *eh = (*get_eh_context) ();
4094 void *pc, *handler;
4095 long offset;
4097 /* XXX maybe make my_ustruct static so we don't have to look it up for
4098 each throw. */
4099 frame_state my_ustruct, *my_udata = &my_ustruct;
4101 /* This is required for C++ semantics. We must call terminate if we
4102 try and rethrow an exception, when there is no exception currently
4103 active. */
4104 if (! eh->info)
4105 __terminate ();
4107 /* This is the table index we want to rethrow from. The value of
4108 the END_REGION label is used for the PC of the throw, and the
4109 search begins with the next table entry. */
4110 eh->table_index = index;
4112 /* Start at our stack frame. */
4113 label:
4114 my_udata = __frame_state_for (&&label, my_udata);
4115 if (! my_udata)
4116 __terminate ();
4118 /* We need to get the value from the CFA register. */
4119 my_udata->cfa = __builtin_dwarf_cfa ();
4121 /* Do any necessary initialization to access arbitrary stack frames.
4122 On the SPARC, this means flushing the register windows. */
4123 __builtin_unwind_init ();
4125 /* Now reset pc to the right throw point. */
4126 pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
4128 handler = throw_helper (eh, pc, my_udata, &offset);
4130 /* Now go! */
4132 __builtin_eh_return ((void *)eh, offset, handler);
4134 /* Epilogue: restore the handler frame's register values and return
4135 to the stub. */
4137 #endif /* DWARF2_UNWIND_INFO */
4139 #endif /* L_eh */
4141 #ifdef L_pure
4142 #ifndef inhibit_libc
4143 /* This gets us __GNU_LIBRARY__. */
4144 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
4145 #include <stdio.h>
4147 #ifdef __GNU_LIBRARY__
4148 /* Avoid forcing the library's meaning of `write' on the user program
4149 by using the "internal" name (for use within the library) */
4150 #define write(fd, buf, n) __write((fd), (buf), (n))
4151 #endif
4152 #endif /* inhibit_libc */
4154 #define MESSAGE "pure virtual method called\n"
4156 extern void __terminate (void) __attribute__ ((__noreturn__));
4158 void
4159 __pure_virtual (void)
4161 #ifndef inhibit_libc
4162 write (2, MESSAGE, sizeof (MESSAGE) - 1);
4163 #endif
4164 __terminate ();
4166 #endif