oops - omitted from previous delta fixing UNIQUE_SECTION
[official-gcc.git] / gcc / libgcc2.c
blobde140514707d272db049d669d29729d7880b6a89
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"
36 /* We disable this when inhibit_libc, so that gcc can still be built without
37 needing header files first. */
38 /* ??? This is not a good solution, since prototypes may be required in
39 some cases for correct code. See also frame.c/crtstuff.c. */
40 #ifndef inhibit_libc
41 /* fixproto guarantees these system headers exist. */
42 #include <stdlib.h>
43 #include <unistd.h>
45 #else
46 #ifndef L_trampoline
47 #include <stddef.h>
48 #ifndef malloc
49 extern void *malloc (size_t);
50 #endif
51 #ifndef free
52 extern void free (void *);
53 #endif
54 #ifndef atexit
55 extern int atexit(void (*)(void));
56 #endif
57 #endif
58 #endif
60 #include "machmode.h"
61 #include "defaults.h"
62 #ifndef L_trampoline
63 #include <stddef.h>
64 #endif
66 /* Don't use `fancy_abort' here even if config.h says to use it. */
67 #ifdef abort
68 #undef abort
69 #endif
71 /* In a cross-compilation situation, default to inhibiting compilation
72 of routines that use libc. */
74 #if defined(CROSS_COMPILE) && !defined(inhibit_libc)
75 #define inhibit_libc
76 #endif
78 /* Permit the tm.h file to select the endianness to use just for this
79 file. This is used when the endianness is determined when the
80 compiler is run. */
82 #ifndef LIBGCC2_WORDS_BIG_ENDIAN
83 #define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
84 #endif
86 #ifndef LIBGCC2_LONG_DOUBLE_TYPE_SIZE
87 #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE LONG_DOUBLE_TYPE_SIZE
88 #endif
90 /* In the first part of this file, we are interfacing to calls generated
91 by the compiler itself. These calls pass values into these routines
92 which have very specific modes (rather than very specific types), and
93 these compiler-generated calls also expect any return values to have
94 very specific modes (rather than very specific types). Thus, we need
95 to avoid using regular C language type names in this part of the file
96 because the sizes for those types can be configured to be anything.
97 Instead we use the following special type names. */
99 typedef int QItype __attribute__ ((mode (QI)));
100 typedef unsigned int UQItype __attribute__ ((mode (QI)));
101 typedef int HItype __attribute__ ((mode (HI)));
102 typedef unsigned int UHItype __attribute__ ((mode (HI)));
103 #if UNITS_PER_WORD > 1
104 /* These typedefs are usually forbidden on dsp's with UNITS_PER_WORD 1 */
105 typedef int SItype __attribute__ ((mode (SI)));
106 typedef unsigned int USItype __attribute__ ((mode (SI)));
107 #if UNITS_PER_WORD > 2
108 /* These typedefs are usually forbidden on archs with UNITS_PER_WORD 2 */
109 typedef int DItype __attribute__ ((mode (DI)));
110 typedef unsigned int UDItype __attribute__ ((mode (DI)));
111 #endif
112 #endif
114 #if BITS_PER_UNIT == 8
116 typedef float SFtype __attribute__ ((mode (SF)));
117 typedef float DFtype __attribute__ ((mode (DF)));
119 #if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
120 typedef float XFtype __attribute__ ((mode (XF)));
121 #endif
122 #if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128
123 typedef float TFtype __attribute__ ((mode (TF)));
124 #endif
126 #else /* BITS_PER_UNIT != 8 */
128 /* On dsp's there are usually qf/hf/tqf modes used instead of the above.
129 For now we don't support them in libgcc2.c. */
131 #undef L_fixdfdi
132 #undef L_fixsfdi
133 #undef L_fixtfdi
134 #undef L_fixunsdfdi
135 #undef L_fixunsdfsi
136 #undef L_fixunssfdi
137 #undef L_fixunssfsi
138 #undef L_fixunstfdi
139 #undef L_fixunsxfdi
140 #undef L_fixunsxfsi
141 #undef L_fixxfdi
142 #undef L_floatdidf
143 #undef L_floatdisf
144 #undef L_floatditf
145 #undef L_floatdixf
147 #endif /* BITS_PER_UNIT != 8 */
149 typedef int word_type __attribute__ ((mode (__word__)));
151 /* Make sure that we don't accidentally use any normal C language built-in
152 type names in the first part of this file. Instead we want to use *only*
153 the type names defined above. The following macro definitions insure
154 that if we *do* accidentally use some normal C language built-in type name,
155 we will get a syntax error. */
157 #define char bogus_type
158 #define short bogus_type
159 #define int bogus_type
160 #define long bogus_type
161 #define unsigned bogus_type
162 #define float bogus_type
163 #define double bogus_type
165 #if UNITS_PER_WORD > 2
166 #define W_TYPE_SIZE (4 * BITS_PER_UNIT)
167 #define Wtype SItype
168 #define UWtype USItype
169 #define HWtype SItype
170 #define UHWtype USItype
171 #define DWtype DItype
172 #define UDWtype UDItype
173 #define __NW(a,b) __ ## a ## si ## b
174 #define __NDW(a,b) __ ## a ## di ## b
175 #elif UNITS_PER_WORD > 1
176 #define W_TYPE_SIZE (2 * BITS_PER_UNIT)
177 #define Wtype HItype
178 #define UWtype UHItype
179 #define HWtype HItype
180 #define UHWtype UHItype
181 #define DWtype SItype
182 #define UDWtype USItype
183 #define __NW(a,b) __ ## a ## hi ## b
184 #define __NDW(a,b) __ ## a ## si ## b
185 #else
186 #define W_TYPE_SIZE BITS_PER_UNIT
187 #define Wtype QItype
188 #define UWtype UQItype
189 #define HWtype QItype
190 #define UHWtype UQItype
191 #define DWtype HItype
192 #define UDWtype UHItype
193 #define __NW(a,b) __ ## a ## qi ## b
194 #define __NDW(a,b) __ ## a ## hi ## b
195 #endif
197 #define __muldi3 __NDW(mul,3)
198 #define __divdi3 __NDW(div,3)
199 #define __udivdi3 __NDW(udiv,3)
200 #define __moddi3 __NDW(mod,3)
201 #define __umoddi3 __NDW(umod,3)
202 #define __negdi2 __NDW(neg,2)
203 #define __lshrdi3 __NDW(lshr,3)
204 #define __ashldi3 __NDW(ashl,3)
205 #define __ashrdi3 __NDW(ashr,3)
206 #define __ffsdi2 __NDW(ffs,2)
207 #define __cmpdi2 __NDW(cmp,2)
208 #define __ucmpdi2 __NDW(ucmp,2)
209 #define __udivmoddi4 __NDW(udivmod,4)
210 #define __fixunstfdi __NDW(fixunstf,)
211 #define __fixtfdi __NDW(fixtf,)
212 #define __fixunsxfdi __NDW(fixunsxf,)
213 #define __fixxfdi __NDW(fixxf,)
214 #define __fixunsdfdi __NDW(fixunsdf,)
215 #define __fixdfdi __NDW(fixdf,)
216 #define __fixunssfdi __NDW(fixunssf,)
217 #define __fixsfdi __NDW(fixsf,)
218 #define __floatdixf __NDW(float,xf)
219 #define __floatditf __NDW(float,tf)
220 #define __floatdidf __NDW(float,df)
221 #define __floatdisf __NDW(float,sf)
222 #define __fixunsxfsi __NW(fixunsxf,)
223 #define __fixunstfsi __NW(fixunstf,)
224 #define __fixunsdfsi __NW(fixunsdf,)
225 #define __fixunssfsi __NW(fixunssf,)
227 /* DWstructs are pairs of Wtype values in the order determined by
228 LIBGCC2_WORDS_BIG_ENDIAN. */
230 #if LIBGCC2_WORDS_BIG_ENDIAN
231 struct DWstruct {Wtype high, low;};
232 #else
233 struct DWstruct {Wtype low, high;};
234 #endif
236 /* We need this union to unpack/pack DImode values, since we don't have
237 any arithmetic yet. Incoming DImode parameters are stored into the
238 `ll' field, and the unpacked result is read from the struct `s'. */
240 typedef union
242 struct DWstruct s;
243 DWtype ll;
244 } DWunion;
246 #if (defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_w_sdiv)\
247 || defined (L_divdi3) || defined (L_udivdi3) \
248 || defined (L_moddi3) || defined (L_umoddi3))
250 #include "longlong.h"
252 #endif /* udiv or mul */
255 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
256 #if defined (L_divdi3) || defined (L_moddi3)
257 static inline
258 #endif
259 DWtype
260 __negdi2 (DWtype u)
262 DWunion w;
263 DWunion uu;
265 uu.ll = u;
267 w.s.low = -uu.s.low;
268 w.s.high = -uu.s.high - ((UWtype) w.s.low > 0);
270 return w.ll;
272 #endif
274 /* Unless shift functions are defined whith full ANSI prototypes,
275 parameter b will be promoted to int if word_type is smaller than an int. */
276 #ifdef L_lshrdi3
277 DWtype
278 __lshrdi3 (DWtype u, word_type b)
280 DWunion w;
281 word_type bm;
282 DWunion uu;
284 if (b == 0)
285 return u;
287 uu.ll = u;
289 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
290 if (bm <= 0)
292 w.s.high = 0;
293 w.s.low = (UWtype)uu.s.high >> -bm;
295 else
297 UWtype carries = (UWtype)uu.s.high << bm;
298 w.s.high = (UWtype)uu.s.high >> b;
299 w.s.low = ((UWtype)uu.s.low >> b) | carries;
302 return w.ll;
304 #endif
306 #ifdef L_ashldi3
307 DWtype
308 __ashldi3 (DWtype u, word_type b)
310 DWunion w;
311 word_type bm;
312 DWunion uu;
314 if (b == 0)
315 return u;
317 uu.ll = u;
319 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
320 if (bm <= 0)
322 w.s.low = 0;
323 w.s.high = (UWtype)uu.s.low << -bm;
325 else
327 UWtype carries = (UWtype)uu.s.low >> bm;
328 w.s.low = (UWtype)uu.s.low << b;
329 w.s.high = ((UWtype)uu.s.high << b) | carries;
332 return w.ll;
334 #endif
336 #ifdef L_ashrdi3
337 DWtype
338 __ashrdi3 (DWtype u, word_type b)
340 DWunion w;
341 word_type bm;
342 DWunion uu;
344 if (b == 0)
345 return u;
347 uu.ll = u;
349 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
350 if (bm <= 0)
352 /* w.s.high = 1..1 or 0..0 */
353 w.s.high = uu.s.high >> (sizeof (Wtype) * BITS_PER_UNIT - 1);
354 w.s.low = uu.s.high >> -bm;
356 else
358 UWtype carries = (UWtype)uu.s.high << bm;
359 w.s.high = uu.s.high >> b;
360 w.s.low = ((UWtype)uu.s.low >> b) | carries;
363 return w.ll;
365 #endif
367 #ifdef L_ffsdi2
368 DWtype
369 __ffsdi2 (DWtype u)
371 DWunion uu, w;
372 uu.ll = u;
373 w.s.high = 0;
374 w.s.low = ffs (uu.s.low);
375 if (w.s.low != 0)
376 return w.ll;
377 w.s.low = ffs (uu.s.high);
378 if (w.s.low != 0)
380 w.s.low += BITS_PER_UNIT * sizeof (Wtype);
381 return w.ll;
383 return w.ll;
385 #endif
387 #ifdef L_muldi3
388 DWtype
389 __muldi3 (DWtype u, DWtype v)
391 DWunion w;
392 DWunion uu, vv;
394 uu.ll = u,
395 vv.ll = v;
397 w.ll = __umulsidi3 (uu.s.low, vv.s.low);
398 w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
399 + (UWtype) uu.s.high * (UWtype) vv.s.low);
401 return w.ll;
403 #endif
405 #ifdef L_udiv_w_sdiv
406 #if defined (sdiv_qrnnd)
407 UWtype
408 __udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d)
410 UWtype q, r;
411 UWtype c0, c1, b1;
413 if ((Wtype) d >= 0)
415 if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1)))
417 /* dividend, divisor, and quotient are nonnegative */
418 sdiv_qrnnd (q, r, a1, a0, d);
420 else
422 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
423 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1));
424 /* Divide (c1*2^32 + c0) by d */
425 sdiv_qrnnd (q, r, c1, c0, d);
426 /* Add 2^31 to quotient */
427 q += (UWtype) 1 << (W_TYPE_SIZE - 1);
430 else
432 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
433 c1 = a1 >> 1; /* A/2 */
434 c0 = (a1 << (W_TYPE_SIZE - 1)) + (a0 >> 1);
436 if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
438 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
440 r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
441 if ((d & 1) != 0)
443 if (r >= q)
444 r = r - q;
445 else if (q - r <= d)
447 r = r - q + d;
448 q--;
450 else
452 r = r - q + 2*d;
453 q -= 2;
457 else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
459 c1 = (b1 - 1) - c1;
460 c0 = ~c0; /* logical NOT */
462 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
464 q = ~q; /* (A/2)/b1 */
465 r = (b1 - 1) - r;
467 r = 2*r + (a0 & 1); /* A/(2*b1) */
469 if ((d & 1) != 0)
471 if (r >= q)
472 r = r - q;
473 else if (q - r <= d)
475 r = r - q + d;
476 q--;
478 else
480 r = r - q + 2*d;
481 q -= 2;
485 else /* Implies c1 = b1 */
486 { /* Hence a1 = d - 1 = 2*b1 - 1 */
487 if (a0 >= -d)
489 q = -1;
490 r = a0 + d;
492 else
494 q = -2;
495 r = a0 + 2*d;
500 *rp = r;
501 return q;
503 #else
504 /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */
505 UWtype
506 __udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)),
507 UWtype a1 __attribute__ ((__unused__)),
508 UWtype a0 __attribute__ ((__unused__)),
509 UWtype d __attribute__ ((__unused__)))
511 return 0;
513 #endif
514 #endif
516 #if (defined (L_udivdi3) || defined (L_divdi3) || \
517 defined (L_umoddi3) || defined (L_moddi3))
518 #define L_udivmoddi4
519 #endif
521 #ifdef L_udivmoddi4
522 static const UQItype __clz_tab[] =
524 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,
525 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,
526 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,
527 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,
528 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,
529 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,
530 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,
531 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,
534 #if (defined (L_udivdi3) || defined (L_divdi3) || \
535 defined (L_umoddi3) || defined (L_moddi3))
536 static inline
537 #endif
538 UDWtype
539 __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
541 DWunion ww;
542 DWunion nn, dd;
543 DWunion rr;
544 UWtype d0, d1, n0, n1, n2;
545 UWtype q0, q1;
546 UWtype b, bm;
548 nn.ll = n;
549 dd.ll = d;
551 d0 = dd.s.low;
552 d1 = dd.s.high;
553 n0 = nn.s.low;
554 n1 = nn.s.high;
556 #if !UDIV_NEEDS_NORMALIZATION
557 if (d1 == 0)
559 if (d0 > n1)
561 /* 0q = nn / 0D */
563 udiv_qrnnd (q0, n0, n1, n0, d0);
564 q1 = 0;
566 /* Remainder in n0. */
568 else
570 /* qq = NN / 0d */
572 if (d0 == 0)
573 d0 = 1 / d0; /* Divide intentionally by zero. */
575 udiv_qrnnd (q1, n1, 0, n1, d0);
576 udiv_qrnnd (q0, n0, n1, n0, d0);
578 /* Remainder in n0. */
581 if (rp != 0)
583 rr.s.low = n0;
584 rr.s.high = 0;
585 *rp = rr.ll;
589 #else /* UDIV_NEEDS_NORMALIZATION */
591 if (d1 == 0)
593 if (d0 > n1)
595 /* 0q = nn / 0D */
597 count_leading_zeros (bm, d0);
599 if (bm != 0)
601 /* Normalize, i.e. make the most significant bit of the
602 denominator set. */
604 d0 = d0 << bm;
605 n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
606 n0 = n0 << bm;
609 udiv_qrnnd (q0, n0, n1, n0, d0);
610 q1 = 0;
612 /* Remainder in n0 >> bm. */
614 else
616 /* qq = NN / 0d */
618 if (d0 == 0)
619 d0 = 1 / d0; /* Divide intentionally by zero. */
621 count_leading_zeros (bm, d0);
623 if (bm == 0)
625 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
626 conclude (the most significant bit of n1 is set) /\ (the
627 leading quotient digit q1 = 1).
629 This special case is necessary, not an optimization.
630 (Shifts counts of W_TYPE_SIZE are undefined.) */
632 n1 -= d0;
633 q1 = 1;
635 else
637 /* Normalize. */
639 b = W_TYPE_SIZE - bm;
641 d0 = d0 << bm;
642 n2 = n1 >> b;
643 n1 = (n1 << bm) | (n0 >> b);
644 n0 = n0 << bm;
646 udiv_qrnnd (q1, n1, n2, n1, d0);
649 /* n1 != d0... */
651 udiv_qrnnd (q0, n0, n1, n0, d0);
653 /* Remainder in n0 >> bm. */
656 if (rp != 0)
658 rr.s.low = n0 >> bm;
659 rr.s.high = 0;
660 *rp = rr.ll;
663 #endif /* UDIV_NEEDS_NORMALIZATION */
665 else
667 if (d1 > n1)
669 /* 00 = nn / DD */
671 q0 = 0;
672 q1 = 0;
674 /* Remainder in n1n0. */
675 if (rp != 0)
677 rr.s.low = n0;
678 rr.s.high = n1;
679 *rp = rr.ll;
682 else
684 /* 0q = NN / dd */
686 count_leading_zeros (bm, d1);
687 if (bm == 0)
689 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
690 conclude (the most significant bit of n1 is set) /\ (the
691 quotient digit q0 = 0 or 1).
693 This special case is necessary, not an optimization. */
695 /* The condition on the next line takes advantage of that
696 n1 >= d1 (true due to program flow). */
697 if (n1 > d1 || n0 >= d0)
699 q0 = 1;
700 sub_ddmmss (n1, n0, n1, n0, d1, d0);
702 else
703 q0 = 0;
705 q1 = 0;
707 if (rp != 0)
709 rr.s.low = n0;
710 rr.s.high = n1;
711 *rp = rr.ll;
714 else
716 UWtype m1, m0;
717 /* Normalize. */
719 b = W_TYPE_SIZE - bm;
721 d1 = (d1 << bm) | (d0 >> b);
722 d0 = d0 << bm;
723 n2 = n1 >> b;
724 n1 = (n1 << bm) | (n0 >> b);
725 n0 = n0 << bm;
727 udiv_qrnnd (q0, n1, n2, n1, d1);
728 umul_ppmm (m1, m0, q0, d0);
730 if (m1 > n1 || (m1 == n1 && m0 > n0))
732 q0--;
733 sub_ddmmss (m1, m0, m1, m0, d1, d0);
736 q1 = 0;
738 /* Remainder in (n1n0 - m1m0) >> bm. */
739 if (rp != 0)
741 sub_ddmmss (n1, n0, n1, n0, m1, m0);
742 rr.s.low = (n1 << b) | (n0 >> bm);
743 rr.s.high = n1 >> bm;
744 *rp = rr.ll;
750 ww.s.low = q0;
751 ww.s.high = q1;
752 return ww.ll;
754 #endif
756 #ifdef L_divdi3
757 DWtype
758 __divdi3 (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 c = ~c,
772 vv.ll = __negdi2 (vv.ll);
774 w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
775 if (c)
776 w = __negdi2 (w);
778 return w;
780 #endif
782 #ifdef L_moddi3
783 DWtype
784 __moddi3 (DWtype u, DWtype v)
786 word_type c = 0;
787 DWunion uu, vv;
788 DWtype w;
790 uu.ll = u;
791 vv.ll = v;
793 if (uu.s.high < 0)
794 c = ~c,
795 uu.ll = __negdi2 (uu.ll);
796 if (vv.s.high < 0)
797 vv.ll = __negdi2 (vv.ll);
799 (void) __udivmoddi4 (uu.ll, vv.ll, &w);
800 if (c)
801 w = __negdi2 (w);
803 return w;
805 #endif
807 #ifdef L_umoddi3
808 UDWtype
809 __umoddi3 (UDWtype u, UDWtype v)
811 UDWtype w;
813 (void) __udivmoddi4 (u, v, &w);
815 return w;
817 #endif
819 #ifdef L_udivdi3
820 UDWtype
821 __udivdi3 (UDWtype n, UDWtype d)
823 return __udivmoddi4 (n, d, (UDWtype *) 0);
825 #endif
827 #ifdef L_cmpdi2
828 word_type
829 __cmpdi2 (DWtype a, DWtype b)
831 DWunion au, bu;
833 au.ll = a, bu.ll = b;
835 if (au.s.high < bu.s.high)
836 return 0;
837 else if (au.s.high > bu.s.high)
838 return 2;
839 if ((UWtype) au.s.low < (UWtype) bu.s.low)
840 return 0;
841 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
842 return 2;
843 return 1;
845 #endif
847 #ifdef L_ucmpdi2
848 word_type
849 __ucmpdi2 (DWtype a, DWtype b)
851 DWunion au, bu;
853 au.ll = a, bu.ll = b;
855 if ((UWtype) au.s.high < (UWtype) bu.s.high)
856 return 0;
857 else if ((UWtype) au.s.high > (UWtype) bu.s.high)
858 return 2;
859 if ((UWtype) au.s.low < (UWtype) bu.s.low)
860 return 0;
861 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
862 return 2;
863 return 1;
865 #endif
867 #if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
868 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
869 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
871 DWtype
872 __fixunstfdi (TFtype a)
874 TFtype b;
875 UDWtype v;
877 if (a < 0)
878 return 0;
880 /* Compute high word of result, as a flonum. */
881 b = (a / HIGH_WORD_COEFF);
882 /* Convert that to fixed (but not to DWtype!),
883 and shift it into the high word. */
884 v = (UWtype) b;
885 v <<= WORD_SIZE;
886 /* Remove high part from the TFtype, leaving the low part as flonum. */
887 a -= (TFtype)v;
888 /* Convert that to fixed (but not to DWtype!) and add it in.
889 Sometimes A comes out negative. This is significant, since
890 A has more bits than a long int does. */
891 if (a < 0)
892 v -= (UWtype) (- a);
893 else
894 v += (UWtype) a;
895 return v;
897 #endif
899 #if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
900 extern DWtype __fixunstfdi (TFtype a);
902 DWtype
903 __fixtfdi (TFtype a)
905 if (a < 0)
906 return - __fixunstfdi (-a);
907 return __fixunstfdi (a);
909 #endif
911 #if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
912 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
913 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
915 DWtype
916 __fixunsxfdi (XFtype a)
918 XFtype b;
919 UDWtype v;
921 if (a < 0)
922 return 0;
924 /* Compute high word of result, as a flonum. */
925 b = (a / HIGH_WORD_COEFF);
926 /* Convert that to fixed (but not to DWtype!),
927 and shift it into the high word. */
928 v = (UWtype) b;
929 v <<= WORD_SIZE;
930 /* Remove high part from the XFtype, leaving the low part as flonum. */
931 a -= (XFtype)v;
932 /* Convert that to fixed (but not to DWtype!) and add it in.
933 Sometimes A comes out negative. This is significant, since
934 A has more bits than a long int does. */
935 if (a < 0)
936 v -= (UWtype) (- a);
937 else
938 v += (UWtype) a;
939 return v;
941 #endif
943 #if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
944 extern DWtype __fixunsxfdi (XFtype a);
946 DWtype
947 __fixxfdi (XFtype a)
949 if (a < 0)
950 return - __fixunsxfdi (-a);
951 return __fixunsxfdi (a);
953 #endif
955 #ifdef L_fixunsdfdi
956 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
957 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
959 DWtype
960 __fixunsdfdi (DFtype a)
962 DFtype b;
963 UDWtype v;
965 if (a < 0)
966 return 0;
968 /* Compute high word of result, as a flonum. */
969 b = (a / HIGH_WORD_COEFF);
970 /* Convert that to fixed (but not to DWtype!),
971 and shift it into the high word. */
972 v = (UWtype) b;
973 v <<= WORD_SIZE;
974 /* Remove high part from the DFtype, leaving the low part as flonum. */
975 a -= (DFtype)v;
976 /* Convert that to fixed (but not to DWtype!) and add it in.
977 Sometimes A comes out negative. This is significant, since
978 A has more bits than a long int does. */
979 if (a < 0)
980 v -= (UWtype) (- a);
981 else
982 v += (UWtype) a;
983 return v;
985 #endif
987 #ifdef L_fixdfdi
988 extern DWtype __fixunsdfdi (DFtype a);
990 DWtype
991 __fixdfdi (DFtype a)
993 if (a < 0)
994 return - __fixunsdfdi (-a);
995 return __fixunsdfdi (a);
997 #endif
999 #ifdef L_fixunssfdi
1000 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1001 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1003 DWtype
1004 __fixunssfdi (SFtype original_a)
1006 /* Convert the SFtype to a DFtype, because that is surely not going
1007 to lose any bits. Some day someone else can write a faster version
1008 that avoids converting to DFtype, and verify it really works right. */
1009 DFtype a = original_a;
1010 DFtype b;
1011 UDWtype v;
1013 if (a < 0)
1014 return 0;
1016 /* Compute high word of result, as a flonum. */
1017 b = (a / HIGH_WORD_COEFF);
1018 /* Convert that to fixed (but not to DWtype!),
1019 and shift it into the high word. */
1020 v = (UWtype) b;
1021 v <<= WORD_SIZE;
1022 /* Remove high part from the DFtype, leaving the low part as flonum. */
1023 a -= (DFtype)v;
1024 /* Convert that to fixed (but not to DWtype!) and add it in.
1025 Sometimes A comes out negative. This is significant, since
1026 A has more bits than a long int does. */
1027 if (a < 0)
1028 v -= (UWtype) (- a);
1029 else
1030 v += (UWtype) a;
1031 return v;
1033 #endif
1035 #ifdef L_fixsfdi
1036 extern DWtype __fixunssfdi (SFtype a);
1038 DWtype
1039 __fixsfdi (SFtype a)
1041 if (a < 0)
1042 return - __fixunssfdi (-a);
1043 return __fixunssfdi (a);
1045 #endif
1047 #if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
1048 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1049 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1050 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1052 XFtype
1053 __floatdixf (DWtype u)
1055 XFtype d;
1057 d = (Wtype) (u >> WORD_SIZE);
1058 d *= HIGH_HALFWORD_COEFF;
1059 d *= HIGH_HALFWORD_COEFF;
1060 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1062 return d;
1064 #endif
1066 #if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
1067 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1068 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1069 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1071 TFtype
1072 __floatditf (DWtype u)
1074 TFtype d;
1076 d = (Wtype) (u >> WORD_SIZE);
1077 d *= HIGH_HALFWORD_COEFF;
1078 d *= HIGH_HALFWORD_COEFF;
1079 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1081 return d;
1083 #endif
1085 #ifdef L_floatdidf
1086 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1087 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1088 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1090 DFtype
1091 __floatdidf (DWtype u)
1093 DFtype d;
1095 d = (Wtype) (u >> WORD_SIZE);
1096 d *= HIGH_HALFWORD_COEFF;
1097 d *= HIGH_HALFWORD_COEFF;
1098 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1100 return d;
1102 #endif
1104 #ifdef L_floatdisf
1105 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1106 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1107 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1108 #define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT)
1110 /* Define codes for all the float formats that we know of. Note
1111 that this is copied from real.h. */
1113 #define UNKNOWN_FLOAT_FORMAT 0
1114 #define IEEE_FLOAT_FORMAT 1
1115 #define VAX_FLOAT_FORMAT 2
1116 #define IBM_FLOAT_FORMAT 3
1118 /* Default to IEEE float if not specified. Nearly all machines use it. */
1119 #ifndef HOST_FLOAT_FORMAT
1120 #define HOST_FLOAT_FORMAT IEEE_FLOAT_FORMAT
1121 #endif
1123 #if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1124 #define DF_SIZE 53
1125 #define SF_SIZE 24
1126 #endif
1128 #if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
1129 #define DF_SIZE 56
1130 #define SF_SIZE 24
1131 #endif
1133 #if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
1134 #define DF_SIZE 56
1135 #define SF_SIZE 24
1136 #endif
1138 SFtype
1139 __floatdisf (DWtype u)
1141 /* Do the calculation in DFmode
1142 so that we don't lose any of the precision of the high word
1143 while multiplying it. */
1144 DFtype f;
1146 /* Protect against double-rounding error.
1147 Represent any low-order bits, that might be truncated in DFmode,
1148 by a bit that won't be lost. The bit can go in anywhere below the
1149 rounding position of the SFmode. A fixed mask and bit position
1150 handles all usual configurations. It doesn't handle the case
1151 of 128-bit DImode, however. */
1152 if (DF_SIZE < DI_SIZE
1153 && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1155 #define REP_BIT ((UWtype) 1 << (DI_SIZE - DF_SIZE))
1156 if (! (- ((DWtype) 1 << DF_SIZE) < u
1157 && u < ((DWtype) 1 << DF_SIZE)))
1159 if ((UWtype) u & (REP_BIT - 1))
1160 u |= REP_BIT;
1163 f = (Wtype) (u >> WORD_SIZE);
1164 f *= HIGH_HALFWORD_COEFF;
1165 f *= HIGH_HALFWORD_COEFF;
1166 f += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1168 return (SFtype) f;
1170 #endif
1172 #if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
1173 /* Reenable the normal types, in case limits.h needs them. */
1174 #undef char
1175 #undef short
1176 #undef int
1177 #undef long
1178 #undef unsigned
1179 #undef float
1180 #undef double
1181 #undef MIN
1182 #undef MAX
1183 #include <limits.h>
1185 UWtype
1186 __fixunsxfsi (XFtype a)
1188 if (a >= - (DFtype) LONG_MIN)
1189 return (Wtype) (a + LONG_MIN) - LONG_MIN;
1190 return (Wtype) a;
1192 #endif
1194 #ifdef L_fixunsdfsi
1195 /* Reenable the normal types, in case limits.h needs them. */
1196 #undef char
1197 #undef short
1198 #undef int
1199 #undef long
1200 #undef unsigned
1201 #undef float
1202 #undef double
1203 #undef MIN
1204 #undef MAX
1205 #include <limits.h>
1207 UWtype
1208 __fixunsdfsi (DFtype a)
1210 if (a >= - (DFtype) LONG_MIN)
1211 return (Wtype) (a + LONG_MIN) - LONG_MIN;
1212 return (Wtype) a;
1214 #endif
1216 #ifdef L_fixunssfsi
1217 /* Reenable the normal types, in case limits.h needs them. */
1218 #undef char
1219 #undef short
1220 #undef int
1221 #undef long
1222 #undef unsigned
1223 #undef float
1224 #undef double
1225 #undef MIN
1226 #undef MAX
1227 #include <limits.h>
1229 UWtype
1230 __fixunssfsi (SFtype a)
1232 if (a >= - (SFtype) LONG_MIN)
1233 return (Wtype) (a + LONG_MIN) - LONG_MIN;
1234 return (Wtype) a;
1236 #endif
1238 /* From here on down, the routines use normal data types. */
1240 #define SItype bogus_type
1241 #define USItype bogus_type
1242 #define DItype bogus_type
1243 #define UDItype bogus_type
1244 #define SFtype bogus_type
1245 #define DFtype bogus_type
1246 #undef Wtype
1247 #undef UWtype
1248 #undef HWtype
1249 #undef UHWtype
1250 #undef DWtype
1251 #undef UDWtype
1253 #undef char
1254 #undef short
1255 #undef int
1256 #undef long
1257 #undef unsigned
1258 #undef float
1259 #undef double
1261 #ifdef L__gcc_bcmp
1263 /* Like bcmp except the sign is meaningful.
1264 Result is negative if S1 is less than S2,
1265 positive if S1 is greater, 0 if S1 and S2 are equal. */
1268 __gcc_bcmp (unsigned char *s1, unsigned char *s2, size_t size)
1270 while (size > 0)
1272 unsigned char c1 = *s1++, c2 = *s2++;
1273 if (c1 != c2)
1274 return c1 - c2;
1275 size--;
1277 return 0;
1280 #endif
1281 \f\f
1282 #ifdef L__dummy
1283 void
1284 __dummy (void) {}
1285 #endif
1287 #ifdef L_varargs
1288 #ifdef __i860__
1289 #if defined(__svr4__) || defined(__alliant__)
1290 asm (" .text");
1291 asm (" .align 4");
1293 /* The Alliant needs the added underscore. */
1294 asm (".globl __builtin_saveregs");
1295 asm ("__builtin_saveregs:");
1296 asm (".globl ___builtin_saveregs");
1297 asm ("___builtin_saveregs:");
1299 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
1300 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
1301 area and also for a new va_list
1302 structure */
1303 /* Save all argument registers in the arg reg save area. The
1304 arg reg save area must have the following layout (according
1305 to the svr4 ABI):
1307 struct {
1308 union {
1309 float freg[8];
1310 double dreg[4];
1311 } float_regs;
1312 long ireg[12];
1316 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
1317 asm (" fst.q %f12,16(%sp)");
1319 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
1320 asm (" st.l %r17,36(%sp)");
1321 asm (" st.l %r18,40(%sp)");
1322 asm (" st.l %r19,44(%sp)");
1323 asm (" st.l %r20,48(%sp)");
1324 asm (" st.l %r21,52(%sp)");
1325 asm (" st.l %r22,56(%sp)");
1326 asm (" st.l %r23,60(%sp)");
1327 asm (" st.l %r24,64(%sp)");
1328 asm (" st.l %r25,68(%sp)");
1329 asm (" st.l %r26,72(%sp)");
1330 asm (" st.l %r27,76(%sp)");
1332 asm (" adds 80,%sp,%r16"); /* compute the address of the new
1333 va_list structure. Put in into
1334 r16 so that it will be returned
1335 to the caller. */
1337 /* Initialize all fields of the new va_list structure. This
1338 structure looks like:
1340 typedef struct {
1341 unsigned long ireg_used;
1342 unsigned long freg_used;
1343 long *reg_base;
1344 long *mem_ptr;
1345 } va_list;
1348 asm (" st.l %r0, 0(%r16)"); /* nfixed */
1349 asm (" st.l %r0, 4(%r16)"); /* nfloating */
1350 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
1351 asm (" bri %r1"); /* delayed return */
1352 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
1354 #else /* not __svr4__ */
1355 #if defined(__PARAGON__)
1357 * we'll use SVR4-ish varargs but need SVR3.2 assembler syntax,
1358 * and we stand a better chance of hooking into libraries
1359 * compiled by PGI. [andyp@ssd.intel.com]
1361 asm (" .text");
1362 asm (" .align 4");
1363 asm (".globl __builtin_saveregs");
1364 asm ("__builtin_saveregs:");
1365 asm (".globl ___builtin_saveregs");
1366 asm ("___builtin_saveregs:");
1368 asm (" andnot 0x0f,sp,sp"); /* round down to 16-byte boundary */
1369 asm (" adds -96,sp,sp"); /* allocate stack space for reg save
1370 area and also for a new va_list
1371 structure */
1372 /* Save all argument registers in the arg reg save area. The
1373 arg reg save area must have the following layout (according
1374 to the svr4 ABI):
1376 struct {
1377 union {
1378 float freg[8];
1379 double dreg[4];
1380 } float_regs;
1381 long ireg[12];
1385 asm (" fst.q f8, 0(sp)");
1386 asm (" fst.q f12,16(sp)");
1387 asm (" st.l r16,32(sp)");
1388 asm (" st.l r17,36(sp)");
1389 asm (" st.l r18,40(sp)");
1390 asm (" st.l r19,44(sp)");
1391 asm (" st.l r20,48(sp)");
1392 asm (" st.l r21,52(sp)");
1393 asm (" st.l r22,56(sp)");
1394 asm (" st.l r23,60(sp)");
1395 asm (" st.l r24,64(sp)");
1396 asm (" st.l r25,68(sp)");
1397 asm (" st.l r26,72(sp)");
1398 asm (" st.l r27,76(sp)");
1400 asm (" adds 80,sp,r16"); /* compute the address of the new
1401 va_list structure. Put in into
1402 r16 so that it will be returned
1403 to the caller. */
1405 /* Initialize all fields of the new va_list structure. This
1406 structure looks like:
1408 typedef struct {
1409 unsigned long ireg_used;
1410 unsigned long freg_used;
1411 long *reg_base;
1412 long *mem_ptr;
1413 } va_list;
1416 asm (" st.l r0, 0(r16)"); /* nfixed */
1417 asm (" st.l r0, 4(r16)"); /* nfloating */
1418 asm (" st.l sp, 8(r16)"); /* __va_ctl points to __va_struct. */
1419 asm (" bri r1"); /* delayed return */
1420 asm (" st.l r28,12(r16)"); /* pointer to overflow args */
1421 #else /* not __PARAGON__ */
1422 asm (" .text");
1423 asm (" .align 4");
1425 asm (".globl ___builtin_saveregs");
1426 asm ("___builtin_saveregs:");
1427 asm (" mov sp,r30");
1428 asm (" andnot 0x0f,sp,sp");
1429 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
1431 /* Fill in the __va_struct. */
1432 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
1433 asm (" st.l r17, 4(sp)"); /* int fixed[12] */
1434 asm (" st.l r18, 8(sp)");
1435 asm (" st.l r19,12(sp)");
1436 asm (" st.l r20,16(sp)");
1437 asm (" st.l r21,20(sp)");
1438 asm (" st.l r22,24(sp)");
1439 asm (" st.l r23,28(sp)");
1440 asm (" st.l r24,32(sp)");
1441 asm (" st.l r25,36(sp)");
1442 asm (" st.l r26,40(sp)");
1443 asm (" st.l r27,44(sp)");
1445 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
1446 asm (" fst.q f12,64(sp)"); /* int floating[8] */
1448 /* Fill in the __va_ctl. */
1449 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
1450 asm (" st.l r28,84(sp)"); /* pointer to more args */
1451 asm (" st.l r0, 88(sp)"); /* nfixed */
1452 asm (" st.l r0, 92(sp)"); /* nfloating */
1454 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
1455 asm (" bri r1");
1456 asm (" mov r30,sp");
1457 /* recover stack and pass address to start
1458 of data. */
1459 #endif /* not __PARAGON__ */
1460 #endif /* not __svr4__ */
1461 #else /* not __i860__ */
1462 #ifdef __sparc__
1463 asm (".global __builtin_saveregs");
1464 asm ("__builtin_saveregs:");
1465 asm (".global ___builtin_saveregs");
1466 asm ("___builtin_saveregs:");
1467 #ifdef NEED_PROC_COMMAND
1468 asm (".proc 020");
1469 #endif
1470 asm ("st %i0,[%fp+68]");
1471 asm ("st %i1,[%fp+72]");
1472 asm ("st %i2,[%fp+76]");
1473 asm ("st %i3,[%fp+80]");
1474 asm ("st %i4,[%fp+84]");
1475 asm ("retl");
1476 asm ("st %i5,[%fp+88]");
1477 #ifdef NEED_TYPE_COMMAND
1478 asm (".type __builtin_saveregs,#function");
1479 asm (".size __builtin_saveregs,.-__builtin_saveregs");
1480 #endif
1481 #else /* not __sparc__ */
1482 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1484 asm (" .text");
1485 #ifdef __mips16
1486 asm (" .set nomips16");
1487 #endif
1488 asm (" .ent __builtin_saveregs");
1489 asm (" .globl __builtin_saveregs");
1490 asm ("__builtin_saveregs:");
1491 asm (" sw $4,0($30)");
1492 asm (" sw $5,4($30)");
1493 asm (" sw $6,8($30)");
1494 asm (" sw $7,12($30)");
1495 asm (" j $31");
1496 asm (" .end __builtin_saveregs");
1497 #else /* not __mips__, etc. */
1499 void *
1500 __builtin_saveregs (void)
1502 abort ();
1505 #endif /* not __mips__ */
1506 #endif /* not __sparc__ */
1507 #endif /* not __i860__ */
1508 #endif
1510 #ifdef L_eprintf
1511 #ifndef inhibit_libc
1513 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1514 #include <stdio.h>
1515 /* This is used by the `assert' macro. */
1516 extern void __eprintf (const char *, const char *, unsigned int, const char *)
1517 __attribute__ ((__noreturn__));
1519 void
1520 __eprintf (const char *string, const char *expression,
1521 unsigned int line, const char *filename)
1523 fprintf (stderr, string, expression, line, filename);
1524 fflush (stderr);
1525 abort ();
1528 #endif
1529 #endif
1531 #ifdef L_bb
1533 /* Structure emitted by -a */
1534 struct bb
1536 long zero_word;
1537 const char *filename;
1538 long *counts;
1539 long ncounts;
1540 struct bb *next;
1541 const unsigned long *addresses;
1543 /* Older GCC's did not emit these fields. */
1544 long nwords;
1545 const char **functions;
1546 const long *line_nums;
1547 const char **filenames;
1548 char *flags;
1551 #ifdef BLOCK_PROFILER_CODE
1552 BLOCK_PROFILER_CODE
1553 #else
1554 #ifndef inhibit_libc
1556 /* Simple minded basic block profiling output dumper for
1557 systems that don't provide tcov support. At present,
1558 it requires atexit and stdio. */
1560 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1561 #include <stdio.h>
1562 char *ctime ();
1564 #include "gbl-ctors.h"
1565 #include "gcov-io.h"
1566 #include <string.h>
1567 #ifdef TARGET_HAS_F_SETLKW
1568 #include <fcntl.h>
1569 #include <errno.h>
1570 #endif
1572 static struct bb *bb_head;
1574 static int num_digits (long value, int base) __attribute__ ((const));
1576 /* Return the number of digits needed to print a value */
1577 /* __inline__ */ static int num_digits (long value, int base)
1579 int minus = (value < 0 && base != 16);
1580 unsigned long v = (minus) ? -value : value;
1581 int ret = minus;
1585 v /= base;
1586 ret++;
1588 while (v);
1590 return ret;
1593 void
1594 __bb_exit_func (void)
1596 FILE *da_file, *file;
1597 long time_value;
1598 int i;
1600 if (bb_head == 0)
1601 return;
1603 i = strlen (bb_head->filename) - 3;
1605 if (!strcmp (bb_head->filename+i, ".da"))
1607 /* Must be -fprofile-arcs not -a.
1608 Dump data in a form that gcov expects. */
1610 struct bb *ptr;
1612 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1614 int firstchar;
1616 /* Make sure the output file exists -
1617 but don't clobber exiting data. */
1618 if ((da_file = fopen (ptr->filename, "a")) != 0)
1619 fclose (da_file);
1621 /* Need to re-open in order to be able to write from the start. */
1622 da_file = fopen (ptr->filename, "r+b");
1623 /* Some old systems might not allow the 'b' mode modifier.
1624 Therefore, try to open without it. This can lead to a race
1625 condition so that when you delete and re-create the file, the
1626 file might be opened in text mode, but then, you shouldn't
1627 delete the file in the first place. */
1628 if (da_file == 0)
1629 da_file = fopen (ptr->filename, "r+");
1630 if (da_file == 0)
1632 fprintf (stderr, "arc profiling: Can't open output file %s.\n",
1633 ptr->filename);
1634 continue;
1637 /* After a fork, another process might try to read and/or write
1638 the same file simultanously. So if we can, lock the file to
1639 avoid race conditions. */
1640 #if defined (TARGET_HAS_F_SETLKW)
1642 struct flock s_flock;
1644 s_flock.l_type = F_WRLCK;
1645 s_flock.l_whence = SEEK_SET;
1646 s_flock.l_start = 0;
1647 s_flock.l_len = 1;
1648 s_flock.l_pid = getpid ();
1650 while (fcntl (fileno (da_file), F_SETLKW, &s_flock)
1651 && errno == EINTR);
1653 #endif
1655 /* If the file is not empty, and the number of counts in it is the
1656 same, then merge them in. */
1657 firstchar = fgetc (da_file);
1658 if (firstchar == EOF)
1660 if (ferror (da_file))
1662 fprintf (stderr, "arc profiling: Can't read output file ");
1663 perror (ptr->filename);
1666 else
1668 long n_counts = 0;
1670 if (ungetc (firstchar, da_file) == EOF)
1671 rewind (da_file);
1672 if (__read_long (&n_counts, da_file, 8) != 0)
1674 fprintf (stderr, "arc profiling: Can't read output file %s.\n",
1675 ptr->filename);
1676 continue;
1679 if (n_counts == ptr->ncounts)
1681 int i;
1683 for (i = 0; i < n_counts; i++)
1685 long v = 0;
1687 if (__read_long (&v, da_file, 8) != 0)
1689 fprintf (stderr, "arc profiling: Can't read output file %s.\n",
1690 ptr->filename);
1691 break;
1693 ptr->counts[i] += v;
1699 rewind (da_file);
1701 /* ??? Should first write a header to the file. Preferably, a 4 byte
1702 magic number, 4 bytes containing the time the program was
1703 compiled, 4 bytes containing the last modification time of the
1704 source file, and 4 bytes indicating the compiler options used.
1706 That way we can easily verify that the proper source/executable/
1707 data file combination is being used from gcov. */
1709 if (__write_long (ptr->ncounts, da_file, 8) != 0)
1712 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1713 ptr->filename);
1715 else
1717 int j;
1718 long *count_ptr = ptr->counts;
1719 int ret = 0;
1720 for (j = ptr->ncounts; j > 0; j--)
1722 if (__write_long (*count_ptr, da_file, 8) != 0)
1724 ret=1;
1725 break;
1727 count_ptr++;
1729 if (ret)
1730 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1731 ptr->filename);
1734 if (fclose (da_file) == EOF)
1735 fprintf (stderr, "arc profiling: Error closing output file %s.\n",
1736 ptr->filename);
1739 return;
1742 /* Must be basic block profiling. Emit a human readable output file. */
1744 file = fopen ("bb.out", "a");
1746 if (!file)
1747 perror ("bb.out");
1749 else
1751 struct bb *ptr;
1753 /* This is somewhat type incorrect, but it avoids worrying about
1754 exactly where time.h is included from. It should be ok unless
1755 a void * differs from other pointer formats, or if sizeof (long)
1756 is < sizeof (time_t). It would be nice if we could assume the
1757 use of rationale standards here. */
1759 time ((void *) &time_value);
1760 fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value));
1762 /* We check the length field explicitly in order to allow compatibility
1763 with older GCC's which did not provide it. */
1765 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1767 int i;
1768 int func_p = (ptr->nwords >= (long) sizeof (struct bb)
1769 && ptr->nwords <= 1000
1770 && ptr->functions);
1771 int line_p = (func_p && ptr->line_nums);
1772 int file_p = (func_p && ptr->filenames);
1773 int addr_p = (ptr->addresses != 0);
1774 long ncounts = ptr->ncounts;
1775 long cnt_max = 0;
1776 long line_max = 0;
1777 long addr_max = 0;
1778 int file_len = 0;
1779 int func_len = 0;
1780 int blk_len = num_digits (ncounts, 10);
1781 int cnt_len;
1782 int line_len;
1783 int addr_len;
1785 fprintf (file, "File %s, %ld basic blocks \n\n",
1786 ptr->filename, ncounts);
1788 /* Get max values for each field. */
1789 for (i = 0; i < ncounts; i++)
1791 const char *p;
1792 int len;
1794 if (cnt_max < ptr->counts[i])
1795 cnt_max = ptr->counts[i];
1797 if (addr_p && (unsigned long) addr_max < ptr->addresses[i])
1798 addr_max = ptr->addresses[i];
1800 if (line_p && line_max < ptr->line_nums[i])
1801 line_max = ptr->line_nums[i];
1803 if (func_p)
1805 p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>";
1806 len = strlen (p);
1807 if (func_len < len)
1808 func_len = len;
1811 if (file_p)
1813 p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>";
1814 len = strlen (p);
1815 if (file_len < len)
1816 file_len = len;
1820 addr_len = num_digits (addr_max, 16);
1821 cnt_len = num_digits (cnt_max, 10);
1822 line_len = num_digits (line_max, 10);
1824 /* Now print out the basic block information. */
1825 for (i = 0; i < ncounts; i++)
1827 fprintf (file,
1828 " Block #%*d: executed %*ld time(s)",
1829 blk_len, i+1,
1830 cnt_len, ptr->counts[i]);
1832 if (addr_p)
1833 fprintf (file, " address= 0x%.*lx", addr_len,
1834 ptr->addresses[i]);
1836 if (func_p)
1837 fprintf (file, " function= %-*s", func_len,
1838 (ptr->functions[i]) ? ptr->functions[i] : "<none>");
1840 if (line_p)
1841 fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]);
1843 if (file_p)
1844 fprintf (file, " file= %s",
1845 (ptr->filenames[i]) ? ptr->filenames[i] : "<none>");
1847 fprintf (file, "\n");
1850 fprintf (file, "\n");
1851 fflush (file);
1854 fprintf (file, "\n\n");
1855 fclose (file);
1859 void
1860 __bb_init_func (struct bb *blocks)
1862 /* User is supposed to check whether the first word is non-0,
1863 but just in case.... */
1865 if (blocks->zero_word)
1866 return;
1868 /* Initialize destructor. */
1869 if (!bb_head)
1870 atexit (__bb_exit_func);
1872 /* Set up linked list. */
1873 blocks->zero_word = 1;
1874 blocks->next = bb_head;
1875 bb_head = blocks;
1878 /* Called before fork or exec - write out profile information gathered so
1879 far and reset it to zero. This avoids duplication or loss of the
1880 profile information gathered so far. */
1881 void
1882 __bb_fork_func (void)
1884 struct bb *ptr;
1886 __bb_exit_func ();
1887 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1889 long i;
1890 for (i = ptr->ncounts - 1; i >= 0; i--)
1891 ptr->counts[i] = 0;
1895 #ifndef MACHINE_STATE_SAVE
1896 #define MACHINE_STATE_SAVE(ID)
1897 #endif
1898 #ifndef MACHINE_STATE_RESTORE
1899 #define MACHINE_STATE_RESTORE(ID)
1900 #endif
1902 /* Number of buckets in hashtable of basic block addresses. */
1904 #define BB_BUCKETS 311
1906 /* Maximum length of string in file bb.in. */
1908 #define BBINBUFSIZE 500
1910 /* BBINBUFSIZE-1 with double quotes. We could use #BBINBUFSIZE or
1911 "BBINBUFSIZE" but want to avoid trouble with preprocessors. */
1913 #define BBINBUFSIZESTR "499"
1915 struct bb_edge
1917 struct bb_edge *next;
1918 unsigned long src_addr;
1919 unsigned long dst_addr;
1920 unsigned long count;
1923 enum bb_func_mode
1925 TRACE_KEEP = 0, TRACE_ON = 1, TRACE_OFF = 2
1928 struct bb_func
1930 struct bb_func *next;
1931 char *funcname;
1932 char *filename;
1933 enum bb_func_mode mode;
1936 /* This is the connection to the outside world.
1937 The BLOCK_PROFILER macro must set __bb.blocks
1938 and __bb.blockno. */
1940 struct {
1941 unsigned long blockno;
1942 struct bb *blocks;
1943 } __bb;
1945 /* Vars to store addrs of source and destination basic blocks
1946 of a jump. */
1948 static unsigned long bb_src = 0;
1949 static unsigned long bb_dst = 0;
1951 static FILE *bb_tracefile = (FILE *) 0;
1952 static struct bb_edge **bb_hashbuckets = (struct bb_edge **) 0;
1953 static struct bb_func *bb_func_head = (struct bb_func *) 0;
1954 static unsigned long bb_callcount = 0;
1955 static int bb_mode = 0;
1957 static unsigned long *bb_stack = (unsigned long *) 0;
1958 static size_t bb_stacksize = 0;
1960 static int reported = 0;
1962 /* Trace modes:
1963 Always : Print execution frequencies of basic blocks
1964 to file bb.out.
1965 bb_mode & 1 != 0 : Dump trace of basic blocks to file bbtrace[.gz]
1966 bb_mode & 2 != 0 : Print jump frequencies to file bb.out.
1967 bb_mode & 4 != 0 : Cut call instructions from basic block flow.
1968 bb_mode & 8 != 0 : Insert return instructions in basic block flow.
1971 #ifdef HAVE_POPEN
1973 /*#include <sys/types.h>*/
1974 #include <sys/stat.h>
1975 /*#include <malloc.h>*/
1977 /* Commands executed by gopen. */
1979 #define GOPENDECOMPRESS "gzip -cd "
1980 #define GOPENCOMPRESS "gzip -c >"
1982 /* Like fopen but pipes through gzip. mode may only be "r" or "w".
1983 If it does not compile, simply replace gopen by fopen and delete
1984 '.gz' from any first parameter to gopen. */
1986 static FILE *
1987 gopen (char *fn, char *mode)
1989 int use_gzip;
1990 char *p;
1992 if (mode[1])
1993 return (FILE *) 0;
1995 if (mode[0] != 'r' && mode[0] != 'w')
1996 return (FILE *) 0;
1998 p = fn + strlen (fn)-1;
1999 use_gzip = ((p[-1] == '.' && (p[0] == 'Z' || p[0] == 'z'))
2000 || (p[-2] == '.' && p[-1] == 'g' && p[0] == 'z'));
2002 if (use_gzip)
2004 if (mode[0]=='r')
2006 FILE *f;
2007 char *s = (char *) malloc (sizeof (char) * strlen (fn)
2008 + sizeof (GOPENDECOMPRESS));
2009 strcpy (s, GOPENDECOMPRESS);
2010 strcpy (s + (sizeof (GOPENDECOMPRESS)-1), fn);
2011 f = popen (s, mode);
2012 free (s);
2013 return f;
2016 else
2018 FILE *f;
2019 char *s = (char *) malloc (sizeof (char) * strlen (fn)
2020 + sizeof (GOPENCOMPRESS));
2021 strcpy (s, GOPENCOMPRESS);
2022 strcpy (s + (sizeof (GOPENCOMPRESS)-1), fn);
2023 if (!(f = popen (s, mode)))
2024 f = fopen (s, mode);
2025 free (s);
2026 return f;
2030 else
2031 return fopen (fn, mode);
2034 static int
2035 gclose (FILE *f)
2037 struct stat buf;
2039 if (f != 0)
2041 if (!fstat (fileno (f), &buf) && S_ISFIFO (buf.st_mode))
2042 return pclose (f);
2044 return fclose (f);
2046 return 0;
2049 #endif /* HAVE_POPEN */
2051 /* Called once per program. */
2053 static void
2054 __bb_exit_trace_func (void)
2056 FILE *file = fopen ("bb.out", "a");
2057 struct bb_func *f;
2058 struct bb *b;
2060 if (!file)
2061 perror ("bb.out");
2063 if (bb_mode & 1)
2065 if (!bb_tracefile)
2066 perror ("bbtrace");
2067 else
2068 #ifdef HAVE_POPEN
2069 gclose (bb_tracefile);
2070 #else
2071 fclose (bb_tracefile);
2072 #endif /* HAVE_POPEN */
2075 /* Check functions in `bb.in'. */
2077 if (file)
2079 long time_value;
2080 const struct bb_func *p;
2081 int printed_something = 0;
2082 struct bb *ptr;
2083 long blk;
2085 /* This is somewhat type incorrect. */
2086 time ((void *) &time_value);
2088 for (p = bb_func_head; p != (struct bb_func *) 0; p = p->next)
2090 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
2092 if (!ptr->filename || (p->filename != (char *) 0 && strcmp (p->filename, ptr->filename)))
2093 continue;
2094 for (blk = 0; blk < ptr->ncounts; blk++)
2096 if (!strcmp (p->funcname, ptr->functions[blk]))
2097 goto found;
2101 if (!printed_something)
2103 fprintf (file, "Functions in `bb.in' not executed during basic block profiling on %s\n", ctime ((void *) &time_value));
2104 printed_something = 1;
2107 fprintf (file, "\tFunction %s", p->funcname);
2108 if (p->filename)
2109 fprintf (file, " of file %s", p->filename);
2110 fprintf (file, "\n" );
2112 found: ;
2115 if (printed_something)
2116 fprintf (file, "\n");
2120 if (bb_mode & 2)
2122 if (!bb_hashbuckets)
2124 if (!reported)
2126 fprintf (stderr, "Profiler: out of memory\n");
2127 reported = 1;
2129 return;
2132 else if (file)
2134 long time_value;
2135 int i;
2136 unsigned long addr_max = 0;
2137 unsigned long cnt_max = 0;
2138 int cnt_len;
2139 int addr_len;
2141 /* This is somewhat type incorrect, but it avoids worrying about
2142 exactly where time.h is included from. It should be ok unless
2143 a void * differs from other pointer formats, or if sizeof (long)
2144 is < sizeof (time_t). It would be nice if we could assume the
2145 use of rationale standards here. */
2147 time ((void *) &time_value);
2148 fprintf (file, "Basic block jump tracing");
2150 switch (bb_mode & 12)
2152 case 0:
2153 fprintf (file, " (with call)");
2154 break;
2156 case 4:
2157 /* Print nothing. */
2158 break;
2160 case 8:
2161 fprintf (file, " (with call & ret)");
2162 break;
2164 case 12:
2165 fprintf (file, " (with ret)");
2166 break;
2169 fprintf (file, " finished on %s\n", ctime ((void *) &time_value));
2171 for (i = 0; i < BB_BUCKETS; i++)
2173 struct bb_edge *bucket = bb_hashbuckets[i];
2174 for ( ; bucket; bucket = bucket->next )
2176 if (addr_max < bucket->src_addr)
2177 addr_max = bucket->src_addr;
2178 if (addr_max < bucket->dst_addr)
2179 addr_max = bucket->dst_addr;
2180 if (cnt_max < bucket->count)
2181 cnt_max = bucket->count;
2184 addr_len = num_digits (addr_max, 16);
2185 cnt_len = num_digits (cnt_max, 10);
2187 for ( i = 0; i < BB_BUCKETS; i++)
2189 struct bb_edge *bucket = bb_hashbuckets[i];
2190 for ( ; bucket; bucket = bucket->next )
2192 fprintf (file, "Jump from block 0x%.*lx to "
2193 "block 0x%.*lx executed %*lu time(s)\n",
2194 addr_len, bucket->src_addr,
2195 addr_len, bucket->dst_addr,
2196 cnt_len, bucket->count);
2200 fprintf (file, "\n");
2205 if (file)
2206 fclose (file);
2208 /* Free allocated memory. */
2210 f = bb_func_head;
2211 while (f)
2213 struct bb_func *old = f;
2215 f = f->next;
2216 if (old->funcname) free (old->funcname);
2217 if (old->filename) free (old->filename);
2218 free (old);
2221 if (bb_stack)
2222 free (bb_stack);
2224 if (bb_hashbuckets)
2226 int i;
2228 for (i = 0; i < BB_BUCKETS; i++)
2230 struct bb_edge *old, *bucket = bb_hashbuckets[i];
2232 while (bucket)
2234 old = bucket;
2235 bucket = bucket->next;
2236 free (old);
2239 free (bb_hashbuckets);
2242 for (b = bb_head; b; b = b->next)
2243 if (b->flags) free (b->flags);
2246 /* Called once per program. */
2248 static void
2249 __bb_init_prg (void)
2251 FILE *file;
2252 char buf[BBINBUFSIZE];
2253 const char *p;
2254 const char *pos;
2255 enum bb_func_mode m;
2256 int i;
2258 /* Initialize destructor. */
2259 atexit (__bb_exit_func);
2261 if (!(file = fopen ("bb.in", "r")))
2262 return;
2264 while(fscanf (file, " %" BBINBUFSIZESTR "s ", buf) != EOF)
2266 p = buf;
2267 if (*p == '-')
2269 m = TRACE_OFF;
2270 p++;
2272 else
2274 m = TRACE_ON;
2276 if (!strcmp (p, "__bb_trace__"))
2277 bb_mode |= 1;
2278 else if (!strcmp (p, "__bb_jumps__"))
2279 bb_mode |= 2;
2280 else if (!strcmp (p, "__bb_hidecall__"))
2281 bb_mode |= 4;
2282 else if (!strcmp (p, "__bb_showret__"))
2283 bb_mode |= 8;
2284 else
2286 struct bb_func *f = (struct bb_func *) malloc (sizeof (struct bb_func));
2287 if (f)
2289 unsigned long l;
2290 f->next = bb_func_head;
2291 if ((pos = strchr (p, ':')))
2293 if (!(f->funcname = (char *) malloc (strlen (pos+1)+1)))
2294 continue;
2295 strcpy (f->funcname, pos+1);
2296 l = pos-p;
2297 if ((f->filename = (char *) malloc (l+1)))
2299 strncpy (f->filename, p, l);
2300 f->filename[l] = '\0';
2302 else
2303 f->filename = (char *) 0;
2305 else
2307 if (!(f->funcname = (char *) malloc (strlen (p)+1)))
2308 continue;
2309 strcpy (f->funcname, p);
2310 f->filename = (char *) 0;
2312 f->mode = m;
2313 bb_func_head = f;
2317 fclose (file);
2319 #ifdef HAVE_POPEN
2321 if (bb_mode & 1)
2322 bb_tracefile = gopen ("bbtrace.gz", "w");
2324 #else
2326 if (bb_mode & 1)
2327 bb_tracefile = fopen ("bbtrace", "w");
2329 #endif /* HAVE_POPEN */
2331 if (bb_mode & 2)
2333 bb_hashbuckets = (struct bb_edge **)
2334 malloc (BB_BUCKETS * sizeof (struct bb_edge *));
2335 if (bb_hashbuckets)
2336 /* Use a loop here rather than calling bzero to avoid having to
2337 conditionalize its existance. */
2338 for (i = 0; i < BB_BUCKETS; i++)
2339 bb_hashbuckets[i] = 0;
2342 if (bb_mode & 12)
2344 bb_stacksize = 10;
2345 bb_stack = (unsigned long *) malloc (bb_stacksize * sizeof (*bb_stack));
2348 /* Initialize destructor. */
2349 atexit (__bb_exit_trace_func);
2352 /* Called upon entering a basic block. */
2354 void
2355 __bb_trace_func (void)
2357 struct bb_edge *bucket;
2359 MACHINE_STATE_SAVE("1")
2361 if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2362 goto skip;
2364 bb_dst = __bb.blocks->addresses[__bb.blockno];
2365 __bb.blocks->counts[__bb.blockno]++;
2367 if (bb_tracefile)
2369 fwrite (&bb_dst, sizeof (unsigned long), 1, bb_tracefile);
2372 if (bb_hashbuckets)
2374 struct bb_edge **startbucket, **oldnext;
2376 oldnext = startbucket
2377 = & bb_hashbuckets[ (((int) bb_src*8) ^ (int) bb_dst) % BB_BUCKETS ];
2378 bucket = *startbucket;
2380 for (bucket = *startbucket; bucket;
2381 oldnext = &(bucket->next), bucket = *oldnext)
2383 if (bucket->src_addr == bb_src
2384 && bucket->dst_addr == bb_dst)
2386 bucket->count++;
2387 *oldnext = bucket->next;
2388 bucket->next = *startbucket;
2389 *startbucket = bucket;
2390 goto ret;
2394 bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2396 if (!bucket)
2398 if (!reported)
2400 fprintf (stderr, "Profiler: out of memory\n");
2401 reported = 1;
2405 else
2407 bucket->src_addr = bb_src;
2408 bucket->dst_addr = bb_dst;
2409 bucket->next = *startbucket;
2410 *startbucket = bucket;
2411 bucket->count = 1;
2415 ret:
2416 bb_src = bb_dst;
2418 skip:
2421 MACHINE_STATE_RESTORE("1")
2425 /* Called when returning from a function and `__bb_showret__' is set. */
2427 static void
2428 __bb_trace_func_ret (void)
2430 struct bb_edge *bucket;
2432 if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2433 goto skip;
2435 if (bb_hashbuckets)
2437 struct bb_edge **startbucket, **oldnext;
2439 oldnext = startbucket
2440 = & bb_hashbuckets[ (((int) bb_dst * 8) ^ (int) bb_src) % BB_BUCKETS ];
2441 bucket = *startbucket;
2443 for (bucket = *startbucket; bucket;
2444 oldnext = &(bucket->next), bucket = *oldnext)
2446 if (bucket->src_addr == bb_dst
2447 && bucket->dst_addr == bb_src)
2449 bucket->count++;
2450 *oldnext = bucket->next;
2451 bucket->next = *startbucket;
2452 *startbucket = bucket;
2453 goto ret;
2457 bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2459 if (!bucket)
2461 if (!reported)
2463 fprintf (stderr, "Profiler: out of memory\n");
2464 reported = 1;
2468 else
2470 bucket->src_addr = bb_dst;
2471 bucket->dst_addr = bb_src;
2472 bucket->next = *startbucket;
2473 *startbucket = bucket;
2474 bucket->count = 1;
2478 ret:
2479 bb_dst = bb_src;
2481 skip:
2486 /* Called upon entering the first function of a file. */
2488 static void
2489 __bb_init_file (struct bb *blocks)
2492 const struct bb_func *p;
2493 long blk, ncounts = blocks->ncounts;
2494 const char **functions = blocks->functions;
2496 /* Set up linked list. */
2497 blocks->zero_word = 1;
2498 blocks->next = bb_head;
2499 bb_head = blocks;
2501 blocks->flags = 0;
2502 if (!bb_func_head
2503 || !(blocks->flags = (char *) malloc (sizeof (char) * blocks->ncounts)))
2504 return;
2506 for (blk = 0; blk < ncounts; blk++)
2507 blocks->flags[blk] = 0;
2509 for (blk = 0; blk < ncounts; blk++)
2511 for (p = bb_func_head; p; p = p->next)
2513 if (!strcmp (p->funcname, functions[blk])
2514 && (!p->filename || !strcmp (p->filename, blocks->filename)))
2516 blocks->flags[blk] |= p->mode;
2523 /* Called when exiting from a function. */
2525 void
2526 __bb_trace_ret (void)
2529 MACHINE_STATE_SAVE("2")
2531 if (bb_callcount)
2533 if ((bb_mode & 12) && bb_stacksize > bb_callcount)
2535 bb_src = bb_stack[bb_callcount];
2536 if (bb_mode & 8)
2537 __bb_trace_func_ret ();
2540 bb_callcount -= 1;
2543 MACHINE_STATE_RESTORE("2")
2547 /* Called when entering a function. */
2549 void
2550 __bb_init_trace_func (struct bb *blocks, unsigned long blockno)
2552 static int trace_init = 0;
2554 MACHINE_STATE_SAVE("3")
2556 if (!blocks->zero_word)
2558 if (!trace_init)
2560 trace_init = 1;
2561 __bb_init_prg ();
2563 __bb_init_file (blocks);
2566 if (bb_callcount)
2569 bb_callcount += 1;
2571 if (bb_mode & 12)
2573 if (bb_callcount >= bb_stacksize)
2575 size_t newsize = bb_callcount + 100;
2577 bb_stack = (unsigned long *) realloc (bb_stack, newsize);
2578 if (! bb_stack)
2580 if (!reported)
2582 fprintf (stderr, "Profiler: out of memory\n");
2583 reported = 1;
2585 bb_stacksize = 0;
2586 goto stack_overflow;
2588 bb_stacksize = newsize;
2590 bb_stack[bb_callcount] = bb_src;
2592 if (bb_mode & 4)
2593 bb_src = 0;
2597 stack_overflow:;
2601 else if (blocks->flags && (blocks->flags[blockno] & TRACE_ON))
2603 bb_callcount = 1;
2604 bb_src = 0;
2606 if (bb_stack)
2607 bb_stack[bb_callcount] = bb_src;
2610 MACHINE_STATE_RESTORE("3")
2613 #endif /* not inhibit_libc */
2614 #endif /* not BLOCK_PROFILER_CODE */
2615 #endif /* L_bb */
2617 #ifdef L_shtab
2618 unsigned int __shtab[] = {
2619 0x00000001, 0x00000002, 0x00000004, 0x00000008,
2620 0x00000010, 0x00000020, 0x00000040, 0x00000080,
2621 0x00000100, 0x00000200, 0x00000400, 0x00000800,
2622 0x00001000, 0x00002000, 0x00004000, 0x00008000,
2623 0x00010000, 0x00020000, 0x00040000, 0x00080000,
2624 0x00100000, 0x00200000, 0x00400000, 0x00800000,
2625 0x01000000, 0x02000000, 0x04000000, 0x08000000,
2626 0x10000000, 0x20000000, 0x40000000, 0x80000000
2628 #endif
2630 #ifdef L_clear_cache
2631 /* Clear part of an instruction cache. */
2633 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
2635 void
2636 __clear_cache (char *beg __attribute__((__unused__)),
2637 char *end __attribute__((__unused__)))
2639 #ifdef CLEAR_INSN_CACHE
2640 CLEAR_INSN_CACHE (beg, end);
2641 #else
2642 #ifdef INSN_CACHE_SIZE
2643 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
2644 static int initialized;
2645 int offset;
2646 void *start_addr
2647 void *end_addr;
2648 typedef (*function_ptr) (void);
2650 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
2651 /* It's cheaper to clear the whole cache.
2652 Put in a series of jump instructions so that calling the beginning
2653 of the cache will clear the whole thing. */
2655 if (! initialized)
2657 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2658 & -INSN_CACHE_LINE_WIDTH);
2659 int end_ptr = ptr + INSN_CACHE_SIZE;
2661 while (ptr < end_ptr)
2663 *(INSTRUCTION_TYPE *)ptr
2664 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
2665 ptr += INSN_CACHE_LINE_WIDTH;
2667 *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
2669 initialized = 1;
2672 /* Call the beginning of the sequence. */
2673 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2674 & -INSN_CACHE_LINE_WIDTH))
2675 ());
2677 #else /* Cache is large. */
2679 if (! initialized)
2681 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2682 & -INSN_CACHE_LINE_WIDTH);
2684 while (ptr < (int) array + sizeof array)
2686 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
2687 ptr += INSN_CACHE_LINE_WIDTH;
2690 initialized = 1;
2693 /* Find the location in array that occupies the same cache line as BEG. */
2695 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
2696 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
2697 & -INSN_CACHE_PLANE_SIZE)
2698 + offset);
2700 /* Compute the cache alignment of the place to stop clearing. */
2701 #if 0 /* This is not needed for gcc's purposes. */
2702 /* If the block to clear is bigger than a cache plane,
2703 we clear the entire cache, and OFFSET is already correct. */
2704 if (end < beg + INSN_CACHE_PLANE_SIZE)
2705 #endif
2706 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
2707 & -INSN_CACHE_LINE_WIDTH)
2708 & (INSN_CACHE_PLANE_SIZE - 1));
2710 #if INSN_CACHE_DEPTH > 1
2711 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
2712 if (end_addr <= start_addr)
2713 end_addr += INSN_CACHE_PLANE_SIZE;
2715 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
2717 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
2718 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
2720 while (addr != stop)
2722 /* Call the return instruction at ADDR. */
2723 ((function_ptr) addr) ();
2725 addr += INSN_CACHE_LINE_WIDTH;
2728 #else /* just one plane */
2731 /* Call the return instruction at START_ADDR. */
2732 ((function_ptr) start_addr) ();
2734 start_addr += INSN_CACHE_LINE_WIDTH;
2736 while ((start_addr % INSN_CACHE_SIZE) != offset);
2737 #endif /* just one plane */
2738 #endif /* Cache is large */
2739 #endif /* Cache exists */
2740 #endif /* CLEAR_INSN_CACHE */
2743 #endif /* L_clear_cache */
2745 #ifdef L_trampoline
2747 /* Jump to a trampoline, loading the static chain address. */
2749 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
2751 long
2752 getpagesize (void)
2754 #ifdef _ALPHA_
2755 return 8192;
2756 #else
2757 return 4096;
2758 #endif
2761 #ifdef __i386__
2762 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
2763 #endif
2766 mprotect (char *addr, int len, int prot)
2768 int np, op;
2770 if (prot == 7)
2771 np = 0x40;
2772 else if (prot == 5)
2773 np = 0x20;
2774 else if (prot == 4)
2775 np = 0x10;
2776 else if (prot == 3)
2777 np = 0x04;
2778 else if (prot == 1)
2779 np = 0x02;
2780 else if (prot == 0)
2781 np = 0x01;
2783 if (VirtualProtect (addr, len, np, &op))
2784 return 0;
2785 else
2786 return -1;
2789 #endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
2791 #ifdef TRANSFER_FROM_TRAMPOLINE
2792 TRANSFER_FROM_TRAMPOLINE
2793 #endif
2795 #if defined (NeXT) && defined (__MACH__)
2797 /* Make stack executable so we can call trampolines on stack.
2798 This is called from INITIALIZE_TRAMPOLINE in next.h. */
2799 #ifdef NeXTStep21
2800 #include <mach.h>
2801 #else
2802 #include <mach/mach.h>
2803 #endif
2805 void
2806 __enable_execute_stack (char *addr)
2808 kern_return_t r;
2809 char *eaddr = addr + TRAMPOLINE_SIZE;
2810 vm_address_t a = (vm_address_t) addr;
2812 /* turn on execute access on stack */
2813 r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
2814 if (r != KERN_SUCCESS)
2816 mach_error("vm_protect VM_PROT_ALL", r);
2817 exit(1);
2820 /* We inline the i-cache invalidation for speed */
2822 #ifdef CLEAR_INSN_CACHE
2823 CLEAR_INSN_CACHE (addr, eaddr);
2824 #else
2825 __clear_cache ((int) addr, (int) eaddr);
2826 #endif
2829 #endif /* defined (NeXT) && defined (__MACH__) */
2831 #ifdef __convex__
2833 /* Make stack executable so we can call trampolines on stack.
2834 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
2836 #include <sys/mman.h>
2837 #include <sys/vmparam.h>
2838 #include <machine/machparam.h>
2840 void
2841 __enable_execute_stack (void)
2843 int fp;
2844 static unsigned lowest = USRSTACK;
2845 unsigned current = (unsigned) &fp & -NBPG;
2847 if (lowest > current)
2849 unsigned len = lowest - current;
2850 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
2851 lowest = current;
2854 /* Clear instruction cache in case an old trampoline is in it. */
2855 asm ("pich");
2857 #endif /* __convex__ */
2859 #ifdef __sysV88__
2861 /* Modified from the convex -code above. */
2863 #include <sys/param.h>
2864 #include <errno.h>
2865 #include <sys/m88kbcs.h>
2867 void
2868 __enable_execute_stack (void)
2870 int save_errno;
2871 static unsigned long lowest = USRSTACK;
2872 unsigned long current = (unsigned long) &save_errno & -NBPC;
2874 /* Ignore errno being set. memctl sets errno to EINVAL whenever the
2875 address is seen as 'negative'. That is the case with the stack. */
2877 save_errno=errno;
2878 if (lowest > current)
2880 unsigned len=lowest-current;
2881 memctl(current,len,MCT_TEXT);
2882 lowest = current;
2884 else
2885 memctl(current,NBPC,MCT_TEXT);
2886 errno=save_errno;
2889 #endif /* __sysV88__ */
2891 #ifdef __sysV68__
2893 #include <sys/signal.h>
2894 #include <errno.h>
2896 /* Motorola forgot to put memctl.o in the libp version of libc881.a,
2897 so define it here, because we need it in __clear_insn_cache below */
2898 /* On older versions of this OS, no memctl or MCT_TEXT are defined;
2899 hence we enable this stuff only if MCT_TEXT is #define'd. */
2901 #ifdef MCT_TEXT
2902 asm("\n\
2903 global memctl\n\
2904 memctl:\n\
2905 movq &75,%d0\n\
2906 trap &0\n\
2907 bcc.b noerror\n\
2908 jmp cerror%\n\
2909 noerror:\n\
2910 movq &0,%d0\n\
2911 rts");
2912 #endif
2914 /* Clear instruction cache so we can call trampolines on stack.
2915 This is called from FINALIZE_TRAMPOLINE in mot3300.h. */
2917 void
2918 __clear_insn_cache (void)
2920 #ifdef MCT_TEXT
2921 int save_errno;
2923 /* Preserve errno, because users would be surprised to have
2924 errno changing without explicitly calling any system-call. */
2925 save_errno = errno;
2927 /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache.
2928 No need to use an address derived from _start or %sp, as 0 works also. */
2929 memctl(0, 4096, MCT_TEXT);
2930 errno = save_errno;
2931 #endif
2934 #endif /* __sysV68__ */
2936 #ifdef __pyr__
2938 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2939 #include <stdio.h>
2940 #include <sys/mman.h>
2941 #include <sys/types.h>
2942 #include <sys/param.h>
2943 #include <sys/vmmac.h>
2945 /* Modified from the convex -code above.
2946 mremap promises to clear the i-cache. */
2948 void
2949 __enable_execute_stack (void)
2951 int fp;
2952 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
2953 PROT_READ|PROT_WRITE|PROT_EXEC))
2955 perror ("mprotect in __enable_execute_stack");
2956 fflush (stderr);
2957 abort ();
2960 #endif /* __pyr__ */
2962 #if defined (sony_news) && defined (SYSTYPE_BSD)
2964 #include <stdio.h>
2965 #include <sys/types.h>
2966 #include <sys/param.h>
2967 #include <syscall.h>
2968 #include <machine/sysnews.h>
2970 /* cacheflush function for NEWS-OS 4.2.
2971 This function is called from trampoline-initialize code
2972 defined in config/mips/mips.h. */
2974 void
2975 cacheflush (char *beg, int size, int flag)
2977 if (syscall (SYS_sysnews, NEWS_CACHEFLUSH, beg, size, FLUSH_BCACHE))
2979 perror ("cache_flush");
2980 fflush (stderr);
2981 abort ();
2985 #endif /* sony_news */
2986 #endif /* L_trampoline */
2988 #ifndef __CYGWIN__
2989 #ifdef L__main
2991 #include "gbl-ctors.h"
2992 /* Some systems use __main in a way incompatible with its use in gcc, in these
2993 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2994 give the same symbol without quotes for an alternative entry point. You
2995 must define both, or neither. */
2996 #ifndef NAME__MAIN
2997 #define NAME__MAIN "__main"
2998 #define SYMBOL__MAIN __main
2999 #endif
3001 #ifdef INIT_SECTION_ASM_OP
3002 #undef HAS_INIT_SECTION
3003 #define HAS_INIT_SECTION
3004 #endif
3006 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
3008 /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
3009 code to run constructors. In that case, we need to handle EH here, too. */
3011 #ifdef EH_FRAME_SECTION
3012 #include "frame.h"
3013 extern unsigned char __EH_FRAME_BEGIN__[];
3014 #endif
3016 /* Run all the global destructors on exit from the program. */
3018 void
3019 __do_global_dtors (void)
3021 #ifdef DO_GLOBAL_DTORS_BODY
3022 DO_GLOBAL_DTORS_BODY;
3023 #else
3024 static func_ptr *p = __DTOR_LIST__ + 1;
3025 while (*p)
3027 p++;
3028 (*(p-1)) ();
3030 #endif
3031 #if defined (EH_FRAME_SECTION) && !defined (HAS_INIT_SECTION)
3033 static int completed = 0;
3034 if (! completed)
3036 completed = 1;
3037 __deregister_frame_info (__EH_FRAME_BEGIN__);
3040 #endif
3042 #endif
3044 #ifndef HAS_INIT_SECTION
3045 /* Run all the global constructors on entry to the program. */
3047 void
3048 __do_global_ctors (void)
3050 #ifdef EH_FRAME_SECTION
3052 static struct object object;
3053 __register_frame_info (__EH_FRAME_BEGIN__, &object);
3055 #endif
3056 DO_GLOBAL_CTORS_BODY;
3057 atexit (__do_global_dtors);
3059 #endif /* no HAS_INIT_SECTION */
3061 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
3062 /* Subroutine called automatically by `main'.
3063 Compiling a global function named `main'
3064 produces an automatic call to this function at the beginning.
3066 For many systems, this routine calls __do_global_ctors.
3067 For systems which support a .init section we use the .init section
3068 to run __do_global_ctors, so we need not do anything here. */
3070 void
3071 SYMBOL__MAIN ()
3073 /* Support recursive calls to `main': run initializers just once. */
3074 static int initialized;
3075 if (! initialized)
3077 initialized = 1;
3078 __do_global_ctors ();
3081 #endif /* no HAS_INIT_SECTION or INVOKE__main */
3083 #endif /* L__main */
3084 #endif /* __CYGWIN__ */
3086 #ifdef L_ctors
3088 #include "gbl-ctors.h"
3090 /* Provide default definitions for the lists of constructors and
3091 destructors, so that we don't get linker errors. These symbols are
3092 intentionally bss symbols, so that gld and/or collect will provide
3093 the right values. */
3095 /* We declare the lists here with two elements each,
3096 so that they are valid empty lists if no other definition is loaded.
3098 If we are using the old "set" extensions to have the gnu linker
3099 collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
3100 must be in the bss/common section.
3102 Long term no port should use those extensions. But many still do. */
3103 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
3104 #if defined (ASM_OUTPUT_CONSTRUCTOR) || defined (USE_COLLECT2)
3105 func_ptr __CTOR_LIST__[2] = {0, 0};
3106 func_ptr __DTOR_LIST__[2] = {0, 0};
3107 #else
3108 func_ptr __CTOR_LIST__[2];
3109 func_ptr __DTOR_LIST__[2];
3110 #endif
3111 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
3112 #endif /* L_ctors */
3114 #ifdef L_exit
3116 #include "gbl-ctors.h"
3118 #ifdef NEED_ATEXIT
3120 #ifndef ON_EXIT
3122 # include <errno.h>
3124 static func_ptr *atexit_chain = 0;
3125 static long atexit_chain_length = 0;
3126 static volatile long last_atexit_chain_slot = -1;
3129 atexit (func_ptr func)
3131 if (++last_atexit_chain_slot == atexit_chain_length)
3133 atexit_chain_length += 32;
3134 if (atexit_chain)
3135 atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
3136 * sizeof (func_ptr));
3137 else
3138 atexit_chain = (func_ptr *) malloc (atexit_chain_length
3139 * sizeof (func_ptr));
3140 if (! atexit_chain)
3142 atexit_chain_length = 0;
3143 last_atexit_chain_slot = -1;
3144 errno = ENOMEM;
3145 return (-1);
3148 atexit_chain[last_atexit_chain_slot] = func;
3149 return (0);
3152 extern void _cleanup (void);
3153 extern void _exit (int) __attribute__ ((__noreturn__));
3155 void
3156 exit (int status)
3158 if (atexit_chain)
3160 for ( ; last_atexit_chain_slot-- >= 0; )
3162 (*atexit_chain[last_atexit_chain_slot + 1]) ();
3163 atexit_chain[last_atexit_chain_slot + 1] = 0;
3165 free (atexit_chain);
3166 atexit_chain = 0;
3168 #ifdef EXIT_BODY
3169 EXIT_BODY;
3170 #else
3171 _cleanup ();
3172 #endif
3173 _exit (status);
3176 #else /* ON_EXIT */
3178 /* Simple; we just need a wrapper for ON_EXIT. */
3180 atexit (func_ptr func)
3182 return ON_EXIT (func);
3185 #endif /* ON_EXIT */
3186 #endif /* NEED_ATEXIT */
3188 #endif /* L_exit */
3190 #ifdef L_eh
3192 #include "gthr.h"
3194 /* Shared exception handling support routines. */
3196 extern void __default_terminate (void) __attribute__ ((__noreturn__));
3198 void
3199 __default_terminate (void)
3201 abort ();
3204 void (*__terminate_func)(void) __attribute__ ((__noreturn__)) =
3205 __default_terminate;
3207 void
3208 __terminate (void)
3210 (*__terminate_func)();
3213 void *
3214 __throw_type_match (void *catch_type, void *throw_type, void *obj)
3216 #if 0
3217 printf ("__throw_type_match (): catch_type = %s, throw_type = %s\n",
3218 catch_type, throw_type);
3219 #endif
3220 if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)
3221 return obj;
3222 return 0;
3225 void
3226 __empty (void)
3231 /* Include definitions of EH context and table layout */
3233 #include "eh-common.h"
3234 #ifndef inhibit_libc
3235 #include <stdio.h>
3236 #endif
3238 /* Allocate and return a new EH context structure. */
3240 extern void __throw (void);
3242 #if __GTHREADS
3243 static void *
3244 new_eh_context (void)
3246 struct eh_full_context {
3247 struct eh_context c;
3248 void *top_elt[2];
3249 } *ehfc = (struct eh_full_context *) malloc (sizeof *ehfc);
3251 if (! ehfc)
3252 __terminate ();
3254 memset (ehfc, 0, sizeof *ehfc);
3256 ehfc->c.dynamic_handler_chain = (void **) ehfc->top_elt;
3258 /* This should optimize out entirely. This should always be true,
3259 but just in case it ever isn't, don't allow bogus code to be
3260 generated. */
3262 if ((void*)(&ehfc->c) != (void*)ehfc)
3263 __terminate ();
3265 return &ehfc->c;
3268 static __gthread_key_t eh_context_key;
3270 /* Destructor for struct eh_context. */
3271 static void
3272 eh_context_free (void *ptr)
3274 __gthread_key_dtor (eh_context_key, ptr);
3275 if (ptr)
3276 free (ptr);
3278 #endif
3280 /* Pointer to function to return EH context. */
3282 static struct eh_context *eh_context_initialize (void);
3283 static struct eh_context *eh_context_static (void);
3284 #if __GTHREADS
3285 static struct eh_context *eh_context_specific (void);
3286 #endif
3288 static struct eh_context *(*get_eh_context) (void) = &eh_context_initialize;
3290 /* Routine to get EH context.
3291 This one will simply call the function pointer. */
3293 void *
3294 __get_eh_context (void)
3296 return (void *) (*get_eh_context) ();
3299 /* Get and set the language specific info pointer. */
3301 void **
3302 __get_eh_info (void)
3304 struct eh_context *eh = (*get_eh_context) ();
3305 return &eh->info;
3308 #ifdef DWARF2_UNWIND_INFO
3309 static int dwarf_reg_size_table_initialized = 0;
3310 static char dwarf_reg_size_table[DWARF_FRAME_REGISTERS];
3312 static void
3313 init_reg_size_table (void)
3315 __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
3316 dwarf_reg_size_table_initialized = 1;
3318 #endif
3320 #if __GTHREADS
3321 static void
3322 eh_threads_initialize (void)
3324 /* Try to create the key. If it fails, revert to static method,
3325 otherwise start using thread specific EH contexts. */
3326 if (__gthread_key_create (&eh_context_key, &eh_context_free) == 0)
3327 get_eh_context = &eh_context_specific;
3328 else
3329 get_eh_context = &eh_context_static;
3331 #endif /* no __GTHREADS */
3333 /* Initialize EH context.
3334 This will be called only once, since we change GET_EH_CONTEXT
3335 pointer to another routine. */
3337 static struct eh_context *
3338 eh_context_initialize (void)
3340 #if __GTHREADS
3342 static __gthread_once_t once = __GTHREAD_ONCE_INIT;
3343 /* Make sure that get_eh_context does not point to us anymore.
3344 Some systems have dummy thread routines in their libc that
3345 return a success (Solaris 2.6 for example). */
3346 if (__gthread_once (&once, eh_threads_initialize) != 0
3347 || get_eh_context == &eh_context_initialize)
3349 /* Use static version of EH context. */
3350 get_eh_context = &eh_context_static;
3352 #ifdef DWARF2_UNWIND_INFO
3354 static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
3355 if (__gthread_once (&once_regsizes, init_reg_size_table) != 0
3356 || ! dwarf_reg_size_table_initialized)
3357 init_reg_size_table ();
3359 #endif
3361 #else /* no __GTHREADS */
3363 /* Use static version of EH context. */
3364 get_eh_context = &eh_context_static;
3366 #ifdef DWARF2_UNWIND_INFO
3367 init_reg_size_table ();
3368 #endif
3370 #endif /* no __GTHREADS */
3372 return (*get_eh_context) ();
3375 /* Return a static EH context. */
3377 static struct eh_context *
3378 eh_context_static (void)
3380 static struct eh_context eh;
3381 static int initialized;
3382 static void *top_elt[2];
3384 if (! initialized)
3386 initialized = 1;
3387 memset (&eh, 0, sizeof eh);
3388 eh.dynamic_handler_chain = top_elt;
3390 return &eh;
3393 #if __GTHREADS
3394 /* Return a thread specific EH context. */
3396 static struct eh_context *
3397 eh_context_specific (void)
3399 struct eh_context *eh;
3400 eh = (struct eh_context *) __gthread_getspecific (eh_context_key);
3401 if (! eh)
3403 eh = new_eh_context ();
3404 if (__gthread_setspecific (eh_context_key, (void *) eh) != 0)
3405 __terminate ();
3408 return eh;
3410 #endif __GTHREADS
3412 /* Support routines for setjmp/longjmp exception handling. */
3414 /* Calls to __sjthrow are generated by the compiler when an exception
3415 is raised when using the setjmp/longjmp exception handling codegen
3416 method. */
3418 #ifdef DONT_USE_BUILTIN_SETJMP
3419 extern void longjmp (void *, int);
3420 #endif
3422 /* Routine to get the head of the current thread's dynamic handler chain
3423 use for exception handling. */
3425 void ***
3426 __get_dynamic_handler_chain (void)
3428 struct eh_context *eh = (*get_eh_context) ();
3429 return &eh->dynamic_handler_chain;
3432 /* This is used to throw an exception when the setjmp/longjmp codegen
3433 method is used for exception handling.
3435 We call __terminate if there are no handlers left. Otherwise we run the
3436 cleanup actions off the dynamic cleanup stack, and pop the top of the
3437 dynamic handler chain, and use longjmp to transfer back to the associated
3438 handler. */
3440 extern void __sjthrow (void) __attribute__ ((__noreturn__));
3442 void
3443 __sjthrow (void)
3445 struct eh_context *eh = (*get_eh_context) ();
3446 void ***dhc = &eh->dynamic_handler_chain;
3447 void *jmpbuf;
3448 void (*func)(void *, int);
3449 void *arg;
3450 /* The cleanup chain is one word into the buffer. Get the cleanup chain. */
3451 void ***cleanup = (void***)&(*dhc)[1];
3453 /* If there are any cleanups in the chain, run them now. */
3454 if (cleanup[0])
3456 double store[200];
3457 void **buf = (void**)store;
3458 buf[1] = 0;
3459 buf[0] = (*dhc);
3461 /* try { */
3462 #ifdef DONT_USE_BUILTIN_SETJMP
3463 if (! setjmp (&buf[2]))
3464 #else
3465 if (! __builtin_setjmp (&buf[2]))
3466 #endif
3468 *dhc = buf;
3469 while (cleanup[0])
3471 func = (void(*)(void*, int))cleanup[0][1];
3472 arg = (void*)cleanup[0][2];
3474 /* Update this before running the cleanup. */
3475 cleanup[0] = (void **)cleanup[0][0];
3477 (*func)(arg, 2);
3479 *dhc = buf[0];
3481 /* catch (...) */
3482 else
3484 __terminate ();
3488 /* We must call terminate if we try and rethrow an exception, when
3489 there is no exception currently active and when there are no
3490 handlers left. */
3491 if (! eh->info || (*dhc)[0] == 0)
3492 __terminate ();
3494 /* Find the jmpbuf associated with the top element of the dynamic
3495 handler chain. The jumpbuf starts two words into the buffer. */
3496 jmpbuf = &(*dhc)[2];
3498 /* Then we pop the top element off the dynamic handler chain. */
3499 *dhc = (void**)(*dhc)[0];
3501 /* And then we jump to the handler. */
3503 #ifdef DONT_USE_BUILTIN_SETJMP
3504 longjmp (jmpbuf, 1);
3505 #else
3506 __builtin_longjmp (jmpbuf, 1);
3507 #endif
3510 /* Run cleanups on the dynamic cleanup stack for the current dynamic
3511 handler, then pop the handler off the dynamic handler stack, and
3512 then throw. This is used to skip the first handler, and transfer
3513 control to the next handler in the dynamic handler stack. */
3515 extern void __sjpopnthrow (void) __attribute__ ((__noreturn__));
3517 void
3518 __sjpopnthrow (void)
3520 struct eh_context *eh = (*get_eh_context) ();
3521 void ***dhc = &eh->dynamic_handler_chain;
3522 void (*func)(void *, int);
3523 void *arg;
3524 /* The cleanup chain is one word into the buffer. Get the cleanup chain. */
3525 void ***cleanup = (void***)&(*dhc)[1];
3527 /* If there are any cleanups in the chain, run them now. */
3528 if (cleanup[0])
3530 double store[200];
3531 void **buf = (void**)store;
3532 buf[1] = 0;
3533 buf[0] = (*dhc);
3535 /* try { */
3536 #ifdef DONT_USE_BUILTIN_SETJMP
3537 if (! setjmp (&buf[2]))
3538 #else
3539 if (! __builtin_setjmp (&buf[2]))
3540 #endif
3542 *dhc = buf;
3543 while (cleanup[0])
3545 func = (void(*)(void*, int))cleanup[0][1];
3546 arg = (void*)cleanup[0][2];
3548 /* Update this before running the cleanup. */
3549 cleanup[0] = (void **)cleanup[0][0];
3551 (*func)(arg, 2);
3553 *dhc = buf[0];
3555 /* catch (...) */
3556 else
3558 __terminate ();
3562 /* Then we pop the top element off the dynamic handler chain. */
3563 *dhc = (void**)(*dhc)[0];
3565 __sjthrow ();
3568 /* Support code for all exception region-based exception handling. */
3571 __eh_rtime_match (void *rtime)
3573 void *info;
3574 __eh_matcher matcher;
3575 void *ret;
3577 info = *(__get_eh_info ());
3578 matcher = ((__eh_info *)info)->match_function;
3579 if (! matcher)
3581 #ifndef inhibit_libc
3582 fprintf (stderr, "Internal Compiler Bug: No runtime type matcher.");
3583 #endif
3584 return 0;
3586 ret = (*matcher) (info, rtime, (void *)0);
3587 return (ret != NULL);
3590 /* This value identifies the place from which an exception is being
3591 thrown. */
3593 #ifdef EH_TABLE_LOOKUP
3595 EH_TABLE_LOOKUP
3597 #else
3599 #ifdef DWARF2_UNWIND_INFO
3601 /* Return the table version of an exception descriptor */
3603 short
3604 __get_eh_table_version (exception_descriptor *table)
3606 return table->lang.version;
3609 /* Return the originating table language of an exception descriptor */
3611 short
3612 __get_eh_table_language (exception_descriptor *table)
3614 return table->lang.language;
3617 /* This routine takes a PC and a pointer to the exception region TABLE for
3618 its translation unit, and returns the address of the exception handler
3619 associated with the closest exception table handler entry associated
3620 with that PC, or 0 if there are no table entries the PC fits in.
3622 In the advent of a tie, we have to give the last entry, as it represents
3623 an inner block. */
3625 static void *
3626 old_find_exception_handler (void *pc, old_exception_table *table)
3628 if (table)
3630 int pos;
3631 int best = -1;
3633 /* We can't do a binary search because the table isn't guaranteed
3634 to be sorted from function to function. */
3635 for (pos = 0; table[pos].start_region != (void *) -1; ++pos)
3637 if (table[pos].start_region <= pc && table[pos].end_region > pc)
3639 /* This can apply. Make sure it is at least as small as
3640 the previous best. */
3641 if (best == -1 || (table[pos].end_region <= table[best].end_region
3642 && table[pos].start_region >= table[best].start_region))
3643 best = pos;
3645 /* But it is sorted by starting PC within a function. */
3646 else if (best >= 0 && table[pos].start_region > pc)
3647 break;
3649 if (best != -1)
3650 return table[best].exception_handler;
3653 return (void *) 0;
3656 /* find_exception_handler finds the correct handler, if there is one, to
3657 handle an exception.
3658 returns a pointer to the handler which controlled should be transferred
3659 to, or NULL if there is nothing left.
3660 Parameters:
3661 PC - pc where the exception originates. If this is a rethrow,
3662 then this starts out as a pointer to the exception table
3663 entry we wish to rethrow out of.
3664 TABLE - exception table for the current module.
3665 EH_INFO - eh info pointer for this exception.
3666 RETHROW - 1 if this is a rethrow. (see incoming value of PC).
3667 CLEANUP - returned flag indicating whether this is a cleanup handler.
3669 static void *
3670 find_exception_handler (void *pc, exception_descriptor *table,
3671 __eh_info *eh_info, int rethrow, int *cleanup)
3674 void *retval = NULL;
3675 *cleanup = 1;
3676 if (table)
3678 int pos = 0;
3679 /* The new model assumed the table is sorted inner-most out so the
3680 first region we find which matches is the correct one */
3682 exception_table *tab = &(table->table[0]);
3684 /* Subtract 1 from the PC to avoid hitting the next region */
3685 if (rethrow)
3687 /* pc is actually the region table entry to rethrow out of */
3688 pos = ((exception_table *) pc) - tab;
3689 pc = ((exception_table *) pc)->end_region - 1;
3691 /* The label is always on the LAST handler entry for a region,
3692 so we know the next entry is a different region, even if the
3693 addresses are the same. Make sure its not end of table tho. */
3694 if (tab[pos].start_region != (void *) -1)
3695 pos++;
3697 else
3698 pc--;
3700 /* We can't do a binary search because the table is in inner-most
3701 to outermost address ranges within functions */
3702 for ( ; tab[pos].start_region != (void *) -1; pos++)
3704 if (tab[pos].start_region <= pc && tab[pos].end_region > pc)
3706 if (tab[pos].match_info)
3708 __eh_matcher matcher = eh_info->match_function;
3709 /* match info but no matcher is NOT a match */
3710 if (matcher)
3712 void *ret = (*matcher)((void *) eh_info,
3713 tab[pos].match_info, table);
3714 if (ret)
3716 if (retval == NULL)
3717 retval = tab[pos].exception_handler;
3718 *cleanup = 0;
3719 break;
3723 else
3725 if (retval == NULL)
3726 retval = tab[pos].exception_handler;
3731 return retval;
3733 #endif /* DWARF2_UNWIND_INFO */
3734 #endif /* EH_TABLE_LOOKUP */
3736 #ifdef DWARF2_UNWIND_INFO
3737 /* Support code for exception handling using static unwind information. */
3739 #include "frame.h"
3741 /* This type is used in get_reg and put_reg to deal with ABIs where a void*
3742 is smaller than a word, such as the Irix 6 n32 ABI. We cast twice to
3743 avoid a warning about casting between int and pointer of different
3744 sizes. */
3746 typedef int ptr_type __attribute__ ((mode (pointer)));
3748 #ifdef INCOMING_REGNO
3749 /* Is the saved value for register REG in frame UDATA stored in a register
3750 window in the previous frame? */
3752 /* ??? The Sparc INCOMING_REGNO references TARGET_FLAT. This allows us
3753 to use the macro here. One wonders, though, that perhaps TARGET_FLAT
3754 compiled functions won't work with the frame-unwind stuff here.
3755 Perhaps the entireity of in_reg_window should be conditional on having
3756 seen a DW_CFA_GNU_window_save? */
3757 #define target_flags 0
3759 static int
3760 in_reg_window (int reg, frame_state *udata)
3762 if (udata->saved[reg] == REG_SAVED_REG)
3763 return INCOMING_REGNO (reg) == reg;
3764 if (udata->saved[reg] != REG_SAVED_OFFSET)
3765 return 0;
3767 #ifdef STACK_GROWS_DOWNWARD
3768 return udata->reg_or_offset[reg] > 0;
3769 #else
3770 return udata->reg_or_offset[reg] < 0;
3771 #endif
3773 #else
3774 static inline int
3775 in_reg_window (int reg __attribute__ ((__unused__)),
3776 frame_state *udata __attribute__ ((__unused__)))
3778 return 0;
3780 #endif /* INCOMING_REGNO */
3782 /* Get the address of register REG as saved in UDATA, where SUB_UDATA is a
3783 frame called by UDATA or 0. */
3785 static word_type *
3786 get_reg_addr (unsigned reg, frame_state *udata, frame_state *sub_udata)
3788 while (udata->saved[reg] == REG_SAVED_REG)
3790 reg = udata->reg_or_offset[reg];
3791 if (in_reg_window (reg, udata))
3793 udata = sub_udata;
3794 sub_udata = NULL;
3797 if (udata->saved[reg] == REG_SAVED_OFFSET)
3798 return (word_type *)(udata->cfa + udata->reg_or_offset[reg]);
3799 else
3800 abort ();
3803 /* Get the value of register REG as saved in UDATA, where SUB_UDATA is a
3804 frame called by UDATA or 0. */
3806 static inline void *
3807 get_reg (unsigned reg, frame_state *udata, frame_state *sub_udata)
3809 return (void *)(ptr_type) *get_reg_addr (reg, udata, sub_udata);
3812 /* Overwrite the saved value for register REG in frame UDATA with VAL. */
3814 static inline void
3815 put_reg (unsigned reg, void *val, frame_state *udata)
3817 *get_reg_addr (reg, udata, NULL) = (word_type)(ptr_type) val;
3820 /* Copy the saved value for register REG from frame UDATA to frame
3821 TARGET_UDATA. Unlike the previous two functions, this can handle
3822 registers that are not one word large. */
3824 static void
3825 copy_reg (unsigned reg, frame_state *udata, frame_state *target_udata)
3827 word_type *preg = get_reg_addr (reg, udata, NULL);
3828 word_type *ptreg = get_reg_addr (reg, target_udata, NULL);
3830 memcpy (ptreg, preg, dwarf_reg_size_table [reg]);
3833 /* Retrieve the return address for frame UDATA. */
3835 static inline void *
3836 get_return_addr (frame_state *udata, frame_state *sub_udata)
3838 return __builtin_extract_return_addr
3839 (get_reg (udata->retaddr_column, udata, sub_udata));
3842 /* Overwrite the return address for frame UDATA with VAL. */
3844 static inline void
3845 put_return_addr (void *val, frame_state *udata)
3847 val = __builtin_frob_return_addr (val);
3848 put_reg (udata->retaddr_column, val, udata);
3851 /* Given the current frame UDATA and its return address PC, return the
3852 information about the calling frame in CALLER_UDATA. */
3854 static void *
3855 next_stack_level (void *pc, frame_state *udata, frame_state *caller_udata)
3857 caller_udata = __frame_state_for (pc, caller_udata);
3858 if (! caller_udata)
3859 return 0;
3861 /* Now go back to our caller's stack frame. If our caller's CFA register
3862 was saved in our stack frame, restore it; otherwise, assume the CFA
3863 register is SP and restore it to our CFA value. */
3864 if (udata->saved[caller_udata->cfa_reg])
3865 caller_udata->cfa = get_reg (caller_udata->cfa_reg, udata, 0);
3866 else
3867 caller_udata->cfa = udata->cfa;
3868 caller_udata->cfa += caller_udata->cfa_offset;
3870 return caller_udata;
3873 /* Hook to call before __terminate if only cleanup handlers remain. */
3874 void
3875 __unwinding_cleanup (void)
3879 /* throw_helper performs some of the common grunt work for a throw. This
3880 routine is called by throw and rethrows. This is pretty much split
3881 out from the old __throw routine. An addition has been added which allows
3882 for a dummy call to a routine __unwinding_cleanup() when there are nothing
3883 but cleanups remaining. This allows a debugger to examine the state
3884 at which the throw was executed, before any cleanups, rather than
3885 at the terminate point after the stack has been unwound.
3887 EH is the current eh_context structure.
3888 PC is the address of the call to __throw.
3889 MY_UDATA is the unwind information for __throw.
3890 OFFSET_P is where we return the SP adjustment offset. */
3892 static void *
3893 throw_helper (struct eh_context *eh, void *pc, frame_state *my_udata,
3894 long *offset_p)
3896 frame_state ustruct2, *udata = &ustruct2;
3897 frame_state ustruct;
3898 frame_state *sub_udata = &ustruct;
3899 void *saved_pc = pc;
3900 void *handler;
3901 void *handler_p = 0;
3902 void *pc_p = 0;
3903 frame_state saved_ustruct;
3904 int new_eh_model;
3905 int cleanup = 0;
3906 int only_cleanup = 0;
3907 int rethrow = 0;
3908 int saved_state = 0;
3909 long args_size;
3910 __eh_info *eh_info = (__eh_info *)eh->info;
3912 /* Do we find a handler based on a re-throw PC? */
3913 if (eh->table_index != (void *) 0)
3914 rethrow = 1;
3916 memcpy (udata, my_udata, sizeof (*udata));
3918 handler = (void *) 0;
3919 for (;;)
3921 frame_state *p = udata;
3922 udata = next_stack_level (pc, udata, sub_udata);
3923 sub_udata = p;
3925 /* If we couldn't find the next frame, we lose. */
3926 if (! udata)
3927 break;
3929 if (udata->eh_ptr == NULL)
3930 new_eh_model = 0;
3931 else
3932 new_eh_model = (((exception_descriptor *)(udata->eh_ptr))->
3933 runtime_id_field == NEW_EH_RUNTIME);
3935 if (rethrow)
3937 rethrow = 0;
3938 handler = find_exception_handler (eh->table_index, udata->eh_ptr,
3939 eh_info, 1, &cleanup);
3940 eh->table_index = (void *)0;
3942 else
3943 if (new_eh_model)
3944 handler = find_exception_handler (pc, udata->eh_ptr, eh_info,
3945 0, &cleanup);
3946 else
3947 handler = old_find_exception_handler (pc, udata->eh_ptr);
3949 /* If we found one, we can stop searching, if its not a cleanup.
3950 for cleanups, we save the state, and keep looking. This allows
3951 us to call a debug hook if there are nothing but cleanups left. */
3952 if (handler)
3954 if (cleanup)
3956 if (!saved_state)
3958 saved_ustruct = *udata;
3959 handler_p = handler;
3960 pc_p = pc;
3961 saved_state = 1;
3962 only_cleanup = 1;
3965 else
3967 only_cleanup = 0;
3968 break;
3972 /* Otherwise, we continue searching. We subtract 1 from PC to avoid
3973 hitting the beginning of the next region. */
3974 pc = get_return_addr (udata, sub_udata) - 1;
3977 if (saved_state)
3979 udata = &saved_ustruct;
3980 handler = handler_p;
3981 pc = pc_p;
3982 if (only_cleanup)
3983 __unwinding_cleanup ();
3986 /* If we haven't found a handler by now, this is an unhandled
3987 exception. */
3988 if (! handler)
3989 __terminate();
3991 eh->handler_label = handler;
3993 args_size = udata->args_size;
3995 if (pc == saved_pc)
3996 /* We found a handler in the throw context, no need to unwind. */
3997 udata = my_udata;
3998 else
4000 int i;
4002 /* Unwind all the frames between this one and the handler by copying
4003 their saved register values into our register save slots. */
4005 /* Remember the PC where we found the handler. */
4006 void *handler_pc = pc;
4008 /* Start from the throw context again. */
4009 pc = saved_pc;
4010 memcpy (udata, my_udata, sizeof (*udata));
4012 while (pc != handler_pc)
4014 frame_state *p = udata;
4015 udata = next_stack_level (pc, udata, sub_udata);
4016 sub_udata = p;
4018 for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
4019 if (i != udata->retaddr_column && udata->saved[i])
4021 /* If you modify the saved value of the return address
4022 register on the SPARC, you modify the return address for
4023 your caller's frame. Don't do that here, as it will
4024 confuse get_return_addr. */
4025 if (in_reg_window (i, udata)
4026 && udata->saved[udata->retaddr_column] == REG_SAVED_REG
4027 && udata->reg_or_offset[udata->retaddr_column] == i)
4028 continue;
4029 copy_reg (i, udata, my_udata);
4032 pc = get_return_addr (udata, sub_udata) - 1;
4035 /* But we do need to update the saved return address register from
4036 the last frame we unwind, or the handler frame will have the wrong
4037 return address. */
4038 if (udata->saved[udata->retaddr_column] == REG_SAVED_REG)
4040 i = udata->reg_or_offset[udata->retaddr_column];
4041 if (in_reg_window (i, udata))
4042 copy_reg (i, udata, my_udata);
4045 /* udata now refers to the frame called by the handler frame. */
4047 /* We adjust SP by the difference between __throw's CFA and the CFA for
4048 the frame called by the handler frame, because those CFAs correspond
4049 to the SP values at the two call sites. We need to further adjust by
4050 the args_size of the handler frame itself to get the handler frame's
4051 SP from before the args were pushed for that call. */
4052 #ifdef STACK_GROWS_DOWNWARD
4053 *offset_p = udata->cfa - my_udata->cfa + args_size;
4054 #else
4055 *offset_p = my_udata->cfa - udata->cfa - args_size;
4056 #endif
4058 return handler;
4062 /* We first search for an exception handler, and if we don't find
4063 it, we call __terminate on the current stack frame so that we may
4064 use the debugger to walk the stack and understand why no handler
4065 was found.
4067 If we find one, then we unwind the frames down to the one that
4068 has the handler and transfer control into the handler. */
4070 /*extern void __throw(void) __attribute__ ((__noreturn__));*/
4072 void
4073 __throw (void)
4075 struct eh_context *eh = (*get_eh_context) ();
4076 void *pc, *handler;
4077 long offset;
4079 /* XXX maybe make my_ustruct static so we don't have to look it up for
4080 each throw. */
4081 frame_state my_ustruct, *my_udata = &my_ustruct;
4083 /* This is required for C++ semantics. We must call terminate if we
4084 try and rethrow an exception, when there is no exception currently
4085 active. */
4086 if (! eh->info)
4087 __terminate ();
4089 /* Start at our stack frame. */
4090 label:
4091 my_udata = __frame_state_for (&&label, my_udata);
4092 if (! my_udata)
4093 __terminate ();
4095 /* We need to get the value from the CFA register. */
4096 my_udata->cfa = __builtin_dwarf_cfa ();
4098 /* Do any necessary initialization to access arbitrary stack frames.
4099 On the SPARC, this means flushing the register windows. */
4100 __builtin_unwind_init ();
4102 /* Now reset pc to the right throw point. */
4103 pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
4105 handler = throw_helper (eh, pc, my_udata, &offset);
4107 /* Now go! */
4109 __builtin_eh_return ((void *)eh, offset, handler);
4111 /* Epilogue: restore the handler frame's register values and return
4112 to the stub. */
4115 /*extern void __rethrow(void *) __attribute__ ((__noreturn__));*/
4117 void
4118 __rethrow (void *index)
4120 struct eh_context *eh = (*get_eh_context) ();
4121 void *pc, *handler;
4122 long offset;
4124 /* XXX maybe make my_ustruct static so we don't have to look it up for
4125 each throw. */
4126 frame_state my_ustruct, *my_udata = &my_ustruct;
4128 /* This is required for C++ semantics. We must call terminate if we
4129 try and rethrow an exception, when there is no exception currently
4130 active. */
4131 if (! eh->info)
4132 __terminate ();
4134 /* This is the table index we want to rethrow from. The value of
4135 the END_REGION label is used for the PC of the throw, and the
4136 search begins with the next table entry. */
4137 eh->table_index = index;
4139 /* Start at our stack frame. */
4140 label:
4141 my_udata = __frame_state_for (&&label, my_udata);
4142 if (! my_udata)
4143 __terminate ();
4145 /* We need to get the value from the CFA register. */
4146 my_udata->cfa = __builtin_dwarf_cfa ();
4148 /* Do any necessary initialization to access arbitrary stack frames.
4149 On the SPARC, this means flushing the register windows. */
4150 __builtin_unwind_init ();
4152 /* Now reset pc to the right throw point. */
4153 pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
4155 handler = throw_helper (eh, pc, my_udata, &offset);
4157 /* Now go! */
4159 __builtin_eh_return ((void *)eh, offset, handler);
4161 /* Epilogue: restore the handler frame's register values and return
4162 to the stub. */
4164 #endif /* DWARF2_UNWIND_INFO */
4166 #endif /* L_eh */
4168 #ifdef L_pure
4169 #ifndef inhibit_libc
4170 /* This gets us __GNU_LIBRARY__. */
4171 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
4172 #include <stdio.h>
4174 #ifdef __GNU_LIBRARY__
4175 /* Avoid forcing the library's meaning of `write' on the user program
4176 by using the "internal" name (for use within the library) */
4177 #define write(fd, buf, n) __write((fd), (buf), (n))
4178 #endif
4179 #endif /* inhibit_libc */
4181 #define MESSAGE "pure virtual method called\n"
4183 extern void __terminate (void) __attribute__ ((__noreturn__));
4185 void
4186 __pure_virtual (void)
4188 #ifndef inhibit_libc
4189 write (2, MESSAGE, sizeof (MESSAGE) - 1);
4190 #endif
4191 __terminate ();
4193 #endif