]> gcc.gnu.org Git - gcc.git/blob - gcc/libgcc2.c
Update FSF address.
[gcc.git] / gcc / libgcc2.c
1 /* More subroutines needed by GCC output code on some machines. */
2 /* Compile this one with gcc. */
3 /* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22 /* As a special exception, if you link this library with other files,
23 some of which are compiled with GCC, to produce an executable,
24 this library does not by itself cause the resulting executable
25 to be covered by the GNU General Public License.
26 This exception does not however invalidate any other reasons why
27 the executable file might be covered by the GNU General Public License. */
28
29 /* It is incorrect to include config.h here, because this file is being
30 compiled for the target, and hence definitions concerning only the host
31 do not apply. */
32
33 #include "tconfig.h"
34 #include "machmode.h"
35 #include "defaults.h"
36 #ifndef L_trampoline
37 #include <stddef.h>
38 #endif
39
40 /* Don't use `fancy_abort' here even if config.h says to use it. */
41 #ifdef abort
42 #undef abort
43 #endif
44
45 #if (SUPPORTS_WEAK == 1) && defined (ASM_OUTPUT_DEF)
46 #define WEAK_ALIAS
47 #endif
48
49 /* Permit the tm.h file to select the endianness to use just for this
50 file. This is used when the endianness is determined when the
51 compiler is run. */
52
53 #ifndef LIBGCC2_WORDS_BIG_ENDIAN
54 #define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
55 #endif
56
57 /* In the first part of this file, we are interfacing to calls generated
58 by the compiler itself. These calls pass values into these routines
59 which have very specific modes (rather than very specific types), and
60 these compiler-generated calls also expect any return values to have
61 very specific modes (rather than very specific types). Thus, we need
62 to avoid using regular C language type names in this part of the file
63 because the sizes for those types can be configured to be anything.
64 Instead we use the following special type names. */
65
66 typedef unsigned int UQItype __attribute__ ((mode (QI)));
67 typedef int SItype __attribute__ ((mode (SI)));
68 typedef unsigned int USItype __attribute__ ((mode (SI)));
69 typedef int DItype __attribute__ ((mode (DI)));
70 typedef unsigned int UDItype __attribute__ ((mode (DI)));
71
72 typedef float SFtype __attribute__ ((mode (SF)));
73 typedef float DFtype __attribute__ ((mode (DF)));
74
75 #if LONG_DOUBLE_TYPE_SIZE == 96
76 typedef float XFtype __attribute__ ((mode (XF)));
77 #endif
78 #if LONG_DOUBLE_TYPE_SIZE == 128
79 typedef float TFtype __attribute__ ((mode (TF)));
80 #endif
81
82 typedef int word_type __attribute__ ((mode (__word__)));
83
84 /* Make sure that we don't accidentally use any normal C language built-in
85 type names in the first part of this file. Instead we want to use *only*
86 the type names defined above. The following macro definitions insure
87 that if we *do* accidentally use some normal C language built-in type name,
88 we will get a syntax error. */
89
90 #define char bogus_type
91 #define short bogus_type
92 #define int bogus_type
93 #define long bogus_type
94 #define unsigned bogus_type
95 #define float bogus_type
96 #define double bogus_type
97
98 #define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
99
100 /* DIstructs are pairs of SItype values in the order determined by
101 LIBGCC2_WORDS_BIG_ENDIAN. */
102
103 #if LIBGCC2_WORDS_BIG_ENDIAN
104 struct DIstruct {SItype high, low;};
105 #else
106 struct DIstruct {SItype low, high;};
107 #endif
108
109 /* We need this union to unpack/pack DImode values, since we don't have
110 any arithmetic yet. Incoming DImode parameters are stored into the
111 `ll' field, and the unpacked result is read from the struct `s'. */
112
113 typedef union
114 {
115 struct DIstruct s;
116 DItype ll;
117 } DIunion;
118
119 #if defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_w_sdiv)
120
121 #include "longlong.h"
122
123 #endif /* udiv or mul */
124
125 extern DItype __fixunssfdi (SFtype a);
126 extern DItype __fixunsdfdi (DFtype a);
127 #if LONG_DOUBLE_TYPE_SIZE == 96
128 extern DItype __fixunsxfdi (XFtype a);
129 #endif
130 #if LONG_DOUBLE_TYPE_SIZE == 128
131 extern DItype __fixunstfdi (TFtype a);
132 #endif
133 \f
134 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
135 #if defined (L_divdi3) || defined (L_moddi3)
136 static inline
137 #endif
138 DItype
139 __negdi2 (u)
140 DItype u;
141 {
142 DIunion w;
143 DIunion uu;
144
145 uu.ll = u;
146
147 w.s.low = -uu.s.low;
148 w.s.high = -uu.s.high - ((USItype) w.s.low > 0);
149
150 return w.ll;
151 }
152 #endif
153 \f
154 #ifdef L_lshrdi3
155 DItype
156 __lshrdi3 (u, b)
157 DItype u;
158 word_type b;
159 {
160 DIunion w;
161 word_type bm;
162 DIunion uu;
163
164 if (b == 0)
165 return u;
166
167 uu.ll = u;
168
169 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
170 if (bm <= 0)
171 {
172 w.s.high = 0;
173 w.s.low = (USItype)uu.s.high >> -bm;
174 }
175 else
176 {
177 USItype carries = (USItype)uu.s.high << bm;
178 w.s.high = (USItype)uu.s.high >> b;
179 w.s.low = ((USItype)uu.s.low >> b) | carries;
180 }
181
182 return w.ll;
183 }
184 #endif
185
186 #ifdef L_ashldi3
187 DItype
188 __ashldi3 (u, b)
189 DItype u;
190 word_type b;
191 {
192 DIunion w;
193 word_type bm;
194 DIunion uu;
195
196 if (b == 0)
197 return u;
198
199 uu.ll = u;
200
201 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
202 if (bm <= 0)
203 {
204 w.s.low = 0;
205 w.s.high = (USItype)uu.s.low << -bm;
206 }
207 else
208 {
209 USItype carries = (USItype)uu.s.low >> bm;
210 w.s.low = (USItype)uu.s.low << b;
211 w.s.high = ((USItype)uu.s.high << b) | carries;
212 }
213
214 return w.ll;
215 }
216 #endif
217
218 #ifdef L_ashrdi3
219 DItype
220 __ashrdi3 (u, b)
221 DItype u;
222 word_type b;
223 {
224 DIunion w;
225 word_type bm;
226 DIunion uu;
227
228 if (b == 0)
229 return u;
230
231 uu.ll = u;
232
233 bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
234 if (bm <= 0)
235 {
236 /* w.s.high = 1..1 or 0..0 */
237 w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
238 w.s.low = uu.s.high >> -bm;
239 }
240 else
241 {
242 USItype carries = (USItype)uu.s.high << bm;
243 w.s.high = uu.s.high >> b;
244 w.s.low = ((USItype)uu.s.low >> b) | carries;
245 }
246
247 return w.ll;
248 }
249 #endif
250 \f
251 #ifdef L_ffsdi2
252 DItype
253 __ffsdi2 (u)
254 DItype u;
255 {
256 DIunion uu, w;
257 uu.ll = u;
258 w.s.high = 0;
259 w.s.low = ffs (uu.s.low);
260 if (w.s.low != 0)
261 return w.ll;
262 w.s.low = ffs (uu.s.high);
263 if (w.s.low != 0)
264 {
265 w.s.low += BITS_PER_UNIT * sizeof (SItype);
266 return w.ll;
267 }
268 return w.ll;
269 }
270 #endif
271 \f
272 #ifdef L_muldi3
273 DItype
274 __muldi3 (u, v)
275 DItype u, v;
276 {
277 DIunion w;
278 DIunion uu, vv;
279
280 uu.ll = u,
281 vv.ll = v;
282
283 w.ll = __umulsidi3 (uu.s.low, vv.s.low);
284 w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
285 + (USItype) uu.s.high * (USItype) vv.s.low);
286
287 return w.ll;
288 }
289 #endif
290 \f
291 #ifdef L_udiv_w_sdiv
292 USItype
293 __udiv_w_sdiv (rp, a1, a0, d)
294 USItype *rp, a1, a0, d;
295 {
296 USItype q, r;
297 USItype c0, c1, b1;
298
299 if ((SItype) d >= 0)
300 {
301 if (a1 < d - a1 - (a0 >> (SI_TYPE_SIZE - 1)))
302 {
303 /* dividend, divisor, and quotient are nonnegative */
304 sdiv_qrnnd (q, r, a1, a0, d);
305 }
306 else
307 {
308 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
309 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (SI_TYPE_SIZE - 1));
310 /* Divide (c1*2^32 + c0) by d */
311 sdiv_qrnnd (q, r, c1, c0, d);
312 /* Add 2^31 to quotient */
313 q += (USItype) 1 << (SI_TYPE_SIZE - 1);
314 }
315 }
316 else
317 {
318 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
319 c1 = a1 >> 1; /* A/2 */
320 c0 = (a1 << (SI_TYPE_SIZE - 1)) + (a0 >> 1);
321
322 if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
323 {
324 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
325
326 r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
327 if ((d & 1) != 0)
328 {
329 if (r >= q)
330 r = r - q;
331 else if (q - r <= d)
332 {
333 r = r - q + d;
334 q--;
335 }
336 else
337 {
338 r = r - q + 2*d;
339 q -= 2;
340 }
341 }
342 }
343 else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
344 {
345 c1 = (b1 - 1) - c1;
346 c0 = ~c0; /* logical NOT */
347
348 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
349
350 q = ~q; /* (A/2)/b1 */
351 r = (b1 - 1) - r;
352
353 r = 2*r + (a0 & 1); /* A/(2*b1) */
354
355 if ((d & 1) != 0)
356 {
357 if (r >= q)
358 r = r - q;
359 else if (q - r <= d)
360 {
361 r = r - q + d;
362 q--;
363 }
364 else
365 {
366 r = r - q + 2*d;
367 q -= 2;
368 }
369 }
370 }
371 else /* Implies c1 = b1 */
372 { /* Hence a1 = d - 1 = 2*b1 - 1 */
373 if (a0 >= -d)
374 {
375 q = -1;
376 r = a0 + d;
377 }
378 else
379 {
380 q = -2;
381 r = a0 + 2*d;
382 }
383 }
384 }
385
386 *rp = r;
387 return q;
388 }
389 #endif
390 \f
391 #ifdef L_udivmoddi4
392 static const UQItype __clz_tab[] =
393 {
394 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,
395 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,
396 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,
397 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,
398 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,
399 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,
400 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,
401 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,
402 };
403
404 UDItype
405 __udivmoddi4 (n, d, rp)
406 UDItype n, d;
407 UDItype *rp;
408 {
409 DIunion ww;
410 DIunion nn, dd;
411 DIunion rr;
412 USItype d0, d1, n0, n1, n2;
413 USItype q0, q1;
414 USItype b, bm;
415
416 nn.ll = n;
417 dd.ll = d;
418
419 d0 = dd.s.low;
420 d1 = dd.s.high;
421 n0 = nn.s.low;
422 n1 = nn.s.high;
423
424 #if !UDIV_NEEDS_NORMALIZATION
425 if (d1 == 0)
426 {
427 if (d0 > n1)
428 {
429 /* 0q = nn / 0D */
430
431 udiv_qrnnd (q0, n0, n1, n0, d0);
432 q1 = 0;
433
434 /* Remainder in n0. */
435 }
436 else
437 {
438 /* qq = NN / 0d */
439
440 if (d0 == 0)
441 d0 = 1 / d0; /* Divide intentionally by zero. */
442
443 udiv_qrnnd (q1, n1, 0, n1, d0);
444 udiv_qrnnd (q0, n0, n1, n0, d0);
445
446 /* Remainder in n0. */
447 }
448
449 if (rp != 0)
450 {
451 rr.s.low = n0;
452 rr.s.high = 0;
453 *rp = rr.ll;
454 }
455 }
456
457 #else /* UDIV_NEEDS_NORMALIZATION */
458
459 if (d1 == 0)
460 {
461 if (d0 > n1)
462 {
463 /* 0q = nn / 0D */
464
465 count_leading_zeros (bm, d0);
466
467 if (bm != 0)
468 {
469 /* Normalize, i.e. make the most significant bit of the
470 denominator set. */
471
472 d0 = d0 << bm;
473 n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
474 n0 = n0 << bm;
475 }
476
477 udiv_qrnnd (q0, n0, n1, n0, d0);
478 q1 = 0;
479
480 /* Remainder in n0 >> bm. */
481 }
482 else
483 {
484 /* qq = NN / 0d */
485
486 if (d0 == 0)
487 d0 = 1 / d0; /* Divide intentionally by zero. */
488
489 count_leading_zeros (bm, d0);
490
491 if (bm == 0)
492 {
493 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
494 conclude (the most significant bit of n1 is set) /\ (the
495 leading quotient digit q1 = 1).
496
497 This special case is necessary, not an optimization.
498 (Shifts counts of SI_TYPE_SIZE are undefined.) */
499
500 n1 -= d0;
501 q1 = 1;
502 }
503 else
504 {
505 /* Normalize. */
506
507 b = SI_TYPE_SIZE - bm;
508
509 d0 = d0 << bm;
510 n2 = n1 >> b;
511 n1 = (n1 << bm) | (n0 >> b);
512 n0 = n0 << bm;
513
514 udiv_qrnnd (q1, n1, n2, n1, d0);
515 }
516
517 /* n1 != d0... */
518
519 udiv_qrnnd (q0, n0, n1, n0, d0);
520
521 /* Remainder in n0 >> bm. */
522 }
523
524 if (rp != 0)
525 {
526 rr.s.low = n0 >> bm;
527 rr.s.high = 0;
528 *rp = rr.ll;
529 }
530 }
531 #endif /* UDIV_NEEDS_NORMALIZATION */
532
533 else
534 {
535 if (d1 > n1)
536 {
537 /* 00 = nn / DD */
538
539 q0 = 0;
540 q1 = 0;
541
542 /* Remainder in n1n0. */
543 if (rp != 0)
544 {
545 rr.s.low = n0;
546 rr.s.high = n1;
547 *rp = rr.ll;
548 }
549 }
550 else
551 {
552 /* 0q = NN / dd */
553
554 count_leading_zeros (bm, d1);
555 if (bm == 0)
556 {
557 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
558 conclude (the most significant bit of n1 is set) /\ (the
559 quotient digit q0 = 0 or 1).
560
561 This special case is necessary, not an optimization. */
562
563 /* The condition on the next line takes advantage of that
564 n1 >= d1 (true due to program flow). */
565 if (n1 > d1 || n0 >= d0)
566 {
567 q0 = 1;
568 sub_ddmmss (n1, n0, n1, n0, d1, d0);
569 }
570 else
571 q0 = 0;
572
573 q1 = 0;
574
575 if (rp != 0)
576 {
577 rr.s.low = n0;
578 rr.s.high = n1;
579 *rp = rr.ll;
580 }
581 }
582 else
583 {
584 USItype m1, m0;
585 /* Normalize. */
586
587 b = SI_TYPE_SIZE - bm;
588
589 d1 = (d1 << bm) | (d0 >> b);
590 d0 = d0 << bm;
591 n2 = n1 >> b;
592 n1 = (n1 << bm) | (n0 >> b);
593 n0 = n0 << bm;
594
595 udiv_qrnnd (q0, n1, n2, n1, d1);
596 umul_ppmm (m1, m0, q0, d0);
597
598 if (m1 > n1 || (m1 == n1 && m0 > n0))
599 {
600 q0--;
601 sub_ddmmss (m1, m0, m1, m0, d1, d0);
602 }
603
604 q1 = 0;
605
606 /* Remainder in (n1n0 - m1m0) >> bm. */
607 if (rp != 0)
608 {
609 sub_ddmmss (n1, n0, n1, n0, m1, m0);
610 rr.s.low = (n1 << b) | (n0 >> bm);
611 rr.s.high = n1 >> bm;
612 *rp = rr.ll;
613 }
614 }
615 }
616 }
617
618 ww.s.low = q0;
619 ww.s.high = q1;
620 return ww.ll;
621 }
622 #endif
623
624 #ifdef L_divdi3
625 UDItype __udivmoddi4 ();
626
627 DItype
628 __divdi3 (u, v)
629 DItype u, v;
630 {
631 word_type c = 0;
632 DIunion uu, vv;
633 DItype w;
634
635 uu.ll = u;
636 vv.ll = v;
637
638 if (uu.s.high < 0)
639 c = ~c,
640 uu.ll = __negdi2 (uu.ll);
641 if (vv.s.high < 0)
642 c = ~c,
643 vv.ll = __negdi2 (vv.ll);
644
645 w = __udivmoddi4 (uu.ll, vv.ll, (UDItype *) 0);
646 if (c)
647 w = __negdi2 (w);
648
649 return w;
650 }
651 #endif
652
653 #ifdef L_moddi3
654 UDItype __udivmoddi4 ();
655 DItype
656 __moddi3 (u, v)
657 DItype u, v;
658 {
659 word_type c = 0;
660 DIunion uu, vv;
661 DItype w;
662
663 uu.ll = u;
664 vv.ll = v;
665
666 if (uu.s.high < 0)
667 c = ~c,
668 uu.ll = __negdi2 (uu.ll);
669 if (vv.s.high < 0)
670 vv.ll = __negdi2 (vv.ll);
671
672 (void) __udivmoddi4 (uu.ll, vv.ll, &w);
673 if (c)
674 w = __negdi2 (w);
675
676 return w;
677 }
678 #endif
679
680 #ifdef L_umoddi3
681 UDItype __udivmoddi4 ();
682 UDItype
683 __umoddi3 (u, v)
684 UDItype u, v;
685 {
686 UDItype w;
687
688 (void) __udivmoddi4 (u, v, &w);
689
690 return w;
691 }
692 #endif
693
694 #ifdef L_udivdi3
695 UDItype __udivmoddi4 ();
696 UDItype
697 __udivdi3 (n, d)
698 UDItype n, d;
699 {
700 return __udivmoddi4 (n, d, (UDItype *) 0);
701 }
702 #endif
703 \f
704 #ifdef L_cmpdi2
705 word_type
706 __cmpdi2 (a, b)
707 DItype a, b;
708 {
709 DIunion au, bu;
710
711 au.ll = a, bu.ll = b;
712
713 if (au.s.high < bu.s.high)
714 return 0;
715 else if (au.s.high > bu.s.high)
716 return 2;
717 if ((USItype) au.s.low < (USItype) bu.s.low)
718 return 0;
719 else if ((USItype) au.s.low > (USItype) bu.s.low)
720 return 2;
721 return 1;
722 }
723 #endif
724
725 #ifdef L_ucmpdi2
726 word_type
727 __ucmpdi2 (a, b)
728 DItype a, b;
729 {
730 DIunion au, bu;
731
732 au.ll = a, bu.ll = b;
733
734 if ((USItype) au.s.high < (USItype) bu.s.high)
735 return 0;
736 else if ((USItype) au.s.high > (USItype) bu.s.high)
737 return 2;
738 if ((USItype) au.s.low < (USItype) bu.s.low)
739 return 0;
740 else if ((USItype) au.s.low > (USItype) bu.s.low)
741 return 2;
742 return 1;
743 }
744 #endif
745 \f
746 #if defined(L_fixunstfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
747 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
748 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
749
750 DItype
751 __fixunstfdi (a)
752 TFtype a;
753 {
754 TFtype b;
755 UDItype v;
756
757 if (a < 0)
758 return 0;
759
760 /* Compute high word of result, as a flonum. */
761 b = (a / HIGH_WORD_COEFF);
762 /* Convert that to fixed (but not to DItype!),
763 and shift it into the high word. */
764 v = (USItype) b;
765 v <<= WORD_SIZE;
766 /* Remove high part from the TFtype, leaving the low part as flonum. */
767 a -= (TFtype)v;
768 /* Convert that to fixed (but not to DItype!) and add it in.
769 Sometimes A comes out negative. This is significant, since
770 A has more bits than a long int does. */
771 if (a < 0)
772 v -= (USItype) (- a);
773 else
774 v += (USItype) a;
775 return v;
776 }
777 #endif
778
779 #if defined(L_fixtfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
780 DItype
781 __fixtfdi (a)
782 TFtype a;
783 {
784 if (a < 0)
785 return - __fixunstfdi (-a);
786 return __fixunstfdi (a);
787 }
788 #endif
789
790 #if defined(L_fixunsxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
791 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
792 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
793
794 DItype
795 __fixunsxfdi (a)
796 XFtype a;
797 {
798 XFtype b;
799 UDItype v;
800
801 if (a < 0)
802 return 0;
803
804 /* Compute high word of result, as a flonum. */
805 b = (a / HIGH_WORD_COEFF);
806 /* Convert that to fixed (but not to DItype!),
807 and shift it into the high word. */
808 v = (USItype) b;
809 v <<= WORD_SIZE;
810 /* Remove high part from the XFtype, leaving the low part as flonum. */
811 a -= (XFtype)v;
812 /* Convert that to fixed (but not to DItype!) and add it in.
813 Sometimes A comes out negative. This is significant, since
814 A has more bits than a long int does. */
815 if (a < 0)
816 v -= (USItype) (- a);
817 else
818 v += (USItype) a;
819 return v;
820 }
821 #endif
822
823 #if defined(L_fixxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
824 DItype
825 __fixxfdi (a)
826 XFtype a;
827 {
828 if (a < 0)
829 return - __fixunsxfdi (-a);
830 return __fixunsxfdi (a);
831 }
832 #endif
833
834 #ifdef L_fixunsdfdi
835 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
836 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
837
838 DItype
839 __fixunsdfdi (a)
840 DFtype a;
841 {
842 DFtype b;
843 UDItype v;
844
845 if (a < 0)
846 return 0;
847
848 /* Compute high word of result, as a flonum. */
849 b = (a / HIGH_WORD_COEFF);
850 /* Convert that to fixed (but not to DItype!),
851 and shift it into the high word. */
852 v = (USItype) b;
853 v <<= WORD_SIZE;
854 /* Remove high part from the DFtype, leaving the low part as flonum. */
855 a -= (DFtype)v;
856 /* Convert that to fixed (but not to DItype!) and add it in.
857 Sometimes A comes out negative. This is significant, since
858 A has more bits than a long int does. */
859 if (a < 0)
860 v -= (USItype) (- a);
861 else
862 v += (USItype) a;
863 return v;
864 }
865 #endif
866
867 #ifdef L_fixdfdi
868 DItype
869 __fixdfdi (a)
870 DFtype a;
871 {
872 if (a < 0)
873 return - __fixunsdfdi (-a);
874 return __fixunsdfdi (a);
875 }
876 #endif
877
878 #ifdef L_fixunssfdi
879 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
880 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
881
882 DItype
883 __fixunssfdi (SFtype original_a)
884 {
885 /* Convert the SFtype to a DFtype, because that is surely not going
886 to lose any bits. Some day someone else can write a faster version
887 that avoids converting to DFtype, and verify it really works right. */
888 DFtype a = original_a;
889 DFtype b;
890 UDItype v;
891
892 if (a < 0)
893 return 0;
894
895 /* Compute high word of result, as a flonum. */
896 b = (a / HIGH_WORD_COEFF);
897 /* Convert that to fixed (but not to DItype!),
898 and shift it into the high word. */
899 v = (USItype) b;
900 v <<= WORD_SIZE;
901 /* Remove high part from the DFtype, leaving the low part as flonum. */
902 a -= (DFtype)v;
903 /* Convert that to fixed (but not to DItype!) and add it in.
904 Sometimes A comes out negative. This is significant, since
905 A has more bits than a long int does. */
906 if (a < 0)
907 v -= (USItype) (- a);
908 else
909 v += (USItype) a;
910 return v;
911 }
912 #endif
913
914 #ifdef L_fixsfdi
915 DItype
916 __fixsfdi (SFtype a)
917 {
918 if (a < 0)
919 return - __fixunssfdi (-a);
920 return __fixunssfdi (a);
921 }
922 #endif
923
924 #if defined(L_floatdixf) && (LONG_DOUBLE_TYPE_SIZE == 96)
925 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
926 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
927 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
928
929 XFtype
930 __floatdixf (u)
931 DItype u;
932 {
933 XFtype d;
934 SItype negate = 0;
935
936 if (u < 0)
937 u = -u, negate = 1;
938
939 d = (USItype) (u >> WORD_SIZE);
940 d *= HIGH_HALFWORD_COEFF;
941 d *= HIGH_HALFWORD_COEFF;
942 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
943
944 return (negate ? -d : d);
945 }
946 #endif
947
948 #if defined(L_floatditf) && (LONG_DOUBLE_TYPE_SIZE == 128)
949 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
950 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
951 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
952
953 TFtype
954 __floatditf (u)
955 DItype u;
956 {
957 TFtype d;
958 SItype negate = 0;
959
960 if (u < 0)
961 u = -u, negate = 1;
962
963 d = (USItype) (u >> WORD_SIZE);
964 d *= HIGH_HALFWORD_COEFF;
965 d *= HIGH_HALFWORD_COEFF;
966 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
967
968 return (negate ? -d : d);
969 }
970 #endif
971
972 #ifdef L_floatdidf
973 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
974 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
975 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
976
977 DFtype
978 __floatdidf (u)
979 DItype u;
980 {
981 DFtype d;
982 SItype negate = 0;
983
984 if (u < 0)
985 u = -u, negate = 1;
986
987 d = (USItype) (u >> WORD_SIZE);
988 d *= HIGH_HALFWORD_COEFF;
989 d *= HIGH_HALFWORD_COEFF;
990 d += (USItype) (u & (HIGH_WORD_COEFF - 1));
991
992 return (negate ? -d : d);
993 }
994 #endif
995
996 #ifdef L_floatdisf
997 #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
998 #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
999 #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
1000 #define DI_SIZE (sizeof (DItype) * BITS_PER_UNIT)
1001
1002 /* Define codes for all the float formats that we know of. Note
1003 that this is copied from real.h. */
1004
1005 #define UNKNOWN_FLOAT_FORMAT 0
1006 #define IEEE_FLOAT_FORMAT 1
1007 #define VAX_FLOAT_FORMAT 2
1008 #define IBM_FLOAT_FORMAT 3
1009
1010 /* Default to IEEE float if not specified. Nearly all machines use it. */
1011 #ifndef HOST_FLOAT_FORMAT
1012 #define HOST_FLOAT_FORMAT IEEE_FLOAT_FORMAT
1013 #endif
1014
1015 #if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1016 #define DF_SIZE 53
1017 #define SF_SIZE 24
1018 #endif
1019
1020 #if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
1021 #define DF_SIZE 56
1022 #define SF_SIZE 24
1023 #endif
1024
1025 #if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
1026 #define DF_SIZE 56
1027 #define SF_SIZE 24
1028 #endif
1029
1030 SFtype
1031 __floatdisf (u)
1032 DItype u;
1033 {
1034 /* Do the calculation in DFmode
1035 so that we don't lose any of the precision of the high word
1036 while multiplying it. */
1037 DFtype f;
1038 SItype negate = 0;
1039
1040 if (u < 0)
1041 u = -u, negate = 1;
1042
1043 /* Protect against double-rounding error.
1044 Represent any low-order bits, that might be truncated in DFmode,
1045 by a bit that won't be lost. The bit can go in anywhere below the
1046 rounding position of the SFmode. A fixed mask and bit position
1047 handles all usual configurations. It doesn't handle the case
1048 of 128-bit DImode, however. */
1049 if (DF_SIZE < DI_SIZE
1050 && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1051 {
1052 #define REP_BIT ((USItype) 1 << (DI_SIZE - DF_SIZE))
1053 if (u >= ((UDItype) 1 << DF_SIZE))
1054 {
1055 if ((USItype) u & (REP_BIT - 1))
1056 u |= REP_BIT;
1057 }
1058 }
1059 f = (USItype) (u >> WORD_SIZE);
1060 f *= HIGH_HALFWORD_COEFF;
1061 f *= HIGH_HALFWORD_COEFF;
1062 f += (USItype) (u & (HIGH_WORD_COEFF - 1));
1063
1064 return (SFtype) (negate ? -f : f);
1065 }
1066 #endif
1067
1068 #if defined(L_fixunsxfsi) && LONG_DOUBLE_TYPE_SIZE == 96
1069 /* Reenable the normal types, in case limits.h needs them. */
1070 #undef char
1071 #undef short
1072 #undef int
1073 #undef long
1074 #undef unsigned
1075 #undef float
1076 #undef double
1077 #include <limits.h>
1078
1079 USItype
1080 __fixunsxfsi (a)
1081 XFtype a;
1082 {
1083 if (a >= - (DFtype) LONG_MIN)
1084 return (SItype) (a + LONG_MIN) - LONG_MIN;
1085 return (SItype) a;
1086 }
1087 #endif
1088
1089 #ifdef L_fixunsdfsi
1090 /* Reenable the normal types, in case limits.h needs them. */
1091 #undef char
1092 #undef short
1093 #undef int
1094 #undef long
1095 #undef unsigned
1096 #undef float
1097 #undef double
1098 #include <limits.h>
1099
1100 USItype
1101 __fixunsdfsi (a)
1102 DFtype a;
1103 {
1104 if (a >= - (DFtype) LONG_MIN)
1105 return (SItype) (a + LONG_MIN) - LONG_MIN;
1106 return (SItype) a;
1107 }
1108 #endif
1109
1110 #ifdef L_fixunssfsi
1111 /* Reenable the normal types, in case limits.h needs them. */
1112 #undef char
1113 #undef short
1114 #undef int
1115 #undef long
1116 #undef unsigned
1117 #undef float
1118 #undef double
1119 #include <limits.h>
1120
1121 USItype
1122 __fixunssfsi (SFtype a)
1123 {
1124 if (a >= - (SFtype) LONG_MIN)
1125 return (SItype) (a + LONG_MIN) - LONG_MIN;
1126 return (SItype) a;
1127 }
1128 #endif
1129 \f
1130 /* From here on down, the routines use normal data types. */
1131
1132 #define SItype bogus_type
1133 #define USItype bogus_type
1134 #define DItype bogus_type
1135 #define UDItype bogus_type
1136 #define SFtype bogus_type
1137 #define DFtype bogus_type
1138
1139 #undef char
1140 #undef short
1141 #undef int
1142 #undef long
1143 #undef unsigned
1144 #undef float
1145 #undef double
1146 \f
1147 #ifdef L__gcc_bcmp
1148
1149 /* Like bcmp except the sign is meaningful.
1150 Result is negative if S1 is less than S2,
1151 positive if S1 is greater, 0 if S1 and S2 are equal. */
1152
1153 int
1154 __gcc_bcmp (s1, s2, size)
1155 unsigned char *s1, *s2;
1156 size_t size;
1157 {
1158 while (size > 0)
1159 {
1160 unsigned char c1 = *s1++, c2 = *s2++;
1161 if (c1 != c2)
1162 return c1 - c2;
1163 size--;
1164 }
1165 return 0;
1166 }
1167
1168 #endif
1169 \f\f
1170 #ifdef L_varargs
1171 #ifdef __i860__
1172 #if defined(__svr4__) || defined(__alliant__)
1173 asm (" .text");
1174 asm (" .align 4");
1175
1176 /* The Alliant needs the added underscore. */
1177 asm (".globl __builtin_saveregs");
1178 asm ("__builtin_saveregs:");
1179 asm (".globl ___builtin_saveregs");
1180 asm ("___builtin_saveregs:");
1181
1182 asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */
1183 asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save
1184 area and also for a new va_list
1185 structure */
1186 /* Save all argument registers in the arg reg save area. The
1187 arg reg save area must have the following layout (according
1188 to the svr4 ABI):
1189
1190 struct {
1191 union {
1192 float freg[8];
1193 double dreg[4];
1194 } float_regs;
1195 long ireg[12];
1196 };
1197 */
1198
1199 asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */
1200 asm (" fst.q %f12,16(%sp)");
1201
1202 asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */
1203 asm (" st.l %r17,36(%sp)");
1204 asm (" st.l %r18,40(%sp)");
1205 asm (" st.l %r19,44(%sp)");
1206 asm (" st.l %r20,48(%sp)");
1207 asm (" st.l %r21,52(%sp)");
1208 asm (" st.l %r22,56(%sp)");
1209 asm (" st.l %r23,60(%sp)");
1210 asm (" st.l %r24,64(%sp)");
1211 asm (" st.l %r25,68(%sp)");
1212 asm (" st.l %r26,72(%sp)");
1213 asm (" st.l %r27,76(%sp)");
1214
1215 asm (" adds 80,%sp,%r16"); /* compute the address of the new
1216 va_list structure. Put in into
1217 r16 so that it will be returned
1218 to the caller. */
1219
1220 /* Initialize all fields of the new va_list structure. This
1221 structure looks like:
1222
1223 typedef struct {
1224 unsigned long ireg_used;
1225 unsigned long freg_used;
1226 long *reg_base;
1227 long *mem_ptr;
1228 } va_list;
1229 */
1230
1231 asm (" st.l %r0, 0(%r16)"); /* nfixed */
1232 asm (" st.l %r0, 4(%r16)"); /* nfloating */
1233 asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */
1234 asm (" bri %r1"); /* delayed return */
1235 asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */
1236
1237 #else /* not __svr4__ */
1238 #if defined(__PARAGON__)
1239 /*
1240 * we'll use SVR4-ish varargs but need SVR3.2 assembler syntax,
1241 * and we stand a better chance of hooking into libraries
1242 * compiled by PGI. [andyp@ssd.intel.com]
1243 */
1244 asm (" .text");
1245 asm (" .align 4");
1246 asm (".globl __builtin_saveregs");
1247 asm ("__builtin_saveregs:");
1248 asm (".globl ___builtin_saveregs");
1249 asm ("___builtin_saveregs:");
1250
1251 asm (" andnot 0x0f,sp,sp"); /* round down to 16-byte boundary */
1252 asm (" adds -96,sp,sp"); /* allocate stack space for reg save
1253 area and also for a new va_list
1254 structure */
1255 /* Save all argument registers in the arg reg save area. The
1256 arg reg save area must have the following layout (according
1257 to the svr4 ABI):
1258
1259 struct {
1260 union {
1261 float freg[8];
1262 double dreg[4];
1263 } float_regs;
1264 long ireg[12];
1265 };
1266 */
1267
1268 asm (" fst.q f8, 0(sp)");
1269 asm (" fst.q f12,16(sp)");
1270 asm (" st.l r16,32(sp)");
1271 asm (" st.l r17,36(sp)");
1272 asm (" st.l r18,40(sp)");
1273 asm (" st.l r19,44(sp)");
1274 asm (" st.l r20,48(sp)");
1275 asm (" st.l r21,52(sp)");
1276 asm (" st.l r22,56(sp)");
1277 asm (" st.l r23,60(sp)");
1278 asm (" st.l r24,64(sp)");
1279 asm (" st.l r25,68(sp)");
1280 asm (" st.l r26,72(sp)");
1281 asm (" st.l r27,76(sp)");
1282
1283 asm (" adds 80,sp,r16"); /* compute the address of the new
1284 va_list structure. Put in into
1285 r16 so that it will be returned
1286 to the caller. */
1287
1288 /* Initialize all fields of the new va_list structure. This
1289 structure looks like:
1290
1291 typedef struct {
1292 unsigned long ireg_used;
1293 unsigned long freg_used;
1294 long *reg_base;
1295 long *mem_ptr;
1296 } va_list;
1297 */
1298
1299 asm (" st.l r0, 0(r16)"); /* nfixed */
1300 asm (" st.l r0, 4(r16)"); /* nfloating */
1301 asm (" st.l sp, 8(r16)"); /* __va_ctl points to __va_struct. */
1302 asm (" bri r1"); /* delayed return */
1303 asm (" st.l r28,12(r16)"); /* pointer to overflow args */
1304 #else /* not __PARAGON__ */
1305 asm (" .text");
1306 asm (" .align 4");
1307
1308 asm (".globl ___builtin_saveregs");
1309 asm ("___builtin_saveregs:");
1310 asm (" mov sp,r30");
1311 asm (" andnot 0x0f,sp,sp");
1312 asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
1313
1314 /* Fill in the __va_struct. */
1315 asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
1316 asm (" st.l r17, 4(sp)"); /* int fixed[12] */
1317 asm (" st.l r18, 8(sp)");
1318 asm (" st.l r19,12(sp)");
1319 asm (" st.l r20,16(sp)");
1320 asm (" st.l r21,20(sp)");
1321 asm (" st.l r22,24(sp)");
1322 asm (" st.l r23,28(sp)");
1323 asm (" st.l r24,32(sp)");
1324 asm (" st.l r25,36(sp)");
1325 asm (" st.l r26,40(sp)");
1326 asm (" st.l r27,44(sp)");
1327
1328 asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
1329 asm (" fst.q f12,64(sp)"); /* int floating[8] */
1330
1331 /* Fill in the __va_ctl. */
1332 asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */
1333 asm (" st.l r28,84(sp)"); /* pointer to more args */
1334 asm (" st.l r0, 88(sp)"); /* nfixed */
1335 asm (" st.l r0, 92(sp)"); /* nfloating */
1336
1337 asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */
1338 asm (" bri r1");
1339 asm (" mov r30,sp");
1340 /* recover stack and pass address to start
1341 of data. */
1342 #endif /* not __PARAGON__ */
1343 #endif /* not __svr4__ */
1344 #else /* not __i860__ */
1345 #ifdef __sparc__
1346 asm (".global __builtin_saveregs");
1347 asm ("__builtin_saveregs:");
1348 asm (".global ___builtin_saveregs");
1349 asm ("___builtin_saveregs:");
1350 #ifdef NEED_PROC_COMMAND
1351 asm (".proc 020");
1352 #endif
1353 asm ("st %i0,[%fp+68]");
1354 asm ("st %i1,[%fp+72]");
1355 asm ("st %i2,[%fp+76]");
1356 asm ("st %i3,[%fp+80]");
1357 asm ("st %i4,[%fp+84]");
1358 asm ("retl");
1359 asm ("st %i5,[%fp+88]");
1360 #ifdef NEED_TYPE_COMMAND
1361 asm (".type __builtin_saveregs,#function");
1362 asm (".size __builtin_saveregs,.-__builtin_saveregs");
1363 #endif
1364 #else /* not __sparc__ */
1365 #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
1366
1367 asm (" .text");
1368 asm (" .ent __builtin_saveregs");
1369 asm (" .globl __builtin_saveregs");
1370 asm ("__builtin_saveregs:");
1371 asm (" sw $4,0($30)");
1372 asm (" sw $5,4($30)");
1373 asm (" sw $6,8($30)");
1374 asm (" sw $7,12($30)");
1375 asm (" j $31");
1376 asm (" .end __builtin_saveregs");
1377 #else /* not __mips__, etc. */
1378
1379 void *
1380 __builtin_saveregs ()
1381 {
1382 abort ();
1383 }
1384
1385 #endif /* not __mips__ */
1386 #endif /* not __sparc__ */
1387 #endif /* not __i860__ */
1388 #endif
1389 \f
1390 #ifdef L_eprintf
1391 #ifndef inhibit_libc
1392
1393 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1394 #include <stdio.h>
1395 /* This is used by the `assert' macro. */
1396 void
1397 __eprintf (string, expression, line, filename)
1398 const char *string;
1399 const char *expression;
1400 int line;
1401 const char *filename;
1402 {
1403 fprintf (stderr, string, expression, line, filename);
1404 fflush (stderr);
1405 abort ();
1406 }
1407
1408 #endif
1409 #endif
1410
1411 #ifdef L_bb
1412
1413 /* Structure emitted by -a */
1414 struct bb
1415 {
1416 long zero_word;
1417 const char *filename;
1418 long *counts;
1419 long ncounts;
1420 struct bb *next;
1421 const unsigned long *addresses;
1422
1423 /* Older GCC's did not emit these fields. */
1424 long nwords;
1425 const char **functions;
1426 const long *line_nums;
1427 const char **filenames;
1428 };
1429
1430 #ifdef BLOCK_PROFILER_CODE
1431 BLOCK_PROFILER_CODE
1432 #else
1433 #ifndef inhibit_libc
1434
1435 /* Simple minded basic block profiling output dumper for
1436 systems that don't provide tcov support. At present,
1437 it requires atexit and stdio. */
1438
1439 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1440 #include <stdio.h>
1441 char *ctime ();
1442
1443 #ifdef HAVE_ATEXIT
1444 #ifdef WINNT
1445 extern int atexit (void (*) (void));
1446 #else
1447 extern void atexit (void (*) (void));
1448 #endif
1449 #define ON_EXIT(FUNC,ARG) atexit ((FUNC))
1450 #else
1451 #ifdef sun
1452 extern void on_exit (void*, void*);
1453 #define ON_EXIT(FUNC,ARG) on_exit ((FUNC), (ARG))
1454 #endif
1455 #endif
1456
1457 static struct bb *bb_head;
1458
1459 /* Return the number of digits needed to print a value */
1460 /* __inline__ */ static int num_digits (long value, int base)
1461 {
1462 int minus = (value < 0 && base != 16);
1463 unsigned long v = (minus) ? -value : value;
1464 int ret = minus;
1465
1466 do
1467 {
1468 v /= base;
1469 ret++;
1470 }
1471 while (v);
1472
1473 return ret;
1474 }
1475
1476 void
1477 __bb_exit_func (void)
1478 {
1479 FILE *file = fopen ("bb.out", "a");
1480 long time_value;
1481
1482 if (!file)
1483 perror ("bb.out");
1484
1485 else
1486 {
1487 struct bb *ptr;
1488
1489 /* This is somewhat type incorrect, but it avoids worrying about
1490 exactly where time.h is included from. It should be ok unless
1491 a void * differs from other pointer formats, or if sizeof(long)
1492 is < sizeof (time_t). It would be nice if we could assume the
1493 use of rationale standards here. */
1494
1495 time((void *) &time_value);
1496 fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value));
1497
1498 /* We check the length field explicitly in order to allow compatibility
1499 with older GCC's which did not provide it. */
1500
1501 for (ptr = bb_head; ptr != (struct bb *)0; ptr = ptr->next)
1502 {
1503 int i;
1504 int func_p = (ptr->nwords >= sizeof (struct bb) && ptr->nwords <= 1000);
1505 int line_p = (func_p && ptr->line_nums);
1506 int file_p = (func_p && ptr->filenames);
1507 long ncounts = ptr->ncounts;
1508 long cnt_max = 0;
1509 long line_max = 0;
1510 long addr_max = 0;
1511 int file_len = 0;
1512 int func_len = 0;
1513 int blk_len = num_digits (ncounts, 10);
1514 int cnt_len;
1515 int line_len;
1516 int addr_len;
1517
1518 fprintf (file, "File %s, %ld basic blocks \n\n",
1519 ptr->filename, ncounts);
1520
1521 /* Get max values for each field. */
1522 for (i = 0; i < ncounts; i++)
1523 {
1524 const char *p;
1525 int len;
1526
1527 if (cnt_max < ptr->counts[i])
1528 cnt_max = ptr->counts[i];
1529
1530 if (addr_max < ptr->addresses[i])
1531 addr_max = ptr->addresses[i];
1532
1533 if (line_p && line_max < ptr->line_nums[i])
1534 line_max = ptr->line_nums[i];
1535
1536 if (func_p)
1537 {
1538 p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>";
1539 len = strlen (p);
1540 if (func_len < len)
1541 func_len = len;
1542 }
1543
1544 if (file_p)
1545 {
1546 p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>";
1547 len = strlen (p);
1548 if (file_len < len)
1549 file_len = len;
1550 }
1551 }
1552
1553 addr_len = num_digits (addr_max, 16);
1554 cnt_len = num_digits (cnt_max, 10);
1555 line_len = num_digits (line_max, 10);
1556
1557 /* Now print out the basic block information. */
1558 for (i = 0; i < ncounts; i++)
1559 {
1560 fprintf (file,
1561 " Block #%*d: executed %*ld time(s) address= 0x%.*lx",
1562 blk_len, i+1,
1563 cnt_len, ptr->counts[i],
1564 addr_len, ptr->addresses[i]);
1565
1566 if (func_p)
1567 fprintf (file, " function= %-*s", func_len,
1568 (ptr->functions[i]) ? ptr->functions[i] : "<none>");
1569
1570 if (line_p)
1571 fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]);
1572
1573 if (file_p)
1574 fprintf (file, " file= %s",
1575 (ptr->filenames[i]) ? ptr->filenames[i] : "<none>");
1576
1577 fprintf (file, "\n");
1578 }
1579
1580 fprintf (file, "\n");
1581 fflush (file);
1582 }
1583
1584 fprintf (file, "\n\n");
1585 fclose (file);
1586 }
1587 }
1588
1589 void
1590 __bb_init_func (struct bb *blocks)
1591 {
1592 /* User is supposed to check whether the first word is non-0,
1593 but just in case.... */
1594
1595 if (blocks->zero_word)
1596 return;
1597
1598 #ifdef ON_EXIT
1599 /* Initialize destructor. */
1600 if (!bb_head)
1601 ON_EXIT (__bb_exit_func, 0);
1602 #endif
1603
1604 /* Set up linked list. */
1605 blocks->zero_word = 1;
1606 blocks->next = bb_head;
1607 bb_head = blocks;
1608 }
1609
1610 #endif /* not inhibit_libc */
1611 #endif /* not BLOCK_PROFILER_CODE */
1612 #endif /* L_bb */
1613 \f
1614 /* Default free-store management functions for C++, per sections 12.5 and
1615 17.3.3 of the Working Paper. */
1616
1617 #ifdef L_op_new
1618 /* operator new (size_t), described in 17.3.3.5. This function is used by
1619 C++ programs to allocate a block of memory to hold a single object. */
1620
1621 typedef void (*vfp)(void);
1622 extern vfp __new_handler;
1623 extern void __default_new_handler (void);
1624
1625 #ifdef WEAK_ALIAS
1626 void * __builtin_new (size_t sz)
1627 __attribute__ ((weak, alias ("___builtin_new")));
1628 void *
1629 ___builtin_new (size_t sz)
1630 #else
1631 void *
1632 __builtin_new (size_t sz)
1633 #endif
1634 {
1635 void *p;
1636 vfp handler = (__new_handler) ? __new_handler : __default_new_handler;
1637
1638 /* malloc (0) is unpredictable; avoid it. */
1639 if (sz == 0)
1640 sz = 1;
1641 p = (void *) malloc (sz);
1642 while (p == 0)
1643 {
1644 (*handler) ();
1645 p = (void *) malloc (sz);
1646 }
1647
1648 return p;
1649 }
1650 #endif /* L_op_new */
1651
1652 #ifdef L_op_vnew
1653 /* void * operator new [] (size_t), described in 17.3.3.6. This function
1654 is used by C++ programs to allocate a block of memory for an array. */
1655
1656 extern void * __builtin_new (size_t);
1657
1658 #ifdef WEAK_ALIAS
1659 void * __builtin_vec_new (size_t sz)
1660 __attribute__ ((weak, alias ("___builtin_vec_new")));
1661 void *
1662 ___builtin_vec_new (size_t sz)
1663 #else
1664 void *
1665 __builtin_vec_new (size_t sz)
1666 #endif
1667 {
1668 return __builtin_new (sz);
1669 }
1670 #endif /* L_op_vnew */
1671
1672 #ifdef L_new_handler
1673 /* set_new_handler (fvoid_t *) and the default new handler, described in
1674 17.3.3.2 and 17.3.3.5. These functions define the result of a failure
1675 to allocate the amount of memory requested from operator new or new []. */
1676
1677 #ifndef inhibit_libc
1678 /* This gets us __GNU_LIBRARY__. */
1679 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1680 #include <stdio.h>
1681
1682 #ifdef __GNU_LIBRARY__
1683 /* Avoid forcing the library's meaning of `write' on the user program
1684 by using the "internal" name (for use within the library) */
1685 #define write(fd, buf, n) __write((fd), (buf), (n))
1686 #endif
1687 #endif /* inhibit_libc */
1688
1689 typedef void (*vfp)(void);
1690 void __default_new_handler (void);
1691
1692 vfp __new_handler = (vfp)0;
1693
1694 vfp
1695 set_new_handler (vfp handler)
1696 {
1697 vfp prev_handler;
1698
1699 prev_handler = __new_handler;
1700 if (handler == 0) handler = __default_new_handler;
1701 __new_handler = handler;
1702 return prev_handler;
1703 }
1704
1705 #define MESSAGE "Virtual memory exceeded in `new'\n"
1706
1707 void
1708 __default_new_handler ()
1709 {
1710 #ifndef inhibit_libc
1711 /* don't use fprintf (stderr, ...) because it may need to call malloc. */
1712 /* This should really print the name of the program, but that is hard to
1713 do. We need a standard, clean way to get at the name. */
1714 write (2, MESSAGE, sizeof (MESSAGE));
1715 #endif
1716 /* don't call exit () because that may call global destructors which
1717 may cause a loop. */
1718 _exit (-1);
1719 }
1720 #endif
1721
1722 #ifdef L_op_delete
1723 /* operator delete (void *), described in 17.3.3.3. This function is used
1724 by C++ programs to return to the free store a block of memory allocated
1725 as a single object. */
1726
1727 #ifdef WEAK_ALIAS
1728 void __builtin_delete (void *ptr)
1729 __attribute__ ((weak, alias ("___builtin_delete")));
1730 void
1731 ___builtin_delete (void *ptr)
1732 #else
1733 void
1734 __builtin_delete (void *ptr)
1735 #endif
1736 {
1737 if (ptr)
1738 free (ptr);
1739 }
1740 #endif
1741
1742 #ifdef L_op_vdel
1743 /* operator delete [] (void *), described in 17.3.3.4. This function is
1744 used by C++ programs to return to the free store a block of memory
1745 allocated as an array. */
1746
1747 extern void __builtin_delete (void *);
1748
1749 #ifdef WEAK_ALIAS
1750 void __builtin_vec_delete (void *ptr)
1751 __attribute__ ((weak, alias ("___builtin_vec_delete")));
1752 void
1753 ___builtin_vec_delete (void *ptr)
1754 #else
1755 void
1756 __builtin_vec_delete (void *ptr)
1757 #endif
1758 {
1759 __builtin_delete (ptr);
1760 }
1761 #endif
1762
1763 /* End of C++ free-store management functions */
1764 \f
1765 #ifdef L_shtab
1766 unsigned int __shtab[] = {
1767 0x00000001, 0x00000002, 0x00000004, 0x00000008,
1768 0x00000010, 0x00000020, 0x00000040, 0x00000080,
1769 0x00000100, 0x00000200, 0x00000400, 0x00000800,
1770 0x00001000, 0x00002000, 0x00004000, 0x00008000,
1771 0x00010000, 0x00020000, 0x00040000, 0x00080000,
1772 0x00100000, 0x00200000, 0x00400000, 0x00800000,
1773 0x01000000, 0x02000000, 0x04000000, 0x08000000,
1774 0x10000000, 0x20000000, 0x40000000, 0x80000000
1775 };
1776 #endif
1777 \f
1778 #ifdef L_clear_cache
1779 /* Clear part of an instruction cache. */
1780
1781 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1782
1783 void
1784 __clear_cache (beg, end)
1785 char *beg, *end;
1786 {
1787 #ifdef CLEAR_INSN_CACHE
1788 CLEAR_INSN_CACHE (beg, end);
1789 #else
1790 #ifdef INSN_CACHE_SIZE
1791 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1792 static int initialized;
1793 int offset;
1794 void *start_addr
1795 void *end_addr;
1796 typedef (*function_ptr) ();
1797
1798 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1799 /* It's cheaper to clear the whole cache.
1800 Put in a series of jump instructions so that calling the beginning
1801 of the cache will clear the whole thing. */
1802
1803 if (! initialized)
1804 {
1805 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1806 & -INSN_CACHE_LINE_WIDTH);
1807 int end_ptr = ptr + INSN_CACHE_SIZE;
1808
1809 while (ptr < end_ptr)
1810 {
1811 *(INSTRUCTION_TYPE *)ptr
1812 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1813 ptr += INSN_CACHE_LINE_WIDTH;
1814 }
1815 *(INSTRUCTION_TYPE *)(ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1816
1817 initialized = 1;
1818 }
1819
1820 /* Call the beginning of the sequence. */
1821 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1822 & -INSN_CACHE_LINE_WIDTH))
1823 ());
1824
1825 #else /* Cache is large. */
1826
1827 if (! initialized)
1828 {
1829 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1830 & -INSN_CACHE_LINE_WIDTH);
1831
1832 while (ptr < (int) array + sizeof array)
1833 {
1834 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1835 ptr += INSN_CACHE_LINE_WIDTH;
1836 }
1837
1838 initialized = 1;
1839 }
1840
1841 /* Find the location in array that occupies the same cache line as BEG. */
1842
1843 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1844 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1845 & -INSN_CACHE_PLANE_SIZE)
1846 + offset);
1847
1848 /* Compute the cache alignment of the place to stop clearing. */
1849 #if 0 /* This is not needed for gcc's purposes. */
1850 /* If the block to clear is bigger than a cache plane,
1851 we clear the entire cache, and OFFSET is already correct. */
1852 if (end < beg + INSN_CACHE_PLANE_SIZE)
1853 #endif
1854 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1855 & -INSN_CACHE_LINE_WIDTH)
1856 & (INSN_CACHE_PLANE_SIZE - 1));
1857
1858 #if INSN_CACHE_DEPTH > 1
1859 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1860 if (end_addr <= start_addr)
1861 end_addr += INSN_CACHE_PLANE_SIZE;
1862
1863 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1864 {
1865 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1866 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1867
1868 while (addr != stop)
1869 {
1870 /* Call the return instruction at ADDR. */
1871 ((function_ptr) addr) ();
1872
1873 addr += INSN_CACHE_LINE_WIDTH;
1874 }
1875 }
1876 #else /* just one plane */
1877 do
1878 {
1879 /* Call the return instruction at START_ADDR. */
1880 ((function_ptr) start_addr) ();
1881
1882 start_addr += INSN_CACHE_LINE_WIDTH;
1883 }
1884 while ((start_addr % INSN_CACHE_SIZE) != offset);
1885 #endif /* just one plane */
1886 #endif /* Cache is large */
1887 #endif /* Cache exists */
1888 #endif /* CLEAR_INSN_CACHE */
1889 }
1890
1891 #endif /* L_clear_cache */
1892 \f
1893 #ifdef L_trampoline
1894
1895 /* Jump to a trampoline, loading the static chain address. */
1896
1897 #ifdef TRANSFER_FROM_TRAMPOLINE
1898 TRANSFER_FROM_TRAMPOLINE
1899 #endif
1900
1901 #if defined (NeXT) && defined (__MACH__)
1902
1903 /* Make stack executable so we can call trampolines on stack.
1904 This is called from INITIALIZE_TRAMPOLINE in next.h. */
1905 #ifdef NeXTStep21
1906 #include <mach.h>
1907 #else
1908 #include <mach/mach.h>
1909 #endif
1910
1911 void
1912 __enable_execute_stack (addr)
1913 char *addr;
1914 {
1915 kern_return_t r;
1916 char *eaddr = addr + TRAMPOLINE_SIZE;
1917 vm_address_t a = (vm_address_t) addr;
1918
1919 /* turn on execute access on stack */
1920 r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
1921 if (r != KERN_SUCCESS)
1922 {
1923 mach_error("vm_protect VM_PROT_ALL", r);
1924 exit(1);
1925 }
1926
1927 /* We inline the i-cache invalidation for speed */
1928
1929 #ifdef CLEAR_INSN_CACHE
1930 CLEAR_INSN_CACHE (addr, eaddr);
1931 #else
1932 __clear_cache ((int) addr, (int) eaddr);
1933 #endif
1934 }
1935
1936 #endif /* defined (NeXT) && defined (__MACH__) */
1937
1938 #ifdef __convex__
1939
1940 /* Make stack executable so we can call trampolines on stack.
1941 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
1942
1943 #include <sys/mman.h>
1944 #include <sys/vmparam.h>
1945 #include <machine/machparam.h>
1946
1947 void
1948 __enable_execute_stack ()
1949 {
1950 int fp;
1951 static unsigned lowest = USRSTACK;
1952 unsigned current = (unsigned) &fp & -NBPG;
1953
1954 if (lowest > current)
1955 {
1956 unsigned len = lowest - current;
1957 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
1958 lowest = current;
1959 }
1960
1961 /* Clear instruction cache in case an old trampoline is in it. */
1962 asm ("pich");
1963 }
1964 #endif /* __convex__ */
1965
1966 #ifdef __DOLPHIN__
1967
1968 /* Modified from the convex -code above. */
1969
1970 #include <sys/param.h>
1971 #include <errno.h>
1972 #include <sys/m88kbcs.h>
1973
1974 void
1975 __enable_execute_stack ()
1976 {
1977 int save_errno;
1978 static unsigned long lowest = USRSTACK;
1979 unsigned long current = (unsigned long) &save_errno & -NBPC;
1980
1981 /* Ignore errno being set. memctl sets errno to EINVAL whenever the
1982 address is seen as 'negative'. That is the case with the stack. */
1983
1984 save_errno=errno;
1985 if (lowest > current)
1986 {
1987 unsigned len=lowest-current;
1988 memctl(current,len,MCT_TEXT);
1989 lowest = current;
1990 }
1991 else
1992 memctl(current,NBPC,MCT_TEXT);
1993 errno=save_errno;
1994 }
1995
1996 #endif /* __DOLPHIN__ */
1997
1998 #ifdef __pyr__
1999
2000 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2001 #include <stdio.h>
2002 #include <sys/mman.h>
2003 #include <sys/types.h>
2004 #include <sys/param.h>
2005 #include <sys/vmmac.h>
2006
2007 /* Modified from the convex -code above.
2008 mremap promises to clear the i-cache. */
2009
2010 void
2011 __enable_execute_stack ()
2012 {
2013 int fp;
2014 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
2015 PROT_READ|PROT_WRITE|PROT_EXEC))
2016 {
2017 perror ("mprotect in __enable_execute_stack");
2018 fflush (stderr);
2019 abort ();
2020 }
2021 }
2022 #endif /* __pyr__ */
2023 #endif /* L_trampoline */
2024 \f
2025 #ifdef L__main
2026
2027 #include "gbl-ctors.h"
2028 /* Some systems use __main in a way incompatible with its use in gcc, in these
2029 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2030 give the same symbol without quotes for an alternative entry point. You
2031 must define both, or neither. */
2032 #ifndef NAME__MAIN
2033 #define NAME__MAIN "__main"
2034 #define SYMBOL__MAIN __main
2035 #endif
2036
2037 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2038 /* Run all the global destructors on exit from the program. */
2039
2040 void
2041 __do_global_dtors ()
2042 {
2043 #ifdef DO_GLOBAL_DTORS_BODY
2044 DO_GLOBAL_DTORS_BODY;
2045 #else
2046 func_ptr *p;
2047 for (p = __DTOR_LIST__ + 1; *p; )
2048 (*p++) ();
2049 #endif
2050 }
2051 #endif
2052
2053 #ifndef INIT_SECTION_ASM_OP
2054 /* Run all the global constructors on entry to the program. */
2055
2056 #ifndef ON_EXIT
2057 #define ON_EXIT(a, b)
2058 #else
2059 /* Make sure the exit routine is pulled in to define the globals as
2060 bss symbols, just in case the linker does not automatically pull
2061 bss definitions from the library. */
2062
2063 extern int _exit_dummy_decl;
2064 int *_exit_dummy_ref = &_exit_dummy_decl;
2065 #endif /* ON_EXIT */
2066
2067 void
2068 __do_global_ctors ()
2069 {
2070 DO_GLOBAL_CTORS_BODY;
2071 ON_EXIT (__do_global_dtors, 0);
2072 }
2073 #endif /* no INIT_SECTION_ASM_OP */
2074
2075 #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
2076 /* Subroutine called automatically by `main'.
2077 Compiling a global function named `main'
2078 produces an automatic call to this function at the beginning.
2079
2080 For many systems, this routine calls __do_global_ctors.
2081 For systems which support a .init section we use the .init section
2082 to run __do_global_ctors, so we need not do anything here. */
2083
2084 void
2085 SYMBOL__MAIN ()
2086 {
2087 /* Support recursive calls to `main': run initializers just once. */
2088 static int initialized;
2089 if (! initialized)
2090 {
2091 initialized = 1;
2092 __do_global_ctors ();
2093 }
2094 }
2095 #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
2096
2097 #endif /* L__main */
2098 \f
2099 #ifdef L_ctors
2100
2101 #include "gbl-ctors.h"
2102
2103 /* Provide default definitions for the lists of constructors and
2104 destructors, so that we don't get linker errors. These symbols are
2105 intentionally bss symbols, so that gld and/or collect will provide
2106 the right values. */
2107
2108 /* We declare the lists here with two elements each,
2109 so that they are valid empty lists if no other definition is loaded. */
2110 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
2111 #ifdef __NeXT__
2112 /* After 2.3, try this definition on all systems. */
2113 func_ptr __CTOR_LIST__[2] = {0, 0};
2114 func_ptr __DTOR_LIST__[2] = {0, 0};
2115 #else
2116 func_ptr __CTOR_LIST__[2];
2117 func_ptr __DTOR_LIST__[2];
2118 #endif
2119 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
2120 #endif /* L_ctors */
2121 \f
2122 #ifdef L_exit
2123
2124 #include "gbl-ctors.h"
2125
2126 #ifndef ON_EXIT
2127
2128 /* If we have no known way of registering our own __do_global_dtors
2129 routine so that it will be invoked at program exit time, then we
2130 have to define our own exit routine which will get this to happen. */
2131
2132 extern void __do_global_dtors ();
2133 extern void _cleanup ();
2134 extern void _exit () __attribute__ ((noreturn));
2135
2136 void
2137 exit (status)
2138 int status;
2139 {
2140 #if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
2141 __do_global_dtors ();
2142 #endif
2143 #ifdef EXIT_BODY
2144 EXIT_BODY;
2145 #else
2146 _cleanup ();
2147 #endif
2148 _exit (status);
2149 }
2150
2151 #else
2152 int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */
2153 #endif
2154
2155 #endif /* L_exit */
2156 \f
2157 #ifdef L_eh
2158 typedef struct {
2159 void *start;
2160 void *end;
2161 void *exception_handler;
2162 } exception_table;
2163
2164 struct exception_table_node {
2165 exception_table *table;
2166 void *start;
2167 void *end;
2168 struct exception_table_node *next;
2169 };
2170
2171 static int except_table_pos;
2172 static void *except_pc;
2173 static struct exception_table_node *exception_table_list;
2174
2175 static exception_table *
2176 find_exception_table (pc)
2177 void* pc;
2178 {
2179 register struct exception_table_node *table = exception_table_list;
2180 for ( ; table != 0; table = table->next)
2181 {
2182 if (table->start <= pc && table->end > pc)
2183 return table->table;
2184 }
2185 return 0;
2186 }
2187
2188 /* this routine takes a pc, and the address of the exception handler associated
2189 with the closest exception table handler entry associated with that PC,
2190 or 0 if there are no table entries the PC fits in. The algorithm works
2191 something like this:
2192
2193 while(current_entry exists) {
2194 if(current_entry.start < pc )
2195 current_entry = next_entry;
2196 else {
2197 if(prev_entry.start <= pc && prev_entry.end > pc) {
2198 save pointer to prev_entry;
2199 return prev_entry.exception_handler;
2200 }
2201 else return 0;
2202 }
2203 }
2204 return 0;
2205
2206 Assuming a correctly sorted table (ascending order) this routine should
2207 return the tighest match...
2208
2209 In the advent of a tie, we have to give the last entry, as it represents
2210 an inner block.
2211 */
2212
2213
2214 void *
2215 __find_first_exception_table_match(pc)
2216 void *pc;
2217 {
2218 exception_table *table = find_exception_table (pc);
2219 int pos = 0;
2220 int best = 0;
2221 if (table == 0)
2222 return (void*)0;
2223 #if 0
2224 printf("find_first_exception_table_match(): pc = %x!\n",pc);
2225 #endif
2226
2227 except_pc = pc;
2228
2229 #if 0
2230 /* We can't do this yet, as we don't know that the table is sorted. */
2231 do {
2232 ++pos;
2233 if (table[pos].start > except_pc)
2234 /* found the first table[pos].start > except_pc, so the previous
2235 entry better be the one we want! */
2236 break;
2237 } while(table[pos].exception_handler != (void*)-1);
2238
2239 --pos;
2240 if (table[pos].start <= except_pc && table[pos].end > except_pc)
2241 {
2242 except_table_pos = pos;
2243 #if 0
2244 printf("find_first_eh_table_match(): found match: %x\n",table[pos].exception_handler);
2245 #endif
2246 return table[pos].exception_handler;
2247 }
2248 #else
2249 while (table[++pos].exception_handler != (void*)-1) {
2250 if (table[pos].start <= except_pc && table[pos].end > except_pc)
2251 {
2252 /* This can apply. Make sure it is better or as good as the previous
2253 best. */
2254 /* The best one ends first. */
2255 if (best == 0 || (table[pos].end <= table[best].end
2256 /* The best one starts last. */
2257 && table[pos].start >= table[best].start))
2258 best = pos;
2259 }
2260 }
2261 if (best != 0)
2262 return table[best].exception_handler;
2263 #endif
2264
2265 #if 0
2266 printf("find_first_eh_table_match(): else: returning NULL!\n");
2267 #endif
2268 return (void*)0;
2269 }
2270
2271 void *
2272 __throw_type_match (void *catch_type, void *throw_type, void* obj)
2273 {
2274 #if 0
2275 printf("__throw_type_match (): catch_type = %s, throw_type = %s\n",
2276 catch_type, throw_type);
2277 #endif
2278 if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0)
2279 return obj;
2280 return 0;
2281 }
2282
2283 void
2284 __register_exceptions (exception_table *table)
2285 {
2286 struct exception_table_node *node;
2287 exception_table *range = table + 1;
2288
2289 if (range->start == (void*)-1)
2290 return;
2291
2292 node = (struct exception_table_node*)
2293 malloc (sizeof (struct exception_table_node));
2294 node->table = table;
2295
2296 /* This look can be optimized away either if the table
2297 is sorted, or if we pass in extra parameters. */
2298 node->start = range->start;
2299 node->end = range->end;
2300 for (range++ ; range->start != (void*)(-1); range++)
2301 {
2302 if (range->start < node->start)
2303 node->start = range->start;
2304 if (range->end > node->end)
2305 node->end = range->end;
2306 }
2307
2308 node->next = exception_table_list;
2309 exception_table_list = node;
2310 }
2311
2312 #if #machine(i386)
2313 void
2314 __unwind_function(void *ptr)
2315 {
2316 asm("movl 8(%esp),%ecx");
2317 /* Undo current frame */
2318 asm("movl %ebp,%esp");
2319 asm("popl %ebp");
2320 /* like ret, but stay here */
2321 asm("addl $4,%esp");
2322
2323 /* Now, undo previous frame. */
2324 /* This is a test routine, as we have to dynamically probe to find out
2325 what to pop for certain, this is just a guess. */
2326 asm("leal -16(%ebp),%esp");
2327 asm("pop %eax"); /* really for popl %ebx */
2328 asm("pop %eax"); /* really for popl %esi */
2329 asm("pop %eax"); /* really for popl %edi */
2330 asm("movl %ebp,%esp");
2331 asm("popl %ebp");
2332
2333 asm("movl %ecx,0(%esp)");
2334 asm("ret");
2335 }
2336 #endif
2337
2338 #if #machine(rs6000)
2339 __unwind_function(void *ptr)
2340 {
2341 asm("mr 31,1");
2342 asm("l 1,0(1)");
2343 asm("l 31,-4(1)");
2344 asm("# br");
2345
2346 asm("mr 31,1");
2347 asm("l 1,0(1)");
2348 /* use 31 as a scratch register to restore the link register. */
2349 asm("l 31, 8(1);mtlr 31 # l lr,8(1)");
2350 asm("l 31,-4(1)");
2351 asm("# br");
2352 asm("mtctr 3;bctr # b 3");
2353 }
2354 #endif /* rs6000 */
2355
2356 #if #machine(powerpc)
2357 __unwind_function(void *ptr)
2358 {
2359 asm("mr 31,1");
2360 asm("lwz 1,0(1)");
2361 asm("lwz 31,-4(1)");
2362 asm("# br");
2363
2364 asm("mr 31,1");
2365 asm("lwz 1,0(1)");
2366 /* use 31 as a scratch register to restore the link register. */
2367 asm("lwz 31, 8(1);mtlr 31 # l lr,8(1)");
2368 asm("lwz 31,-4(1)");
2369 asm("# br");
2370 asm("mtctr 3;bctr # b 3");
2371 }
2372 #endif /* powerpc */
2373 #endif /* L_eh */
2374 \f
2375 #ifdef L_pure
2376 #ifndef inhibit_libc
2377 /* This gets us __GNU_LIBRARY__. */
2378 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2379 #include <stdio.h>
2380
2381 #ifdef __GNU_LIBRARY__
2382 /* Avoid forcing the library's meaning of `write' on the user program
2383 by using the "internal" name (for use within the library) */
2384 #define write(fd, buf, n) __write((fd), (buf), (n))
2385 #endif
2386 #endif /* inhibit_libc */
2387
2388 #define MESSAGE "pure virtual method called\n"
2389
2390 void
2391 __pure_virtual ()
2392 {
2393 #ifndef inhibit_libc
2394 write (2, MESSAGE, sizeof (MESSAGE) - 1);
2395 #endif
2396 _exit (-1);
2397 }
2398 #endif
This page took 0.140529 seconds and 5 git commands to generate.