libgcc2.c, libgcc2.h: Restore __eprintf.
[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, 1996, 1997, 1998, 1999,
4 2000, 2001 Free Software Foundation, Inc.
5
6 This file is part of GNU CC.
7
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.
12
13 In addition to the permissions in the GNU General Public License, the
14 Free Software Foundation gives you unlimited permission to link the
15 compiled version of this file into combinations with other programs,
16 and to distribute those combinations without any restriction coming
17 from the use of this file. (The General Public License restrictions
18 do apply in other respects; for example, they cover modification of
19 the file, and distribution when not linked into a combine
20 executable.)
21
22 GNU CC is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 GNU General Public License for more details.
26
27 You should have received a copy of the GNU General Public License
28 along with GNU CC; see the file COPYING. If not, write to
29 the Free Software Foundation, 59 Temple Place - Suite 330,
30 Boston, MA 02111-1307, USA. */
31
32 /* It is incorrect to include config.h here, because this file is being
33 compiled for the target, and hence definitions concerning only the host
34 do not apply. */
35
36 #include "tconfig.h"
37 #include "tsystem.h"
38
39 #include "machmode.h"
40
41 /* Don't use `fancy_abort' here even if config.h says to use it. */
42 #ifdef abort
43 #undef abort
44 #endif
45
46 #include "libgcc2.h"
47 \f
48 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
49 #if defined (L_divdi3) || defined (L_moddi3)
50 static inline
51 #endif
52 DWtype
53 __negdi2 (DWtype u)
54 {
55 DWunion w;
56 DWunion uu;
57
58 uu.ll = u;
59
60 w.s.low = -uu.s.low;
61 w.s.high = -uu.s.high - ((UWtype) w.s.low > 0);
62
63 return w.ll;
64 }
65 #endif
66
67 #ifdef L_addvsi3
68 Wtype
69 __addvsi3 (Wtype a, Wtype b)
70 {
71 Wtype w;
72
73 w = a + b;
74
75 if (b >= 0 ? w < a : w > a)
76 abort ();
77
78 return w;
79 }
80 #endif
81 \f
82 #ifdef L_addvdi3
83 DWtype
84 __addvdi3 (DWtype a, DWtype b)
85 {
86 DWtype w;
87
88 w = a + b;
89
90 if (b >= 0 ? w < a : w > a)
91 abort ();
92
93 return w;
94 }
95 #endif
96 \f
97 #ifdef L_subvsi3
98 Wtype
99 __subvsi3 (Wtype a, Wtype b)
100 {
101 #ifdef L_addvsi3
102 return __addvsi3 (a, (-b));
103 #else
104 DWtype w;
105
106 w = a - b;
107
108 if (b >= 0 ? w > a : w < a)
109 abort ();
110
111 return w;
112 #endif
113 }
114 #endif
115 \f
116 #ifdef L_subvdi3
117 DWtype
118 __subvdi3 (DWtype a, DWtype b)
119 {
120 #ifdef L_addvdi3
121 return (a, (-b));
122 #else
123 DWtype w;
124
125 w = a - b;
126
127 if (b >= 0 ? w > a : w < a)
128 abort ();
129
130 return w;
131 #endif
132 }
133 #endif
134 \f
135 #ifdef L_mulvsi3
136 Wtype
137 __mulvsi3 (Wtype a, Wtype b)
138 {
139 DWtype w;
140
141 w = a * b;
142
143 if (((a >= 0) == (b >= 0)) ? w < 0 : w > 0)
144 abort ();
145
146 return w;
147 }
148 #endif
149 \f
150 #ifdef L_negvsi2
151 Wtype
152 __negvsi2 (Wtype a)
153 {
154 Wtype w;
155
156 w = -a;
157
158 if (a >= 0 ? w > 0 : w < 0)
159 abort ();
160
161 return w;
162 }
163 #endif
164 \f
165 #ifdef L_negvdi2
166 DWtype
167 __negvdi2 (DWtype a)
168 {
169 DWtype w;
170
171 w = -a;
172
173 if (a >= 0 ? w > 0 : w < 0)
174 abort ();
175
176 return w;
177 }
178 #endif
179 \f
180 #ifdef L_absvsi2
181 Wtype
182 __absvsi2 (Wtype a)
183 {
184 Wtype w = a;
185
186 if (a < 0)
187 #ifdef L_negvsi2
188 w = __negvsi2 (a);
189 #else
190 w = -a;
191
192 if (w < 0)
193 abort ();
194 #endif
195
196 return w;
197 }
198 #endif
199 \f
200 #ifdef L_absvdi2
201 DWtype
202 __absvdi2 (DWtype a)
203 {
204 DWtype w = a;
205
206 if (a < 0)
207 #ifdef L_negvsi2
208 w = __negvsi2 (a);
209 #else
210 w = -a;
211
212 if (w < 0)
213 abort ();
214 #endif
215
216 return w;
217 }
218 #endif
219 \f
220 #ifdef L_mulvdi3
221 DWtype
222 __mulvdi3 (DWtype u, DWtype v)
223 {
224 DWtype w;
225
226 w = u * v;
227
228 if (((u >= 0) == (v >= 0)) ? w < 0 : w > 0)
229 abort ();
230
231 return w;
232 }
233 #endif
234 \f
235
236 /* Unless shift functions are defined whith full ANSI prototypes,
237 parameter b will be promoted to int if word_type is smaller than an int. */
238 #ifdef L_lshrdi3
239 DWtype
240 __lshrdi3 (DWtype u, word_type b)
241 {
242 DWunion w;
243 word_type bm;
244 DWunion uu;
245
246 if (b == 0)
247 return u;
248
249 uu.ll = u;
250
251 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
252 if (bm <= 0)
253 {
254 w.s.high = 0;
255 w.s.low = (UWtype) uu.s.high >> -bm;
256 }
257 else
258 {
259 UWtype carries = (UWtype) uu.s.high << bm;
260
261 w.s.high = (UWtype) uu.s.high >> b;
262 w.s.low = ((UWtype) uu.s.low >> b) | carries;
263 }
264
265 return w.ll;
266 }
267 #endif
268
269 #ifdef L_ashldi3
270 DWtype
271 __ashldi3 (DWtype u, word_type b)
272 {
273 DWunion w;
274 word_type bm;
275 DWunion uu;
276
277 if (b == 0)
278 return u;
279
280 uu.ll = u;
281
282 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
283 if (bm <= 0)
284 {
285 w.s.low = 0;
286 w.s.high = (UWtype) uu.s.low << -bm;
287 }
288 else
289 {
290 UWtype carries = (UWtype) uu.s.low >> bm;
291
292 w.s.low = (UWtype) uu.s.low << b;
293 w.s.high = ((UWtype) uu.s.high << b) | carries;
294 }
295
296 return w.ll;
297 }
298 #endif
299
300 #ifdef L_ashrdi3
301 DWtype
302 __ashrdi3 (DWtype u, word_type b)
303 {
304 DWunion w;
305 word_type bm;
306 DWunion uu;
307
308 if (b == 0)
309 return u;
310
311 uu.ll = u;
312
313 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
314 if (bm <= 0)
315 {
316 /* w.s.high = 1..1 or 0..0 */
317 w.s.high = uu.s.high >> (sizeof (Wtype) * BITS_PER_UNIT - 1);
318 w.s.low = uu.s.high >> -bm;
319 }
320 else
321 {
322 UWtype carries = (UWtype) uu.s.high << bm;
323
324 w.s.high = uu.s.high >> b;
325 w.s.low = ((UWtype) uu.s.low >> b) | carries;
326 }
327
328 return w.ll;
329 }
330 #endif
331 \f
332 #ifdef L_ffsdi2
333 DWtype
334 __ffsdi2 (DWtype u)
335 {
336 DWunion uu;
337 UWtype word, count, add;
338
339 uu.ll = u;
340 if (uu.s.low != 0)
341 word = uu.s.low, add = 0;
342 else if (uu.s.high != 0)
343 word = uu.s.high, add = BITS_PER_UNIT * sizeof (Wtype);
344 else
345 return 0;
346
347 count_trailing_zeros (count, word);
348 return count + add + 1;
349 }
350 #endif
351 \f
352 #ifdef L_muldi3
353 DWtype
354 __muldi3 (DWtype u, DWtype v)
355 {
356 DWunion w;
357 DWunion uu, vv;
358
359 uu.ll = u,
360 vv.ll = v;
361
362 w.ll = __umulsidi3 (uu.s.low, vv.s.low);
363 w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
364 + (UWtype) uu.s.high * (UWtype) vv.s.low);
365
366 return w.ll;
367 }
368 #endif
369 \f
370 #ifdef L_udiv_w_sdiv
371 #if defined (sdiv_qrnnd)
372 UWtype
373 __udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d)
374 {
375 UWtype q, r;
376 UWtype c0, c1, b1;
377
378 if ((Wtype) d >= 0)
379 {
380 if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1)))
381 {
382 /* dividend, divisor, and quotient are nonnegative */
383 sdiv_qrnnd (q, r, a1, a0, d);
384 }
385 else
386 {
387 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
388 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1));
389 /* Divide (c1*2^32 + c0) by d */
390 sdiv_qrnnd (q, r, c1, c0, d);
391 /* Add 2^31 to quotient */
392 q += (UWtype) 1 << (W_TYPE_SIZE - 1);
393 }
394 }
395 else
396 {
397 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
398 c1 = a1 >> 1; /* A/2 */
399 c0 = (a1 << (W_TYPE_SIZE - 1)) + (a0 >> 1);
400
401 if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
402 {
403 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
404
405 r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
406 if ((d & 1) != 0)
407 {
408 if (r >= q)
409 r = r - q;
410 else if (q - r <= d)
411 {
412 r = r - q + d;
413 q--;
414 }
415 else
416 {
417 r = r - q + 2*d;
418 q -= 2;
419 }
420 }
421 }
422 else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
423 {
424 c1 = (b1 - 1) - c1;
425 c0 = ~c0; /* logical NOT */
426
427 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
428
429 q = ~q; /* (A/2)/b1 */
430 r = (b1 - 1) - r;
431
432 r = 2*r + (a0 & 1); /* A/(2*b1) */
433
434 if ((d & 1) != 0)
435 {
436 if (r >= q)
437 r = r - q;
438 else if (q - r <= d)
439 {
440 r = r - q + d;
441 q--;
442 }
443 else
444 {
445 r = r - q + 2*d;
446 q -= 2;
447 }
448 }
449 }
450 else /* Implies c1 = b1 */
451 { /* Hence a1 = d - 1 = 2*b1 - 1 */
452 if (a0 >= -d)
453 {
454 q = -1;
455 r = a0 + d;
456 }
457 else
458 {
459 q = -2;
460 r = a0 + 2*d;
461 }
462 }
463 }
464
465 *rp = r;
466 return q;
467 }
468 #else
469 /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */
470 UWtype
471 __udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)),
472 UWtype a1 __attribute__ ((__unused__)),
473 UWtype a0 __attribute__ ((__unused__)),
474 UWtype d __attribute__ ((__unused__)))
475 {
476 return 0;
477 }
478 #endif
479 #endif
480 \f
481 #if (defined (L_udivdi3) || defined (L_divdi3) || \
482 defined (L_umoddi3) || defined (L_moddi3))
483 #define L_udivmoddi4
484 #endif
485
486 #ifdef L_clz
487 const UQItype __clz_tab[] =
488 {
489 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,
490 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,
491 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,
492 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,
493 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,
494 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,
495 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,
496 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,
497 };
498 #endif
499
500 #ifdef L_udivmoddi4
501
502 #if (defined (L_udivdi3) || defined (L_divdi3) || \
503 defined (L_umoddi3) || defined (L_moddi3))
504 static inline
505 #endif
506 UDWtype
507 __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
508 {
509 DWunion ww;
510 DWunion nn, dd;
511 DWunion rr;
512 UWtype d0, d1, n0, n1, n2;
513 UWtype q0, q1;
514 UWtype b, bm;
515
516 nn.ll = n;
517 dd.ll = d;
518
519 d0 = dd.s.low;
520 d1 = dd.s.high;
521 n0 = nn.s.low;
522 n1 = nn.s.high;
523
524 #if !UDIV_NEEDS_NORMALIZATION
525 if (d1 == 0)
526 {
527 if (d0 > n1)
528 {
529 /* 0q = nn / 0D */
530
531 udiv_qrnnd (q0, n0, n1, n0, d0);
532 q1 = 0;
533
534 /* Remainder in n0. */
535 }
536 else
537 {
538 /* qq = NN / 0d */
539
540 if (d0 == 0)
541 d0 = 1 / d0; /* Divide intentionally by zero. */
542
543 udiv_qrnnd (q1, n1, 0, n1, d0);
544 udiv_qrnnd (q0, n0, n1, n0, d0);
545
546 /* Remainder in n0. */
547 }
548
549 if (rp != 0)
550 {
551 rr.s.low = n0;
552 rr.s.high = 0;
553 *rp = rr.ll;
554 }
555 }
556
557 #else /* UDIV_NEEDS_NORMALIZATION */
558
559 if (d1 == 0)
560 {
561 if (d0 > n1)
562 {
563 /* 0q = nn / 0D */
564
565 count_leading_zeros (bm, d0);
566
567 if (bm != 0)
568 {
569 /* Normalize, i.e. make the most significant bit of the
570 denominator set. */
571
572 d0 = d0 << bm;
573 n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
574 n0 = n0 << bm;
575 }
576
577 udiv_qrnnd (q0, n0, n1, n0, d0);
578 q1 = 0;
579
580 /* Remainder in n0 >> bm. */
581 }
582 else
583 {
584 /* qq = NN / 0d */
585
586 if (d0 == 0)
587 d0 = 1 / d0; /* Divide intentionally by zero. */
588
589 count_leading_zeros (bm, d0);
590
591 if (bm == 0)
592 {
593 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
594 conclude (the most significant bit of n1 is set) /\ (the
595 leading quotient digit q1 = 1).
596
597 This special case is necessary, not an optimization.
598 (Shifts counts of W_TYPE_SIZE are undefined.) */
599
600 n1 -= d0;
601 q1 = 1;
602 }
603 else
604 {
605 /* Normalize. */
606
607 b = W_TYPE_SIZE - bm;
608
609 d0 = d0 << bm;
610 n2 = n1 >> b;
611 n1 = (n1 << bm) | (n0 >> b);
612 n0 = n0 << bm;
613
614 udiv_qrnnd (q1, n1, n2, n1, d0);
615 }
616
617 /* n1 != d0... */
618
619 udiv_qrnnd (q0, n0, n1, n0, d0);
620
621 /* Remainder in n0 >> bm. */
622 }
623
624 if (rp != 0)
625 {
626 rr.s.low = n0 >> bm;
627 rr.s.high = 0;
628 *rp = rr.ll;
629 }
630 }
631 #endif /* UDIV_NEEDS_NORMALIZATION */
632
633 else
634 {
635 if (d1 > n1)
636 {
637 /* 00 = nn / DD */
638
639 q0 = 0;
640 q1 = 0;
641
642 /* Remainder in n1n0. */
643 if (rp != 0)
644 {
645 rr.s.low = n0;
646 rr.s.high = n1;
647 *rp = rr.ll;
648 }
649 }
650 else
651 {
652 /* 0q = NN / dd */
653
654 count_leading_zeros (bm, d1);
655 if (bm == 0)
656 {
657 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
658 conclude (the most significant bit of n1 is set) /\ (the
659 quotient digit q0 = 0 or 1).
660
661 This special case is necessary, not an optimization. */
662
663 /* The condition on the next line takes advantage of that
664 n1 >= d1 (true due to program flow). */
665 if (n1 > d1 || n0 >= d0)
666 {
667 q0 = 1;
668 sub_ddmmss (n1, n0, n1, n0, d1, d0);
669 }
670 else
671 q0 = 0;
672
673 q1 = 0;
674
675 if (rp != 0)
676 {
677 rr.s.low = n0;
678 rr.s.high = n1;
679 *rp = rr.ll;
680 }
681 }
682 else
683 {
684 UWtype m1, m0;
685 /* Normalize. */
686
687 b = W_TYPE_SIZE - bm;
688
689 d1 = (d1 << bm) | (d0 >> b);
690 d0 = d0 << bm;
691 n2 = n1 >> b;
692 n1 = (n1 << bm) | (n0 >> b);
693 n0 = n0 << bm;
694
695 udiv_qrnnd (q0, n1, n2, n1, d1);
696 umul_ppmm (m1, m0, q0, d0);
697
698 if (m1 > n1 || (m1 == n1 && m0 > n0))
699 {
700 q0--;
701 sub_ddmmss (m1, m0, m1, m0, d1, d0);
702 }
703
704 q1 = 0;
705
706 /* Remainder in (n1n0 - m1m0) >> bm. */
707 if (rp != 0)
708 {
709 sub_ddmmss (n1, n0, n1, n0, m1, m0);
710 rr.s.low = (n1 << b) | (n0 >> bm);
711 rr.s.high = n1 >> bm;
712 *rp = rr.ll;
713 }
714 }
715 }
716 }
717
718 ww.s.low = q0;
719 ww.s.high = q1;
720 return ww.ll;
721 }
722 #endif
723
724 #ifdef L_divdi3
725 DWtype
726 __divdi3 (DWtype u, DWtype v)
727 {
728 word_type c = 0;
729 DWunion uu, vv;
730 DWtype w;
731
732 uu.ll = u;
733 vv.ll = v;
734
735 if (uu.s.high < 0)
736 c = ~c,
737 uu.ll = __negdi2 (uu.ll);
738 if (vv.s.high < 0)
739 c = ~c,
740 vv.ll = __negdi2 (vv.ll);
741
742 w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
743 if (c)
744 w = __negdi2 (w);
745
746 return w;
747 }
748 #endif
749
750 #ifdef L_moddi3
751 DWtype
752 __moddi3 (DWtype u, DWtype v)
753 {
754 word_type c = 0;
755 DWunion uu, vv;
756 DWtype w;
757
758 uu.ll = u;
759 vv.ll = v;
760
761 if (uu.s.high < 0)
762 c = ~c,
763 uu.ll = __negdi2 (uu.ll);
764 if (vv.s.high < 0)
765 vv.ll = __negdi2 (vv.ll);
766
767 (void) __udivmoddi4 (uu.ll, vv.ll, &w);
768 if (c)
769 w = __negdi2 (w);
770
771 return w;
772 }
773 #endif
774
775 #ifdef L_umoddi3
776 UDWtype
777 __umoddi3 (UDWtype u, UDWtype v)
778 {
779 UDWtype w;
780
781 (void) __udivmoddi4 (u, v, &w);
782
783 return w;
784 }
785 #endif
786
787 #ifdef L_udivdi3
788 UDWtype
789 __udivdi3 (UDWtype n, UDWtype d)
790 {
791 return __udivmoddi4 (n, d, (UDWtype *) 0);
792 }
793 #endif
794 \f
795 #ifdef L_cmpdi2
796 word_type
797 __cmpdi2 (DWtype a, DWtype b)
798 {
799 DWunion au, bu;
800
801 au.ll = a, bu.ll = b;
802
803 if (au.s.high < bu.s.high)
804 return 0;
805 else if (au.s.high > bu.s.high)
806 return 2;
807 if ((UWtype) au.s.low < (UWtype) bu.s.low)
808 return 0;
809 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
810 return 2;
811 return 1;
812 }
813 #endif
814
815 #ifdef L_ucmpdi2
816 word_type
817 __ucmpdi2 (DWtype a, DWtype b)
818 {
819 DWunion au, bu;
820
821 au.ll = a, bu.ll = b;
822
823 if ((UWtype) au.s.high < (UWtype) bu.s.high)
824 return 0;
825 else if ((UWtype) au.s.high > (UWtype) bu.s.high)
826 return 2;
827 if ((UWtype) au.s.low < (UWtype) bu.s.low)
828 return 0;
829 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
830 return 2;
831 return 1;
832 }
833 #endif
834 \f
835 #if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
836 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
837 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
838
839 DWtype
840 __fixunstfDI (TFtype a)
841 {
842 TFtype b;
843 UDWtype 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 DWtype!),
851 and shift it into the high word. */
852 v = (UWtype) b;
853 v <<= WORD_SIZE;
854 /* Remove high part from the TFtype, leaving the low part as flonum. */
855 a -= (TFtype)v;
856 /* Convert that to fixed (but not to DWtype!) 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 -= (UWtype) (- a);
861 else
862 v += (UWtype) a;
863 return v;
864 }
865 #endif
866
867 #if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
868 DWtype
869 __fixtfdi (TFtype a)
870 {
871 if (a < 0)
872 return - __fixunstfDI (-a);
873 return __fixunstfDI (a);
874 }
875 #endif
876
877 #if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
878 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
879 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
880
881 DWtype
882 __fixunsxfDI (XFtype a)
883 {
884 XFtype b;
885 UDWtype v;
886
887 if (a < 0)
888 return 0;
889
890 /* Compute high word of result, as a flonum. */
891 b = (a / HIGH_WORD_COEFF);
892 /* Convert that to fixed (but not to DWtype!),
893 and shift it into the high word. */
894 v = (UWtype) b;
895 v <<= WORD_SIZE;
896 /* Remove high part from the XFtype, leaving the low part as flonum. */
897 a -= (XFtype)v;
898 /* Convert that to fixed (but not to DWtype!) and add it in.
899 Sometimes A comes out negative. This is significant, since
900 A has more bits than a long int does. */
901 if (a < 0)
902 v -= (UWtype) (- a);
903 else
904 v += (UWtype) a;
905 return v;
906 }
907 #endif
908
909 #if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
910 DWtype
911 __fixxfdi (XFtype a)
912 {
913 if (a < 0)
914 return - __fixunsxfDI (-a);
915 return __fixunsxfDI (a);
916 }
917 #endif
918
919 #ifdef L_fixunsdfdi
920 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
921 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
922
923 DWtype
924 __fixunsdfDI (DFtype a)
925 {
926 DFtype b;
927 UDWtype v;
928
929 if (a < 0)
930 return 0;
931
932 /* Compute high word of result, as a flonum. */
933 b = (a / HIGH_WORD_COEFF);
934 /* Convert that to fixed (but not to DWtype!),
935 and shift it into the high word. */
936 v = (UWtype) b;
937 v <<= WORD_SIZE;
938 /* Remove high part from the DFtype, leaving the low part as flonum. */
939 a -= (DFtype)v;
940 /* Convert that to fixed (but not to DWtype!) and add it in.
941 Sometimes A comes out negative. This is significant, since
942 A has more bits than a long int does. */
943 if (a < 0)
944 v -= (UWtype) (- a);
945 else
946 v += (UWtype) a;
947 return v;
948 }
949 #endif
950
951 #ifdef L_fixdfdi
952 DWtype
953 __fixdfdi (DFtype a)
954 {
955 if (a < 0)
956 return - __fixunsdfDI (-a);
957 return __fixunsdfDI (a);
958 }
959 #endif
960
961 #ifdef L_fixunssfdi
962 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
963 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
964
965 DWtype
966 __fixunssfDI (SFtype original_a)
967 {
968 /* Convert the SFtype to a DFtype, because that is surely not going
969 to lose any bits. Some day someone else can write a faster version
970 that avoids converting to DFtype, and verify it really works right. */
971 DFtype a = original_a;
972 DFtype b;
973 UDWtype v;
974
975 if (a < 0)
976 return 0;
977
978 /* Compute high word of result, as a flonum. */
979 b = (a / HIGH_WORD_COEFF);
980 /* Convert that to fixed (but not to DWtype!),
981 and shift it into the high word. */
982 v = (UWtype) b;
983 v <<= WORD_SIZE;
984 /* Remove high part from the DFtype, leaving the low part as flonum. */
985 a -= (DFtype) v;
986 /* Convert that to fixed (but not to DWtype!) and add it in.
987 Sometimes A comes out negative. This is significant, since
988 A has more bits than a long int does. */
989 if (a < 0)
990 v -= (UWtype) (- a);
991 else
992 v += (UWtype) a;
993 return v;
994 }
995 #endif
996
997 #ifdef L_fixsfdi
998 DWtype
999 __fixsfdi (SFtype a)
1000 {
1001 if (a < 0)
1002 return - __fixunssfDI (-a);
1003 return __fixunssfDI (a);
1004 }
1005 #endif
1006
1007 #if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
1008 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1009 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1010 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1011
1012 XFtype
1013 __floatdixf (DWtype u)
1014 {
1015 XFtype d;
1016
1017 d = (Wtype) (u >> WORD_SIZE);
1018 d *= HIGH_HALFWORD_COEFF;
1019 d *= HIGH_HALFWORD_COEFF;
1020 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1021
1022 return d;
1023 }
1024 #endif
1025
1026 #if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
1027 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1028 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1029 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1030
1031 TFtype
1032 __floatditf (DWtype u)
1033 {
1034 TFtype d;
1035
1036 d = (Wtype) (u >> WORD_SIZE);
1037 d *= HIGH_HALFWORD_COEFF;
1038 d *= HIGH_HALFWORD_COEFF;
1039 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1040
1041 return d;
1042 }
1043 #endif
1044
1045 #ifdef L_floatdidf
1046 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1047 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1048 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1049
1050 DFtype
1051 __floatdidf (DWtype u)
1052 {
1053 DFtype d;
1054
1055 d = (Wtype) (u >> WORD_SIZE);
1056 d *= HIGH_HALFWORD_COEFF;
1057 d *= HIGH_HALFWORD_COEFF;
1058 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1059
1060 return d;
1061 }
1062 #endif
1063
1064 #ifdef L_floatdisf
1065 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1066 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1067 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1068 #define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT)
1069
1070 /* Define codes for all the float formats that we know of. Note
1071 that this is copied from real.h. */
1072
1073 #define UNKNOWN_FLOAT_FORMAT 0
1074 #define IEEE_FLOAT_FORMAT 1
1075 #define VAX_FLOAT_FORMAT 2
1076 #define IBM_FLOAT_FORMAT 3
1077
1078 /* Default to IEEE float if not specified. Nearly all machines use it. */
1079 #ifndef HOST_FLOAT_FORMAT
1080 #define HOST_FLOAT_FORMAT IEEE_FLOAT_FORMAT
1081 #endif
1082
1083 #if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1084 #define DF_SIZE 53
1085 #define SF_SIZE 24
1086 #endif
1087
1088 #if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
1089 #define DF_SIZE 56
1090 #define SF_SIZE 24
1091 #endif
1092
1093 #if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
1094 #define DF_SIZE 56
1095 #define SF_SIZE 24
1096 #endif
1097
1098 SFtype
1099 __floatdisf (DWtype u)
1100 {
1101 /* Do the calculation in DFmode
1102 so that we don't lose any of the precision of the high word
1103 while multiplying it. */
1104 DFtype f;
1105
1106 /* Protect against double-rounding error.
1107 Represent any low-order bits, that might be truncated in DFmode,
1108 by a bit that won't be lost. The bit can go in anywhere below the
1109 rounding position of the SFmode. A fixed mask and bit position
1110 handles all usual configurations. It doesn't handle the case
1111 of 128-bit DImode, however. */
1112 if (DF_SIZE < DI_SIZE
1113 && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1114 {
1115 #define REP_BIT ((UDWtype) 1 << (DI_SIZE - DF_SIZE))
1116 if (! (- ((DWtype) 1 << DF_SIZE) < u
1117 && u < ((DWtype) 1 << DF_SIZE)))
1118 {
1119 if ((UDWtype) u & (REP_BIT - 1))
1120 u |= REP_BIT;
1121 }
1122 }
1123 f = (Wtype) (u >> WORD_SIZE);
1124 f *= HIGH_HALFWORD_COEFF;
1125 f *= HIGH_HALFWORD_COEFF;
1126 f += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1127
1128 return (SFtype) f;
1129 }
1130 #endif
1131
1132 #if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
1133 /* Reenable the normal types, in case limits.h needs them. */
1134 #undef char
1135 #undef short
1136 #undef int
1137 #undef long
1138 #undef unsigned
1139 #undef float
1140 #undef double
1141 #undef MIN
1142 #undef MAX
1143 #include <limits.h>
1144
1145 UWtype
1146 __fixunsxfSI (XFtype a)
1147 {
1148 if (a >= - (DFtype) Wtype_MIN)
1149 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1150 return (Wtype) a;
1151 }
1152 #endif
1153
1154 #ifdef L_fixunsdfsi
1155 /* Reenable the normal types, in case limits.h needs them. */
1156 #undef char
1157 #undef short
1158 #undef int
1159 #undef long
1160 #undef unsigned
1161 #undef float
1162 #undef double
1163 #undef MIN
1164 #undef MAX
1165 #include <limits.h>
1166
1167 UWtype
1168 __fixunsdfSI (DFtype a)
1169 {
1170 if (a >= - (DFtype) Wtype_MIN)
1171 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1172 return (Wtype) a;
1173 }
1174 #endif
1175
1176 #ifdef L_fixunssfsi
1177 /* Reenable the normal types, in case limits.h needs them. */
1178 #undef char
1179 #undef short
1180 #undef int
1181 #undef long
1182 #undef unsigned
1183 #undef float
1184 #undef double
1185 #undef MIN
1186 #undef MAX
1187 #include <limits.h>
1188
1189 UWtype
1190 __fixunssfSI (SFtype a)
1191 {
1192 if (a >= - (SFtype) Wtype_MIN)
1193 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1194 return (Wtype) a;
1195 }
1196 #endif
1197 \f
1198 /* From here on down, the routines use normal data types. */
1199
1200 #define SItype bogus_type
1201 #define USItype bogus_type
1202 #define DItype bogus_type
1203 #define UDItype bogus_type
1204 #define SFtype bogus_type
1205 #define DFtype bogus_type
1206 #undef Wtype
1207 #undef UWtype
1208 #undef HWtype
1209 #undef UHWtype
1210 #undef DWtype
1211 #undef UDWtype
1212
1213 #undef char
1214 #undef short
1215 #undef int
1216 #undef long
1217 #undef unsigned
1218 #undef float
1219 #undef double
1220 \f
1221 #ifdef L__gcc_bcmp
1222
1223 /* Like bcmp except the sign is meaningful.
1224 Result is negative if S1 is less than S2,
1225 positive if S1 is greater, 0 if S1 and S2 are equal. */
1226
1227 int
1228 __gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
1229 {
1230 while (size > 0)
1231 {
1232 unsigned char c1 = *s1++, c2 = *s2++;
1233 if (c1 != c2)
1234 return c1 - c2;
1235 size--;
1236 }
1237 return 0;
1238 }
1239
1240 #endif
1241 \f
1242 /* __eprintf used to be used by GCC's private version of <assert.h>.
1243 We no longer provide that header, but this routine remains in libgcc.a
1244 for binary backward compatibility. Note that it is not included in
1245 the shared version of libgcc. */
1246 #ifdef L_eprintf
1247 #ifndef inhibit_libc
1248
1249 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1250 #include <stdio.h>
1251
1252 void
1253 __eprintf (const char *string, const char *expression,
1254 unsigned int line, const char *filename)
1255 {
1256 fprintf (stderr, string, expression, line, filename);
1257 fflush (stderr);
1258 abort ();
1259 }
1260
1261 #endif
1262 #endif
1263
1264 #ifdef L_bb
1265
1266 /* Structure emitted by -a */
1267 struct bb
1268 {
1269 long zero_word;
1270 const char *filename;
1271 long *counts;
1272 long ncounts;
1273 struct bb *next;
1274 const unsigned long *addresses;
1275
1276 /* Older GCC's did not emit these fields. */
1277 long nwords;
1278 const char **functions;
1279 const long *line_nums;
1280 const char **filenames;
1281 char *flags;
1282 };
1283
1284 #ifdef BLOCK_PROFILER_CODE
1285 BLOCK_PROFILER_CODE
1286 #else
1287 #ifndef inhibit_libc
1288
1289 /* Simple minded basic block profiling output dumper for
1290 systems that don't provide tcov support. At present,
1291 it requires atexit and stdio. */
1292
1293 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1294 #include <stdio.h>
1295 char *ctime PARAMS ((const time_t *));
1296
1297 #include "gbl-ctors.h"
1298 #include "gcov-io.h"
1299 #include <string.h>
1300 #ifdef TARGET_HAS_F_SETLKW
1301 #include <fcntl.h>
1302 #include <errno.h>
1303 #endif
1304
1305 static struct bb *bb_head;
1306
1307 static int num_digits (long value, int base) __attribute__ ((const));
1308
1309 /* Return the number of digits needed to print a value */
1310 /* __inline__ */ static int num_digits (long value, int base)
1311 {
1312 int minus = (value < 0 && base != 16);
1313 unsigned long v = (minus) ? -value : value;
1314 int ret = minus;
1315
1316 do
1317 {
1318 v /= base;
1319 ret++;
1320 }
1321 while (v);
1322
1323 return ret;
1324 }
1325
1326 void
1327 __bb_exit_func (void)
1328 {
1329 FILE *da_file, *file;
1330 long time_value;
1331 int i;
1332
1333 if (bb_head == 0)
1334 return;
1335
1336 i = strlen (bb_head->filename) - 3;
1337
1338 if (!strcmp (bb_head->filename+i, ".da"))
1339 {
1340 /* Must be -fprofile-arcs not -a.
1341 Dump data in a form that gcov expects. */
1342
1343 struct bb *ptr;
1344
1345 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1346 {
1347 int firstchar;
1348
1349 /* Make sure the output file exists -
1350 but don't clobber exiting data. */
1351 if ((da_file = fopen (ptr->filename, "a")) != 0)
1352 fclose (da_file);
1353
1354 /* Need to re-open in order to be able to write from the start. */
1355 da_file = fopen (ptr->filename, "r+b");
1356 /* Some old systems might not allow the 'b' mode modifier.
1357 Therefore, try to open without it. This can lead to a race
1358 condition so that when you delete and re-create the file, the
1359 file might be opened in text mode, but then, you shouldn't
1360 delete the file in the first place. */
1361 if (da_file == 0)
1362 da_file = fopen (ptr->filename, "r+");
1363 if (da_file == 0)
1364 {
1365 fprintf (stderr, "arc profiling: Can't open output file %s.\n",
1366 ptr->filename);
1367 continue;
1368 }
1369
1370 /* After a fork, another process might try to read and/or write
1371 the same file simultanously. So if we can, lock the file to
1372 avoid race conditions. */
1373 #if defined (TARGET_HAS_F_SETLKW)
1374 {
1375 struct flock s_flock;
1376
1377 s_flock.l_type = F_WRLCK;
1378 s_flock.l_whence = SEEK_SET;
1379 s_flock.l_start = 0;
1380 s_flock.l_len = 1;
1381 s_flock.l_pid = getpid ();
1382
1383 while (fcntl (fileno (da_file), F_SETLKW, &s_flock)
1384 && errno == EINTR);
1385 }
1386 #endif
1387
1388 /* If the file is not empty, and the number of counts in it is the
1389 same, then merge them in. */
1390 firstchar = fgetc (da_file);
1391 if (firstchar == EOF)
1392 {
1393 if (ferror (da_file))
1394 {
1395 fprintf (stderr, "arc profiling: Can't read output file ");
1396 perror (ptr->filename);
1397 }
1398 }
1399 else
1400 {
1401 long n_counts = 0;
1402
1403 if (ungetc (firstchar, da_file) == EOF)
1404 rewind (da_file);
1405 if (__read_long (&n_counts, da_file, 8) != 0)
1406 {
1407 fprintf (stderr, "arc profiling: Can't read output file %s.\n",
1408 ptr->filename);
1409 continue;
1410 }
1411
1412 if (n_counts == ptr->ncounts)
1413 {
1414 int i;
1415
1416 for (i = 0; i < n_counts; i++)
1417 {
1418 long v = 0;
1419
1420 if (__read_long (&v, da_file, 8) != 0)
1421 {
1422 fprintf (stderr, "arc profiling: Can't read output file %s.\n",
1423 ptr->filename);
1424 break;
1425 }
1426 ptr->counts[i] += v;
1427 }
1428 }
1429
1430 }
1431
1432 rewind (da_file);
1433
1434 /* ??? Should first write a header to the file. Preferably, a 4 byte
1435 magic number, 4 bytes containing the time the program was
1436 compiled, 4 bytes containing the last modification time of the
1437 source file, and 4 bytes indicating the compiler options used.
1438
1439 That way we can easily verify that the proper source/executable/
1440 data file combination is being used from gcov. */
1441
1442 if (__write_long (ptr->ncounts, da_file, 8) != 0)
1443 {
1444
1445 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1446 ptr->filename);
1447 }
1448 else
1449 {
1450 int j;
1451 long *count_ptr = ptr->counts;
1452 int ret = 0;
1453 for (j = ptr->ncounts; j > 0; j--)
1454 {
1455 if (__write_long (*count_ptr, da_file, 8) != 0)
1456 {
1457 ret=1;
1458 break;
1459 }
1460 count_ptr++;
1461 }
1462 if (ret)
1463 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1464 ptr->filename);
1465 }
1466
1467 if (fclose (da_file) == EOF)
1468 fprintf (stderr, "arc profiling: Error closing output file %s.\n",
1469 ptr->filename);
1470 }
1471
1472 return;
1473 }
1474
1475 /* Must be basic block profiling. Emit a human readable output file. */
1476
1477 file = fopen ("bb.out", "a");
1478
1479 if (!file)
1480 perror ("bb.out");
1481
1482 else
1483 {
1484 struct bb *ptr;
1485
1486 /* This is somewhat type incorrect, but it avoids worrying about
1487 exactly where time.h is included from. It should be ok unless
1488 a void * differs from other pointer formats, or if sizeof (long)
1489 is < sizeof (time_t). It would be nice if we could assume the
1490 use of rationale standards here. */
1491
1492 time ((void *) &time_value);
1493 fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value));
1494
1495 /* We check the length field explicitly in order to allow compatibility
1496 with older GCC's which did not provide it. */
1497
1498 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1499 {
1500 int i;
1501 int func_p = (ptr->nwords >= (long) sizeof (struct bb)
1502 && ptr->nwords <= 1000
1503 && ptr->functions);
1504 int line_p = (func_p && ptr->line_nums);
1505 int file_p = (func_p && ptr->filenames);
1506 int addr_p = (ptr->addresses != 0);
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_p && (unsigned long) 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)",
1562 blk_len, i+1,
1563 cnt_len, ptr->counts[i]);
1564
1565 if (addr_p)
1566 fprintf (file, " address= 0x%.*lx", addr_len,
1567 ptr->addresses[i]);
1568
1569 if (func_p)
1570 fprintf (file, " function= %-*s", func_len,
1571 (ptr->functions[i]) ? ptr->functions[i] : "<none>");
1572
1573 if (line_p)
1574 fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]);
1575
1576 if (file_p)
1577 fprintf (file, " file= %s",
1578 (ptr->filenames[i]) ? ptr->filenames[i] : "<none>");
1579
1580 fprintf (file, "\n");
1581 }
1582
1583 fprintf (file, "\n");
1584 fflush (file);
1585 }
1586
1587 fprintf (file, "\n\n");
1588 fclose (file);
1589 }
1590 }
1591
1592 void
1593 __bb_init_func (struct bb *blocks)
1594 {
1595 /* User is supposed to check whether the first word is non-0,
1596 but just in case.... */
1597
1598 if (blocks->zero_word)
1599 return;
1600
1601 /* Initialize destructor. */
1602 if (!bb_head)
1603 atexit (__bb_exit_func);
1604
1605 /* Set up linked list. */
1606 blocks->zero_word = 1;
1607 blocks->next = bb_head;
1608 bb_head = blocks;
1609 }
1610
1611 /* Called before fork or exec - write out profile information gathered so
1612 far and reset it to zero. This avoids duplication or loss of the
1613 profile information gathered so far. */
1614 void
1615 __bb_fork_func (void)
1616 {
1617 struct bb *ptr;
1618
1619 __bb_exit_func ();
1620 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1621 {
1622 long i;
1623 for (i = ptr->ncounts - 1; i >= 0; i--)
1624 ptr->counts[i] = 0;
1625 }
1626 }
1627
1628 #ifndef MACHINE_STATE_SAVE
1629 #define MACHINE_STATE_SAVE(ID)
1630 #endif
1631 #ifndef MACHINE_STATE_RESTORE
1632 #define MACHINE_STATE_RESTORE(ID)
1633 #endif
1634
1635 /* Number of buckets in hashtable of basic block addresses. */
1636
1637 #define BB_BUCKETS 311
1638
1639 /* Maximum length of string in file bb.in. */
1640
1641 #define BBINBUFSIZE 500
1642
1643 struct bb_edge
1644 {
1645 struct bb_edge *next;
1646 unsigned long src_addr;
1647 unsigned long dst_addr;
1648 unsigned long count;
1649 };
1650
1651 enum bb_func_mode
1652 {
1653 TRACE_KEEP = 0, TRACE_ON = 1, TRACE_OFF = 2
1654 };
1655
1656 struct bb_func
1657 {
1658 struct bb_func *next;
1659 char *funcname;
1660 char *filename;
1661 enum bb_func_mode mode;
1662 };
1663
1664 /* This is the connection to the outside world.
1665 The BLOCK_PROFILER macro must set __bb.blocks
1666 and __bb.blockno. */
1667
1668 struct {
1669 unsigned long blockno;
1670 struct bb *blocks;
1671 } __bb;
1672
1673 /* Vars to store addrs of source and destination basic blocks
1674 of a jump. */
1675
1676 static unsigned long bb_src = 0;
1677 static unsigned long bb_dst = 0;
1678
1679 static FILE *bb_tracefile = (FILE *) 0;
1680 static struct bb_edge **bb_hashbuckets = (struct bb_edge **) 0;
1681 static struct bb_func *bb_func_head = (struct bb_func *) 0;
1682 static unsigned long bb_callcount = 0;
1683 static int bb_mode = 0;
1684
1685 static unsigned long *bb_stack = (unsigned long *) 0;
1686 static size_t bb_stacksize = 0;
1687
1688 static int reported = 0;
1689
1690 /* Trace modes:
1691 Always : Print execution frequencies of basic blocks
1692 to file bb.out.
1693 bb_mode & 1 != 0 : Dump trace of basic blocks to file bbtrace[.gz]
1694 bb_mode & 2 != 0 : Print jump frequencies to file bb.out.
1695 bb_mode & 4 != 0 : Cut call instructions from basic block flow.
1696 bb_mode & 8 != 0 : Insert return instructions in basic block flow.
1697 */
1698
1699 #ifdef HAVE_POPEN
1700
1701 /*#include <sys/types.h>*/
1702 #include <sys/stat.h>
1703 /*#include <malloc.h>*/
1704
1705 /* Commands executed by gopen. */
1706
1707 #define GOPENDECOMPRESS "gzip -cd "
1708 #define GOPENCOMPRESS "gzip -c >"
1709
1710 /* Like fopen but pipes through gzip. mode may only be "r" or "w".
1711 If it does not compile, simply replace gopen by fopen and delete
1712 '.gz' from any first parameter to gopen. */
1713
1714 static FILE *
1715 gopen (char *fn, char *mode)
1716 {
1717 int use_gzip;
1718 char *p;
1719
1720 if (mode[1])
1721 return (FILE *) 0;
1722
1723 if (mode[0] != 'r' && mode[0] != 'w')
1724 return (FILE *) 0;
1725
1726 p = fn + strlen (fn)-1;
1727 use_gzip = ((p[-1] == '.' && (p[0] == 'Z' || p[0] == 'z'))
1728 || (p[-2] == '.' && p[-1] == 'g' && p[0] == 'z'));
1729
1730 if (use_gzip)
1731 {
1732 if (mode[0]=='r')
1733 {
1734 FILE *f;
1735 char *s = (char *) malloc (sizeof (char) * strlen (fn)
1736 + sizeof (GOPENDECOMPRESS));
1737 strcpy (s, GOPENDECOMPRESS);
1738 strcpy (s + (sizeof (GOPENDECOMPRESS)-1), fn);
1739 f = popen (s, mode);
1740 free (s);
1741 return f;
1742 }
1743
1744 else
1745 {
1746 FILE *f;
1747 char *s = (char *) malloc (sizeof (char) * strlen (fn)
1748 + sizeof (GOPENCOMPRESS));
1749 strcpy (s, GOPENCOMPRESS);
1750 strcpy (s + (sizeof (GOPENCOMPRESS)-1), fn);
1751 if (!(f = popen (s, mode)))
1752 f = fopen (s, mode);
1753 free (s);
1754 return f;
1755 }
1756 }
1757
1758 else
1759 return fopen (fn, mode);
1760 }
1761
1762 static int
1763 gclose (FILE *f)
1764 {
1765 struct stat buf;
1766
1767 if (f != 0)
1768 {
1769 if (!fstat (fileno (f), &buf) && S_ISFIFO (buf.st_mode))
1770 return pclose (f);
1771
1772 return fclose (f);
1773 }
1774 return 0;
1775 }
1776
1777 #endif /* HAVE_POPEN */
1778
1779 /* Called once per program. */
1780
1781 static void
1782 __bb_exit_trace_func (void)
1783 {
1784 FILE *file = fopen ("bb.out", "a");
1785 struct bb_func *f;
1786 struct bb *b;
1787
1788 if (!file)
1789 perror ("bb.out");
1790
1791 if (bb_mode & 1)
1792 {
1793 if (!bb_tracefile)
1794 perror ("bbtrace");
1795 else
1796 #ifdef HAVE_POPEN
1797 gclose (bb_tracefile);
1798 #else
1799 fclose (bb_tracefile);
1800 #endif /* HAVE_POPEN */
1801 }
1802
1803 /* Check functions in `bb.in'. */
1804
1805 if (file)
1806 {
1807 long time_value;
1808 const struct bb_func *p;
1809 int printed_something = 0;
1810 struct bb *ptr;
1811 long blk;
1812
1813 /* This is somewhat type incorrect. */
1814 time ((void *) &time_value);
1815
1816 for (p = bb_func_head; p != (struct bb_func *) 0; p = p->next)
1817 {
1818 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1819 {
1820 if (!ptr->filename || (p->filename != (char *) 0 && strcmp (p->filename, ptr->filename)))
1821 continue;
1822 for (blk = 0; blk < ptr->ncounts; blk++)
1823 {
1824 if (!strcmp (p->funcname, ptr->functions[blk]))
1825 goto found;
1826 }
1827 }
1828
1829 if (!printed_something)
1830 {
1831 fprintf (file, "Functions in `bb.in' not executed during basic block profiling on %s\n", ctime ((void *) &time_value));
1832 printed_something = 1;
1833 }
1834
1835 fprintf (file, "\tFunction %s", p->funcname);
1836 if (p->filename)
1837 fprintf (file, " of file %s", p->filename);
1838 fprintf (file, "\n" );
1839
1840 found: ;
1841 }
1842
1843 if (printed_something)
1844 fprintf (file, "\n");
1845
1846 }
1847
1848 if (bb_mode & 2)
1849 {
1850 if (!bb_hashbuckets)
1851 {
1852 if (!reported)
1853 {
1854 fprintf (stderr, "Profiler: out of memory\n");
1855 reported = 1;
1856 }
1857 return;
1858 }
1859
1860 else if (file)
1861 {
1862 long time_value;
1863 int i;
1864 unsigned long addr_max = 0;
1865 unsigned long cnt_max = 0;
1866 int cnt_len;
1867 int addr_len;
1868
1869 /* This is somewhat type incorrect, but it avoids worrying about
1870 exactly where time.h is included from. It should be ok unless
1871 a void * differs from other pointer formats, or if sizeof (long)
1872 is < sizeof (time_t). It would be nice if we could assume the
1873 use of rationale standards here. */
1874
1875 time ((void *) &time_value);
1876 fprintf (file, "Basic block jump tracing");
1877
1878 switch (bb_mode & 12)
1879 {
1880 case 0:
1881 fprintf (file, " (with call)");
1882 break;
1883
1884 case 4:
1885 /* Print nothing. */
1886 break;
1887
1888 case 8:
1889 fprintf (file, " (with call & ret)");
1890 break;
1891
1892 case 12:
1893 fprintf (file, " (with ret)");
1894 break;
1895 }
1896
1897 fprintf (file, " finished on %s\n", ctime ((void *) &time_value));
1898
1899 for (i = 0; i < BB_BUCKETS; i++)
1900 {
1901 struct bb_edge *bucket = bb_hashbuckets[i];
1902 for ( ; bucket; bucket = bucket->next )
1903 {
1904 if (addr_max < bucket->src_addr)
1905 addr_max = bucket->src_addr;
1906 if (addr_max < bucket->dst_addr)
1907 addr_max = bucket->dst_addr;
1908 if (cnt_max < bucket->count)
1909 cnt_max = bucket->count;
1910 }
1911 }
1912 addr_len = num_digits (addr_max, 16);
1913 cnt_len = num_digits (cnt_max, 10);
1914
1915 for ( i = 0; i < BB_BUCKETS; i++)
1916 {
1917 struct bb_edge *bucket = bb_hashbuckets[i];
1918 for ( ; bucket; bucket = bucket->next )
1919 {
1920 fprintf (file,
1921 "Jump from block 0x%.*lx to block 0x%.*lx executed %*lu time(s)\n",
1922 addr_len, bucket->src_addr,
1923 addr_len, bucket->dst_addr,
1924 cnt_len, bucket->count);
1925 }
1926 }
1927
1928 fprintf (file, "\n");
1929
1930 }
1931 }
1932
1933 if (file)
1934 fclose (file);
1935
1936 /* Free allocated memory. */
1937
1938 f = bb_func_head;
1939 while (f)
1940 {
1941 struct bb_func *old = f;
1942
1943 f = f->next;
1944 if (old->funcname) free (old->funcname);
1945 if (old->filename) free (old->filename);
1946 free (old);
1947 }
1948
1949 if (bb_stack)
1950 free (bb_stack);
1951
1952 if (bb_hashbuckets)
1953 {
1954 int i;
1955
1956 for (i = 0; i < BB_BUCKETS; i++)
1957 {
1958 struct bb_edge *old, *bucket = bb_hashbuckets[i];
1959
1960 while (bucket)
1961 {
1962 old = bucket;
1963 bucket = bucket->next;
1964 free (old);
1965 }
1966 }
1967 free (bb_hashbuckets);
1968 }
1969
1970 for (b = bb_head; b; b = b->next)
1971 if (b->flags) free (b->flags);
1972 }
1973
1974 /* Called once per program. */
1975
1976 static void
1977 __bb_init_prg (void)
1978 {
1979 FILE *file;
1980 char buf[BBINBUFSIZE];
1981 const char *p;
1982 const char *pos;
1983 enum bb_func_mode m;
1984 int i;
1985
1986 /* Initialize destructor. */
1987 atexit (__bb_exit_func);
1988
1989 if (!(file = fopen ("bb.in", "r")))
1990 return;
1991
1992 while(fgets (buf, BBINBUFSIZE, file) != 0)
1993 {
1994 i = strlen (buf);
1995 if (buf[i] == '\n')
1996 buf[i--] = '\0';
1997
1998 p = buf;
1999 if (*p == '-')
2000 {
2001 m = TRACE_OFF;
2002 p++;
2003 }
2004 else
2005 {
2006 m = TRACE_ON;
2007 }
2008 if (!strcmp (p, "__bb_trace__"))
2009 bb_mode |= 1;
2010 else if (!strcmp (p, "__bb_jumps__"))
2011 bb_mode |= 2;
2012 else if (!strcmp (p, "__bb_hidecall__"))
2013 bb_mode |= 4;
2014 else if (!strcmp (p, "__bb_showret__"))
2015 bb_mode |= 8;
2016 else
2017 {
2018 struct bb_func *f = (struct bb_func *) malloc (sizeof (struct bb_func));
2019 if (f)
2020 {
2021 unsigned long l;
2022 f->next = bb_func_head;
2023 if ((pos = strchr (p, ':')))
2024 {
2025 if (!(f->funcname = (char *) malloc (strlen (pos+1)+1)))
2026 continue;
2027 strcpy (f->funcname, pos+1);
2028 l = pos-p;
2029 if ((f->filename = (char *) malloc (l+1)))
2030 {
2031 strncpy (f->filename, p, l);
2032 f->filename[l] = '\0';
2033 }
2034 else
2035 f->filename = (char *) 0;
2036 }
2037 else
2038 {
2039 if (!(f->funcname = (char *) malloc (strlen (p)+1)))
2040 continue;
2041 strcpy (f->funcname, p);
2042 f->filename = (char *) 0;
2043 }
2044 f->mode = m;
2045 bb_func_head = f;
2046 }
2047 }
2048 }
2049 fclose (file);
2050
2051 #ifdef HAVE_POPEN
2052
2053 if (bb_mode & 1)
2054 bb_tracefile = gopen ("bbtrace.gz", "w");
2055
2056 #else
2057
2058 if (bb_mode & 1)
2059 bb_tracefile = fopen ("bbtrace", "w");
2060
2061 #endif /* HAVE_POPEN */
2062
2063 if (bb_mode & 2)
2064 {
2065 bb_hashbuckets = (struct bb_edge **)
2066 malloc (BB_BUCKETS * sizeof (struct bb_edge *));
2067 if (bb_hashbuckets)
2068 /* Use a loop here rather than calling bzero to avoid having to
2069 conditionalize its existance. */
2070 for (i = 0; i < BB_BUCKETS; i++)
2071 bb_hashbuckets[i] = 0;
2072 }
2073
2074 if (bb_mode & 12)
2075 {
2076 bb_stacksize = 10;
2077 bb_stack = (unsigned long *) malloc (bb_stacksize * sizeof (*bb_stack));
2078 }
2079
2080 /* Initialize destructor. */
2081 atexit (__bb_exit_trace_func);
2082 }
2083
2084 /* Called upon entering a basic block. */
2085
2086 void
2087 __bb_trace_func (void)
2088 {
2089 struct bb_edge *bucket;
2090
2091 MACHINE_STATE_SAVE("1")
2092
2093 if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2094 goto skip;
2095
2096 bb_dst = __bb.blocks->addresses[__bb.blockno];
2097 __bb.blocks->counts[__bb.blockno]++;
2098
2099 if (bb_tracefile)
2100 {
2101 fwrite (&bb_dst, sizeof (unsigned long), 1, bb_tracefile);
2102 }
2103
2104 if (bb_hashbuckets)
2105 {
2106 struct bb_edge **startbucket, **oldnext;
2107
2108 oldnext = startbucket
2109 = & bb_hashbuckets[ (((int) bb_src*8) ^ (int) bb_dst) % BB_BUCKETS ];
2110 bucket = *startbucket;
2111
2112 for (bucket = *startbucket; bucket;
2113 oldnext = &(bucket->next), bucket = *oldnext)
2114 {
2115 if (bucket->src_addr == bb_src
2116 && bucket->dst_addr == bb_dst)
2117 {
2118 bucket->count++;
2119 *oldnext = bucket->next;
2120 bucket->next = *startbucket;
2121 *startbucket = bucket;
2122 goto ret;
2123 }
2124 }
2125
2126 bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2127
2128 if (!bucket)
2129 {
2130 if (!reported)
2131 {
2132 fprintf (stderr, "Profiler: out of memory\n");
2133 reported = 1;
2134 }
2135 }
2136
2137 else
2138 {
2139 bucket->src_addr = bb_src;
2140 bucket->dst_addr = bb_dst;
2141 bucket->next = *startbucket;
2142 *startbucket = bucket;
2143 bucket->count = 1;
2144 }
2145 }
2146
2147 ret:
2148 bb_src = bb_dst;
2149
2150 skip:
2151 ;
2152
2153 MACHINE_STATE_RESTORE("1")
2154
2155 }
2156
2157 /* Called when returning from a function and `__bb_showret__' is set. */
2158
2159 static void
2160 __bb_trace_func_ret (void)
2161 {
2162 struct bb_edge *bucket;
2163
2164 if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF)))
2165 goto skip;
2166
2167 if (bb_hashbuckets)
2168 {
2169 struct bb_edge **startbucket, **oldnext;
2170
2171 oldnext = startbucket
2172 = & bb_hashbuckets[ (((int) bb_dst * 8) ^ (int) bb_src) % BB_BUCKETS ];
2173 bucket = *startbucket;
2174
2175 for (bucket = *startbucket; bucket;
2176 oldnext = &(bucket->next), bucket = *oldnext)
2177 {
2178 if (bucket->src_addr == bb_dst
2179 && bucket->dst_addr == bb_src)
2180 {
2181 bucket->count++;
2182 *oldnext = bucket->next;
2183 bucket->next = *startbucket;
2184 *startbucket = bucket;
2185 goto ret;
2186 }
2187 }
2188
2189 bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge));
2190
2191 if (!bucket)
2192 {
2193 if (!reported)
2194 {
2195 fprintf (stderr, "Profiler: out of memory\n");
2196 reported = 1;
2197 }
2198 }
2199
2200 else
2201 {
2202 bucket->src_addr = bb_dst;
2203 bucket->dst_addr = bb_src;
2204 bucket->next = *startbucket;
2205 *startbucket = bucket;
2206 bucket->count = 1;
2207 }
2208 }
2209
2210 ret:
2211 bb_dst = bb_src;
2212
2213 skip:
2214 ;
2215
2216 }
2217
2218 /* Called upon entering the first function of a file. */
2219
2220 static void
2221 __bb_init_file (struct bb *blocks)
2222 {
2223
2224 const struct bb_func *p;
2225 long blk, ncounts = blocks->ncounts;
2226 const char **functions = blocks->functions;
2227
2228 /* Set up linked list. */
2229 blocks->zero_word = 1;
2230 blocks->next = bb_head;
2231 bb_head = blocks;
2232
2233 blocks->flags = 0;
2234 if (!bb_func_head
2235 || !(blocks->flags = (char *) malloc (sizeof (char) * blocks->ncounts)))
2236 return;
2237
2238 for (blk = 0; blk < ncounts; blk++)
2239 blocks->flags[blk] = 0;
2240
2241 for (blk = 0; blk < ncounts; blk++)
2242 {
2243 for (p = bb_func_head; p; p = p->next)
2244 {
2245 if (!strcmp (p->funcname, functions[blk])
2246 && (!p->filename || !strcmp (p->filename, blocks->filename)))
2247 {
2248 blocks->flags[blk] |= p->mode;
2249 }
2250 }
2251 }
2252
2253 }
2254
2255 /* Called when exiting from a function. */
2256
2257 void
2258 __bb_trace_ret (void)
2259 {
2260
2261 MACHINE_STATE_SAVE("2")
2262
2263 if (bb_callcount)
2264 {
2265 if ((bb_mode & 12) && bb_stacksize > bb_callcount)
2266 {
2267 bb_src = bb_stack[bb_callcount];
2268 if (bb_mode & 8)
2269 __bb_trace_func_ret ();
2270 }
2271
2272 bb_callcount -= 1;
2273 }
2274
2275 MACHINE_STATE_RESTORE("2")
2276
2277 }
2278
2279 /* Called when entering a function. */
2280
2281 void
2282 __bb_init_trace_func (struct bb *blocks, unsigned long blockno)
2283 {
2284 static int trace_init = 0;
2285
2286 MACHINE_STATE_SAVE("3")
2287
2288 if (!blocks->zero_word)
2289 {
2290 if (!trace_init)
2291 {
2292 trace_init = 1;
2293 __bb_init_prg ();
2294 }
2295 __bb_init_file (blocks);
2296 }
2297
2298 if (bb_callcount)
2299 {
2300
2301 bb_callcount += 1;
2302
2303 if (bb_mode & 12)
2304 {
2305 if (bb_callcount >= bb_stacksize)
2306 {
2307 size_t newsize = bb_callcount + 100;
2308
2309 bb_stack = (unsigned long *) realloc (bb_stack, newsize);
2310 if (! bb_stack)
2311 {
2312 if (!reported)
2313 {
2314 fprintf (stderr, "Profiler: out of memory\n");
2315 reported = 1;
2316 }
2317 bb_stacksize = 0;
2318 goto stack_overflow;
2319 }
2320 bb_stacksize = newsize;
2321 }
2322 bb_stack[bb_callcount] = bb_src;
2323
2324 if (bb_mode & 4)
2325 bb_src = 0;
2326
2327 }
2328
2329 stack_overflow:;
2330
2331 }
2332
2333 else if (blocks->flags && (blocks->flags[blockno] & TRACE_ON))
2334 {
2335 bb_callcount = 1;
2336 bb_src = 0;
2337
2338 if (bb_stack)
2339 bb_stack[bb_callcount] = bb_src;
2340 }
2341
2342 MACHINE_STATE_RESTORE("3")
2343 }
2344
2345 #endif /* not inhibit_libc */
2346 #endif /* not BLOCK_PROFILER_CODE */
2347 #endif /* L_bb */
2348 \f
2349 #ifdef L_clear_cache
2350 /* Clear part of an instruction cache. */
2351
2352 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
2353
2354 void
2355 __clear_cache (char *beg __attribute__((__unused__)),
2356 char *end __attribute__((__unused__)))
2357 {
2358 #ifdef CLEAR_INSN_CACHE
2359 CLEAR_INSN_CACHE (beg, end);
2360 #else
2361 #ifdef INSN_CACHE_SIZE
2362 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
2363 static int initialized;
2364 int offset;
2365 void *start_addr
2366 void *end_addr;
2367 typedef (*function_ptr) (void);
2368
2369 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
2370 /* It's cheaper to clear the whole cache.
2371 Put in a series of jump instructions so that calling the beginning
2372 of the cache will clear the whole thing. */
2373
2374 if (! initialized)
2375 {
2376 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2377 & -INSN_CACHE_LINE_WIDTH);
2378 int end_ptr = ptr + INSN_CACHE_SIZE;
2379
2380 while (ptr < end_ptr)
2381 {
2382 *(INSTRUCTION_TYPE *)ptr
2383 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
2384 ptr += INSN_CACHE_LINE_WIDTH;
2385 }
2386 *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
2387
2388 initialized = 1;
2389 }
2390
2391 /* Call the beginning of the sequence. */
2392 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2393 & -INSN_CACHE_LINE_WIDTH))
2394 ());
2395
2396 #else /* Cache is large. */
2397
2398 if (! initialized)
2399 {
2400 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
2401 & -INSN_CACHE_LINE_WIDTH);
2402
2403 while (ptr < (int) array + sizeof array)
2404 {
2405 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
2406 ptr += INSN_CACHE_LINE_WIDTH;
2407 }
2408
2409 initialized = 1;
2410 }
2411
2412 /* Find the location in array that occupies the same cache line as BEG. */
2413
2414 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
2415 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
2416 & -INSN_CACHE_PLANE_SIZE)
2417 + offset);
2418
2419 /* Compute the cache alignment of the place to stop clearing. */
2420 #if 0 /* This is not needed for gcc's purposes. */
2421 /* If the block to clear is bigger than a cache plane,
2422 we clear the entire cache, and OFFSET is already correct. */
2423 if (end < beg + INSN_CACHE_PLANE_SIZE)
2424 #endif
2425 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
2426 & -INSN_CACHE_LINE_WIDTH)
2427 & (INSN_CACHE_PLANE_SIZE - 1));
2428
2429 #if INSN_CACHE_DEPTH > 1
2430 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
2431 if (end_addr <= start_addr)
2432 end_addr += INSN_CACHE_PLANE_SIZE;
2433
2434 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
2435 {
2436 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
2437 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
2438
2439 while (addr != stop)
2440 {
2441 /* Call the return instruction at ADDR. */
2442 ((function_ptr) addr) ();
2443
2444 addr += INSN_CACHE_LINE_WIDTH;
2445 }
2446 }
2447 #else /* just one plane */
2448 do
2449 {
2450 /* Call the return instruction at START_ADDR. */
2451 ((function_ptr) start_addr) ();
2452
2453 start_addr += INSN_CACHE_LINE_WIDTH;
2454 }
2455 while ((start_addr % INSN_CACHE_SIZE) != offset);
2456 #endif /* just one plane */
2457 #endif /* Cache is large */
2458 #endif /* Cache exists */
2459 #endif /* CLEAR_INSN_CACHE */
2460 }
2461
2462 #endif /* L_clear_cache */
2463 \f
2464 #ifdef L_trampoline
2465
2466 /* Jump to a trampoline, loading the static chain address. */
2467
2468 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
2469
2470 long
2471 getpagesize (void)
2472 {
2473 #ifdef _ALPHA_
2474 return 8192;
2475 #else
2476 return 4096;
2477 #endif
2478 }
2479
2480 #ifdef __i386__
2481 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
2482 #endif
2483
2484 int
2485 mprotect (char *addr, int len, int prot)
2486 {
2487 int np, op;
2488
2489 if (prot == 7)
2490 np = 0x40;
2491 else if (prot == 5)
2492 np = 0x20;
2493 else if (prot == 4)
2494 np = 0x10;
2495 else if (prot == 3)
2496 np = 0x04;
2497 else if (prot == 1)
2498 np = 0x02;
2499 else if (prot == 0)
2500 np = 0x01;
2501
2502 if (VirtualProtect (addr, len, np, &op))
2503 return 0;
2504 else
2505 return -1;
2506 }
2507
2508 #endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
2509
2510 #ifdef TRANSFER_FROM_TRAMPOLINE
2511 TRANSFER_FROM_TRAMPOLINE
2512 #endif
2513
2514 #if defined (NeXT) && defined (__MACH__)
2515
2516 /* Make stack executable so we can call trampolines on stack.
2517 This is called from INITIALIZE_TRAMPOLINE in next.h. */
2518 #ifdef NeXTStep21
2519 #include <mach.h>
2520 #else
2521 #include <mach/mach.h>
2522 #endif
2523
2524 void
2525 __enable_execute_stack (char *addr)
2526 {
2527 kern_return_t r;
2528 char *eaddr = addr + TRAMPOLINE_SIZE;
2529 vm_address_t a = (vm_address_t) addr;
2530
2531 /* turn on execute access on stack */
2532 r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
2533 if (r != KERN_SUCCESS)
2534 {
2535 mach_error("vm_protect VM_PROT_ALL", r);
2536 exit(1);
2537 }
2538
2539 /* We inline the i-cache invalidation for speed */
2540
2541 #ifdef CLEAR_INSN_CACHE
2542 CLEAR_INSN_CACHE (addr, eaddr);
2543 #else
2544 __clear_cache ((int) addr, (int) eaddr);
2545 #endif
2546 }
2547
2548 #endif /* defined (NeXT) && defined (__MACH__) */
2549
2550 #ifdef __convex__
2551
2552 /* Make stack executable so we can call trampolines on stack.
2553 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
2554
2555 #include <sys/mman.h>
2556 #include <sys/vmparam.h>
2557 #include <machine/machparam.h>
2558
2559 void
2560 __enable_execute_stack (void)
2561 {
2562 int fp;
2563 static unsigned lowest = USRSTACK;
2564 unsigned current = (unsigned) &fp & -NBPG;
2565
2566 if (lowest > current)
2567 {
2568 unsigned len = lowest - current;
2569 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
2570 lowest = current;
2571 }
2572
2573 /* Clear instruction cache in case an old trampoline is in it. */
2574 asm ("pich");
2575 }
2576 #endif /* __convex__ */
2577
2578 #ifdef __sysV88__
2579
2580 /* Modified from the convex -code above. */
2581
2582 #include <sys/param.h>
2583 #include <errno.h>
2584 #include <sys/m88kbcs.h>
2585
2586 void
2587 __enable_execute_stack (void)
2588 {
2589 int save_errno;
2590 static unsigned long lowest = USRSTACK;
2591 unsigned long current = (unsigned long) &save_errno & -NBPC;
2592
2593 /* Ignore errno being set. memctl sets errno to EINVAL whenever the
2594 address is seen as 'negative'. That is the case with the stack. */
2595
2596 save_errno=errno;
2597 if (lowest > current)
2598 {
2599 unsigned len=lowest-current;
2600 memctl(current,len,MCT_TEXT);
2601 lowest = current;
2602 }
2603 else
2604 memctl(current,NBPC,MCT_TEXT);
2605 errno=save_errno;
2606 }
2607
2608 #endif /* __sysV88__ */
2609
2610 #ifdef __sysV68__
2611
2612 #include <sys/signal.h>
2613 #include <errno.h>
2614
2615 /* Motorola forgot to put memctl.o in the libp version of libc881.a,
2616 so define it here, because we need it in __clear_insn_cache below */
2617 /* On older versions of this OS, no memctl or MCT_TEXT are defined;
2618 hence we enable this stuff only if MCT_TEXT is #define'd. */
2619
2620 #ifdef MCT_TEXT
2621 asm("\n\
2622 global memctl\n\
2623 memctl:\n\
2624 movq &75,%d0\n\
2625 trap &0\n\
2626 bcc.b noerror\n\
2627 jmp cerror%\n\
2628 noerror:\n\
2629 movq &0,%d0\n\
2630 rts");
2631 #endif
2632
2633 /* Clear instruction cache so we can call trampolines on stack.
2634 This is called from FINALIZE_TRAMPOLINE in mot3300.h. */
2635
2636 void
2637 __clear_insn_cache (void)
2638 {
2639 #ifdef MCT_TEXT
2640 int save_errno;
2641
2642 /* Preserve errno, because users would be surprised to have
2643 errno changing without explicitly calling any system-call. */
2644 save_errno = errno;
2645
2646 /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache.
2647 No need to use an address derived from _start or %sp, as 0 works also. */
2648 memctl(0, 4096, MCT_TEXT);
2649 errno = save_errno;
2650 #endif
2651 }
2652
2653 #endif /* __sysV68__ */
2654
2655 #ifdef __pyr__
2656
2657 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2658 #include <stdio.h>
2659 #include <sys/mman.h>
2660 #include <sys/types.h>
2661 #include <sys/param.h>
2662 #include <sys/vmmac.h>
2663
2664 /* Modified from the convex -code above.
2665 mremap promises to clear the i-cache. */
2666
2667 void
2668 __enable_execute_stack (void)
2669 {
2670 int fp;
2671 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
2672 PROT_READ|PROT_WRITE|PROT_EXEC))
2673 {
2674 perror ("mprotect in __enable_execute_stack");
2675 fflush (stderr);
2676 abort ();
2677 }
2678 }
2679 #endif /* __pyr__ */
2680
2681 #if defined (sony_news) && defined (SYSTYPE_BSD)
2682
2683 #include <stdio.h>
2684 #include <sys/types.h>
2685 #include <sys/param.h>
2686 #include <syscall.h>
2687 #include <machine/sysnews.h>
2688
2689 /* cacheflush function for NEWS-OS 4.2.
2690 This function is called from trampoline-initialize code
2691 defined in config/mips/mips.h. */
2692
2693 void
2694 cacheflush (char *beg, int size, int flag)
2695 {
2696 if (syscall (SYS_sysnews, NEWS_CACHEFLUSH, beg, size, FLUSH_BCACHE))
2697 {
2698 perror ("cache_flush");
2699 fflush (stderr);
2700 abort ();
2701 }
2702 }
2703
2704 #endif /* sony_news */
2705 #endif /* L_trampoline */
2706 \f
2707 #ifndef __CYGWIN__
2708 #ifdef L__main
2709
2710 #include "gbl-ctors.h"
2711 /* Some systems use __main in a way incompatible with its use in gcc, in these
2712 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2713 give the same symbol without quotes for an alternative entry point. You
2714 must define both, or neither. */
2715 #ifndef NAME__MAIN
2716 #define NAME__MAIN "__main"
2717 #define SYMBOL__MAIN __main
2718 #endif
2719
2720 #ifdef INIT_SECTION_ASM_OP
2721 #undef HAS_INIT_SECTION
2722 #define HAS_INIT_SECTION
2723 #endif
2724
2725 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
2726
2727 /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
2728 code to run constructors. In that case, we need to handle EH here, too. */
2729
2730 #ifdef EH_FRAME_SECTION
2731 #include "unwind-dw2-fde.h"
2732 extern unsigned char __EH_FRAME_BEGIN__[];
2733 #endif
2734
2735 /* Run all the global destructors on exit from the program. */
2736
2737 void
2738 __do_global_dtors (void)
2739 {
2740 #ifdef DO_GLOBAL_DTORS_BODY
2741 DO_GLOBAL_DTORS_BODY;
2742 #else
2743 static func_ptr *p = __DTOR_LIST__ + 1;
2744 while (*p)
2745 {
2746 p++;
2747 (*(p-1)) ();
2748 }
2749 #endif
2750 #if defined (EH_FRAME_SECTION) && !defined (HAS_INIT_SECTION)
2751 {
2752 static int completed = 0;
2753 if (! completed)
2754 {
2755 completed = 1;
2756 __deregister_frame_info (__EH_FRAME_BEGIN__);
2757 }
2758 }
2759 #endif
2760 }
2761 #endif
2762
2763 #ifndef HAS_INIT_SECTION
2764 /* Run all the global constructors on entry to the program. */
2765
2766 void
2767 __do_global_ctors (void)
2768 {
2769 #ifdef EH_FRAME_SECTION
2770 {
2771 static struct object object;
2772 __register_frame_info (__EH_FRAME_BEGIN__, &object);
2773 }
2774 #endif
2775 DO_GLOBAL_CTORS_BODY;
2776 atexit (__do_global_dtors);
2777 }
2778 #endif /* no HAS_INIT_SECTION */
2779
2780 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
2781 /* Subroutine called automatically by `main'.
2782 Compiling a global function named `main'
2783 produces an automatic call to this function at the beginning.
2784
2785 For many systems, this routine calls __do_global_ctors.
2786 For systems which support a .init section we use the .init section
2787 to run __do_global_ctors, so we need not do anything here. */
2788
2789 void
2790 SYMBOL__MAIN ()
2791 {
2792 /* Support recursive calls to `main': run initializers just once. */
2793 static int initialized;
2794 if (! initialized)
2795 {
2796 initialized = 1;
2797 __do_global_ctors ();
2798 }
2799 }
2800 #endif /* no HAS_INIT_SECTION or INVOKE__main */
2801
2802 #endif /* L__main */
2803 #endif /* __CYGWIN__ */
2804 \f
2805 #ifdef L_ctors
2806
2807 #include "gbl-ctors.h"
2808
2809 /* Provide default definitions for the lists of constructors and
2810 destructors, so that we don't get linker errors. These symbols are
2811 intentionally bss symbols, so that gld and/or collect will provide
2812 the right values. */
2813
2814 /* We declare the lists here with two elements each,
2815 so that they are valid empty lists if no other definition is loaded.
2816
2817 If we are using the old "set" extensions to have the gnu linker
2818 collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
2819 must be in the bss/common section.
2820
2821 Long term no port should use those extensions. But many still do. */
2822 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
2823 #if defined (ASM_OUTPUT_CONSTRUCTOR) || defined (USE_COLLECT2)
2824 func_ptr __CTOR_LIST__[2] = {0, 0};
2825 func_ptr __DTOR_LIST__[2] = {0, 0};
2826 #else
2827 func_ptr __CTOR_LIST__[2];
2828 func_ptr __DTOR_LIST__[2];
2829 #endif
2830 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
2831 #endif /* L_ctors */
2832 \f
2833 #ifdef L_exit
2834
2835 #include "gbl-ctors.h"
2836
2837 #ifdef NEED_ATEXIT
2838
2839 #ifndef ON_EXIT
2840
2841 # include <errno.h>
2842
2843 static func_ptr *atexit_chain = 0;
2844 static long atexit_chain_length = 0;
2845 static volatile long last_atexit_chain_slot = -1;
2846
2847 int
2848 atexit (func_ptr func)
2849 {
2850 if (++last_atexit_chain_slot == atexit_chain_length)
2851 {
2852 atexit_chain_length += 32;
2853 if (atexit_chain)
2854 atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
2855 * sizeof (func_ptr));
2856 else
2857 atexit_chain = (func_ptr *) malloc (atexit_chain_length
2858 * sizeof (func_ptr));
2859 if (! atexit_chain)
2860 {
2861 atexit_chain_length = 0;
2862 last_atexit_chain_slot = -1;
2863 errno = ENOMEM;
2864 return (-1);
2865 }
2866 }
2867 atexit_chain[last_atexit_chain_slot] = func;
2868 return (0);
2869 }
2870
2871 extern void _cleanup (void);
2872 extern void _exit (int) __attribute__ ((__noreturn__));
2873
2874 void
2875 exit (int status)
2876 {
2877 if (atexit_chain)
2878 {
2879 for ( ; last_atexit_chain_slot-- >= 0; )
2880 {
2881 (*atexit_chain[last_atexit_chain_slot + 1]) ();
2882 atexit_chain[last_atexit_chain_slot + 1] = 0;
2883 }
2884 free (atexit_chain);
2885 atexit_chain = 0;
2886 }
2887 #ifdef EXIT_BODY
2888 EXIT_BODY;
2889 #else
2890 _cleanup ();
2891 #endif
2892 _exit (status);
2893 }
2894
2895 #else /* ON_EXIT */
2896
2897 /* Simple; we just need a wrapper for ON_EXIT. */
2898 int
2899 atexit (func_ptr func)
2900 {
2901 return ON_EXIT (func);
2902 }
2903
2904 #endif /* ON_EXIT */
2905 #endif /* NEED_ATEXIT */
2906
2907 #endif /* L_exit */