* libgcc2.c (__bb_exit_func): Revert 03-31 change.
[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 GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 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 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
23 WARRANTY; without even the implied warranty of MERCHANTABILITY or
24 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25 for more details.
26
27 You should have received a copy of the GNU General Public License
28 along with GCC; see the file COPYING. If not, write to the Free
29 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
30 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
1069 #define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT)
1070 #define DF_SIZE DBL_MANT_DIG
1071 #define SF_SIZE FLT_MANT_DIG
1072
1073 SFtype
1074 __floatdisf (DWtype u)
1075 {
1076 /* Do the calculation in DFmode
1077 so that we don't lose any of the precision of the high word
1078 while multiplying it. */
1079 DFtype f;
1080
1081 /* Protect against double-rounding error.
1082 Represent any low-order bits, that might be truncated in DFmode,
1083 by a bit that won't be lost. The bit can go in anywhere below the
1084 rounding position of the SFmode. A fixed mask and bit position
1085 handles all usual configurations. It doesn't handle the case
1086 of 128-bit DImode, however. */
1087 if (DF_SIZE < DI_SIZE
1088 && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1089 {
1090 #define REP_BIT ((UDWtype) 1 << (DI_SIZE - DF_SIZE))
1091 if (! (- ((DWtype) 1 << DF_SIZE) < u
1092 && u < ((DWtype) 1 << DF_SIZE)))
1093 {
1094 if ((UDWtype) u & (REP_BIT - 1))
1095 u |= REP_BIT;
1096 }
1097 }
1098 f = (Wtype) (u >> WORD_SIZE);
1099 f *= HIGH_HALFWORD_COEFF;
1100 f *= HIGH_HALFWORD_COEFF;
1101 f += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1102
1103 return (SFtype) f;
1104 }
1105 #endif
1106
1107 #if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
1108 /* Reenable the normal types, in case limits.h needs them. */
1109 #undef char
1110 #undef short
1111 #undef int
1112 #undef long
1113 #undef unsigned
1114 #undef float
1115 #undef double
1116 #undef MIN
1117 #undef MAX
1118 #include <limits.h>
1119
1120 UWtype
1121 __fixunsxfSI (XFtype a)
1122 {
1123 if (a >= - (DFtype) Wtype_MIN)
1124 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1125 return (Wtype) a;
1126 }
1127 #endif
1128
1129 #ifdef L_fixunsdfsi
1130 /* Reenable the normal types, in case limits.h needs them. */
1131 #undef char
1132 #undef short
1133 #undef int
1134 #undef long
1135 #undef unsigned
1136 #undef float
1137 #undef double
1138 #undef MIN
1139 #undef MAX
1140 #include <limits.h>
1141
1142 UWtype
1143 __fixunsdfSI (DFtype a)
1144 {
1145 if (a >= - (DFtype) Wtype_MIN)
1146 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1147 return (Wtype) a;
1148 }
1149 #endif
1150
1151 #ifdef L_fixunssfsi
1152 /* Reenable the normal types, in case limits.h needs them. */
1153 #undef char
1154 #undef short
1155 #undef int
1156 #undef long
1157 #undef unsigned
1158 #undef float
1159 #undef double
1160 #undef MIN
1161 #undef MAX
1162 #include <limits.h>
1163
1164 UWtype
1165 __fixunssfSI (SFtype a)
1166 {
1167 if (a >= - (SFtype) Wtype_MIN)
1168 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1169 return (Wtype) a;
1170 }
1171 #endif
1172 \f
1173 /* From here on down, the routines use normal data types. */
1174
1175 #define SItype bogus_type
1176 #define USItype bogus_type
1177 #define DItype bogus_type
1178 #define UDItype bogus_type
1179 #define SFtype bogus_type
1180 #define DFtype bogus_type
1181 #undef Wtype
1182 #undef UWtype
1183 #undef HWtype
1184 #undef UHWtype
1185 #undef DWtype
1186 #undef UDWtype
1187
1188 #undef char
1189 #undef short
1190 #undef int
1191 #undef long
1192 #undef unsigned
1193 #undef float
1194 #undef double
1195 \f
1196 #ifdef L__gcc_bcmp
1197
1198 /* Like bcmp except the sign is meaningful.
1199 Result is negative if S1 is less than S2,
1200 positive if S1 is greater, 0 if S1 and S2 are equal. */
1201
1202 int
1203 __gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
1204 {
1205 while (size > 0)
1206 {
1207 unsigned char c1 = *s1++, c2 = *s2++;
1208 if (c1 != c2)
1209 return c1 - c2;
1210 size--;
1211 }
1212 return 0;
1213 }
1214
1215 #endif
1216 \f
1217 /* __eprintf used to be used by GCC's private version of <assert.h>.
1218 We no longer provide that header, but this routine remains in libgcc.a
1219 for binary backward compatibility. Note that it is not included in
1220 the shared version of libgcc. */
1221 #ifdef L_eprintf
1222 #ifndef inhibit_libc
1223
1224 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1225 #include <stdio.h>
1226
1227 void
1228 __eprintf (const char *string, const char *expression,
1229 unsigned int line, const char *filename)
1230 {
1231 fprintf (stderr, string, expression, line, filename);
1232 fflush (stderr);
1233 abort ();
1234 }
1235
1236 #endif
1237 #endif
1238
1239 #ifdef L_bb
1240
1241 #if LONG_TYPE_SIZE == GCOV_TYPE_SIZE
1242 typedef long gcov_type;
1243 #else
1244 typedef long long gcov_type;
1245 #endif
1246
1247
1248 /* Structure emitted by -a */
1249 struct bb
1250 {
1251 long zero_word;
1252 const char *filename;
1253 gcov_type *counts;
1254 long ncounts;
1255 struct bb *next;
1256 const unsigned long *addresses;
1257
1258 /* Older GCC's did not emit these fields. */
1259 long nwords;
1260 const char **functions;
1261 const long *line_nums;
1262 const char **filenames;
1263 char *flags;
1264 };
1265
1266 #ifdef BLOCK_PROFILER_CODE
1267 BLOCK_PROFILER_CODE
1268 #else
1269 #ifndef inhibit_libc
1270
1271 /* Simple minded basic block profiling output dumper for
1272 systems that don't provide tcov support. At present,
1273 it requires atexit and stdio. */
1274
1275 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1276 #include <stdio.h>
1277
1278 #include "gbl-ctors.h"
1279 #include "gcov-io.h"
1280 #include <string.h>
1281 #ifdef TARGET_HAS_F_SETLKW
1282 #include <fcntl.h>
1283 #include <errno.h>
1284 #endif
1285
1286 static struct bb *bb_head;
1287
1288 void
1289 __bb_exit_func (void)
1290 {
1291 FILE *da_file;
1292 int i;
1293 struct bb *ptr;
1294
1295 if (bb_head == 0)
1296 return;
1297
1298 i = strlen (bb_head->filename) - 3;
1299
1300
1301 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1302 {
1303 int firstchar;
1304
1305 /* Make sure the output file exists -
1306 but don't clobber exiting data. */
1307 if ((da_file = fopen (ptr->filename, "a")) != 0)
1308 fclose (da_file);
1309
1310 /* Need to re-open in order to be able to write from the start. */
1311 da_file = fopen (ptr->filename, "r+b");
1312 /* Some old systems might not allow the 'b' mode modifier.
1313 Therefore, try to open without it. This can lead to a race
1314 condition so that when you delete and re-create the file, the
1315 file might be opened in text mode, but then, you shouldn't
1316 delete the file in the first place. */
1317 if (da_file == 0)
1318 da_file = fopen (ptr->filename, "r+");
1319 if (da_file == 0)
1320 {
1321 fprintf (stderr, "arc profiling: Can't open output file %s.\n",
1322 ptr->filename);
1323 continue;
1324 }
1325
1326 /* After a fork, another process might try to read and/or write
1327 the same file simultanously. So if we can, lock the file to
1328 avoid race conditions. */
1329 #if defined (TARGET_HAS_F_SETLKW)
1330 {
1331 struct flock s_flock;
1332
1333 s_flock.l_type = F_WRLCK;
1334 s_flock.l_whence = SEEK_SET;
1335 s_flock.l_start = 0;
1336 s_flock.l_len = 1;
1337 s_flock.l_pid = getpid ();
1338
1339 while (fcntl (fileno (da_file), F_SETLKW, &s_flock)
1340 && errno == EINTR);
1341 }
1342 #endif
1343
1344 /* If the file is not empty, and the number of counts in it is the
1345 same, then merge them in. */
1346 firstchar = fgetc (da_file);
1347 if (firstchar == EOF)
1348 {
1349 if (ferror (da_file))
1350 {
1351 fprintf (stderr, "arc profiling: Can't read output file ");
1352 perror (ptr->filename);
1353 }
1354 }
1355 else
1356 {
1357 long n_counts = 0;
1358
1359 if (ungetc (firstchar, da_file) == EOF)
1360 rewind (da_file);
1361 if (__read_long (&n_counts, da_file, 8) != 0)
1362 {
1363 fprintf (stderr, "arc profiling: Can't read output file %s.\n",
1364 ptr->filename);
1365 continue;
1366 }
1367
1368 if (n_counts == ptr->ncounts)
1369 {
1370 int i;
1371
1372 for (i = 0; i < n_counts; i++)
1373 {
1374 gcov_type v = 0;
1375
1376 if (__read_gcov_type (&v, da_file, 8) != 0)
1377 {
1378 fprintf (stderr,
1379 "arc profiling: Can't read output file %s.\n",
1380 ptr->filename);
1381 break;
1382 }
1383 ptr->counts[i] += v;
1384 }
1385 }
1386
1387 }
1388
1389 rewind (da_file);
1390
1391 /* ??? Should first write a header to the file. Preferably, a 4 byte
1392 magic number, 4 bytes containing the time the program was
1393 compiled, 4 bytes containing the last modification time of the
1394 source file, and 4 bytes indicating the compiler options used.
1395
1396 That way we can easily verify that the proper source/executable/
1397 data file combination is being used from gcov. */
1398
1399 if (__write_gcov_type (ptr->ncounts, da_file, 8) != 0)
1400 {
1401
1402 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1403 ptr->filename);
1404 }
1405 else
1406 {
1407 int j;
1408 gcov_type *count_ptr = ptr->counts;
1409 int ret = 0;
1410 for (j = ptr->ncounts; j > 0; j--)
1411 {
1412 if (__write_gcov_type (*count_ptr, da_file, 8) != 0)
1413 {
1414 ret = 1;
1415 break;
1416 }
1417 count_ptr++;
1418 }
1419 if (ret)
1420 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1421 ptr->filename);
1422 }
1423
1424 if (fclose (da_file) == EOF)
1425 fprintf (stderr, "arc profiling: Error closing output file %s.\n",
1426 ptr->filename);
1427 }
1428
1429 return;
1430 }
1431
1432 void
1433 __bb_init_func (struct bb *blocks)
1434 {
1435 /* User is supposed to check whether the first word is non-0,
1436 but just in case.... */
1437
1438 if (blocks->zero_word)
1439 return;
1440
1441 /* Initialize destructor. */
1442 if (!bb_head)
1443 atexit (__bb_exit_func);
1444
1445 /* Set up linked list. */
1446 blocks->zero_word = 1;
1447 blocks->next = bb_head;
1448 bb_head = blocks;
1449 }
1450
1451 /* Called before fork or exec - write out profile information gathered so
1452 far and reset it to zero. This avoids duplication or loss of the
1453 profile information gathered so far. */
1454 void
1455 __bb_fork_func (void)
1456 {
1457 struct bb *ptr;
1458
1459 __bb_exit_func ();
1460 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1461 {
1462 long i;
1463 for (i = ptr->ncounts - 1; i >= 0; i--)
1464 ptr->counts[i] = 0;
1465 }
1466 }
1467
1468 #endif /* not inhibit_libc */
1469 #endif /* not BLOCK_PROFILER_CODE */
1470 #endif /* L_bb */
1471 \f
1472 #ifdef L_clear_cache
1473 /* Clear part of an instruction cache. */
1474
1475 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1476
1477 void
1478 __clear_cache (char *beg __attribute__((__unused__)),
1479 char *end __attribute__((__unused__)))
1480 {
1481 #ifdef CLEAR_INSN_CACHE
1482 CLEAR_INSN_CACHE (beg, end);
1483 #else
1484 #ifdef INSN_CACHE_SIZE
1485 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1486 static int initialized;
1487 int offset;
1488 void *start_addr
1489 void *end_addr;
1490 typedef (*function_ptr) (void);
1491
1492 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1493 /* It's cheaper to clear the whole cache.
1494 Put in a series of jump instructions so that calling the beginning
1495 of the cache will clear the whole thing. */
1496
1497 if (! initialized)
1498 {
1499 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1500 & -INSN_CACHE_LINE_WIDTH);
1501 int end_ptr = ptr + INSN_CACHE_SIZE;
1502
1503 while (ptr < end_ptr)
1504 {
1505 *(INSTRUCTION_TYPE *)ptr
1506 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1507 ptr += INSN_CACHE_LINE_WIDTH;
1508 }
1509 *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1510
1511 initialized = 1;
1512 }
1513
1514 /* Call the beginning of the sequence. */
1515 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1516 & -INSN_CACHE_LINE_WIDTH))
1517 ());
1518
1519 #else /* Cache is large. */
1520
1521 if (! initialized)
1522 {
1523 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1524 & -INSN_CACHE_LINE_WIDTH);
1525
1526 while (ptr < (int) array + sizeof array)
1527 {
1528 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1529 ptr += INSN_CACHE_LINE_WIDTH;
1530 }
1531
1532 initialized = 1;
1533 }
1534
1535 /* Find the location in array that occupies the same cache line as BEG. */
1536
1537 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1538 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1539 & -INSN_CACHE_PLANE_SIZE)
1540 + offset);
1541
1542 /* Compute the cache alignment of the place to stop clearing. */
1543 #if 0 /* This is not needed for gcc's purposes. */
1544 /* If the block to clear is bigger than a cache plane,
1545 we clear the entire cache, and OFFSET is already correct. */
1546 if (end < beg + INSN_CACHE_PLANE_SIZE)
1547 #endif
1548 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1549 & -INSN_CACHE_LINE_WIDTH)
1550 & (INSN_CACHE_PLANE_SIZE - 1));
1551
1552 #if INSN_CACHE_DEPTH > 1
1553 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1554 if (end_addr <= start_addr)
1555 end_addr += INSN_CACHE_PLANE_SIZE;
1556
1557 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1558 {
1559 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1560 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1561
1562 while (addr != stop)
1563 {
1564 /* Call the return instruction at ADDR. */
1565 ((function_ptr) addr) ();
1566
1567 addr += INSN_CACHE_LINE_WIDTH;
1568 }
1569 }
1570 #else /* just one plane */
1571 do
1572 {
1573 /* Call the return instruction at START_ADDR. */
1574 ((function_ptr) start_addr) ();
1575
1576 start_addr += INSN_CACHE_LINE_WIDTH;
1577 }
1578 while ((start_addr % INSN_CACHE_SIZE) != offset);
1579 #endif /* just one plane */
1580 #endif /* Cache is large */
1581 #endif /* Cache exists */
1582 #endif /* CLEAR_INSN_CACHE */
1583 }
1584
1585 #endif /* L_clear_cache */
1586 \f
1587 #ifdef L_trampoline
1588
1589 /* Jump to a trampoline, loading the static chain address. */
1590
1591 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
1592
1593 long
1594 getpagesize (void)
1595 {
1596 #ifdef _ALPHA_
1597 return 8192;
1598 #else
1599 return 4096;
1600 #endif
1601 }
1602
1603 #ifdef __i386__
1604 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
1605 #endif
1606
1607 int
1608 mprotect (char *addr, int len, int prot)
1609 {
1610 int np, op;
1611
1612 if (prot == 7)
1613 np = 0x40;
1614 else if (prot == 5)
1615 np = 0x20;
1616 else if (prot == 4)
1617 np = 0x10;
1618 else if (prot == 3)
1619 np = 0x04;
1620 else if (prot == 1)
1621 np = 0x02;
1622 else if (prot == 0)
1623 np = 0x01;
1624
1625 if (VirtualProtect (addr, len, np, &op))
1626 return 0;
1627 else
1628 return -1;
1629 }
1630
1631 #endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
1632
1633 #ifdef TRANSFER_FROM_TRAMPOLINE
1634 TRANSFER_FROM_TRAMPOLINE
1635 #endif
1636
1637 #if defined (NeXT) && defined (__MACH__)
1638
1639 /* Make stack executable so we can call trampolines on stack.
1640 This is called from INITIALIZE_TRAMPOLINE in next.h. */
1641 #ifdef NeXTStep21
1642 #include <mach.h>
1643 #else
1644 #include <mach/mach.h>
1645 #endif
1646
1647 void
1648 __enable_execute_stack (char *addr)
1649 {
1650 kern_return_t r;
1651 char *eaddr = addr + TRAMPOLINE_SIZE;
1652 vm_address_t a = (vm_address_t) addr;
1653
1654 /* turn on execute access on stack */
1655 r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
1656 if (r != KERN_SUCCESS)
1657 {
1658 mach_error("vm_protect VM_PROT_ALL", r);
1659 exit(1);
1660 }
1661
1662 /* We inline the i-cache invalidation for speed */
1663
1664 #ifdef CLEAR_INSN_CACHE
1665 CLEAR_INSN_CACHE (addr, eaddr);
1666 #else
1667 __clear_cache ((int) addr, (int) eaddr);
1668 #endif
1669 }
1670
1671 #endif /* defined (NeXT) && defined (__MACH__) */
1672
1673 #ifdef __convex__
1674
1675 /* Make stack executable so we can call trampolines on stack.
1676 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
1677
1678 #include <sys/mman.h>
1679 #include <sys/vmparam.h>
1680 #include <machine/machparam.h>
1681
1682 void
1683 __enable_execute_stack (void)
1684 {
1685 int fp;
1686 static unsigned lowest = USRSTACK;
1687 unsigned current = (unsigned) &fp & -NBPG;
1688
1689 if (lowest > current)
1690 {
1691 unsigned len = lowest - current;
1692 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
1693 lowest = current;
1694 }
1695
1696 /* Clear instruction cache in case an old trampoline is in it. */
1697 asm ("pich");
1698 }
1699 #endif /* __convex__ */
1700
1701 #ifdef __sysV88__
1702
1703 /* Modified from the convex -code above. */
1704
1705 #include <sys/param.h>
1706 #include <errno.h>
1707 #include <sys/m88kbcs.h>
1708
1709 void
1710 __enable_execute_stack (void)
1711 {
1712 int save_errno;
1713 static unsigned long lowest = USRSTACK;
1714 unsigned long current = (unsigned long) &save_errno & -NBPC;
1715
1716 /* Ignore errno being set. memctl sets errno to EINVAL whenever the
1717 address is seen as 'negative'. That is the case with the stack. */
1718
1719 save_errno=errno;
1720 if (lowest > current)
1721 {
1722 unsigned len=lowest-current;
1723 memctl(current,len,MCT_TEXT);
1724 lowest = current;
1725 }
1726 else
1727 memctl(current,NBPC,MCT_TEXT);
1728 errno=save_errno;
1729 }
1730
1731 #endif /* __sysV88__ */
1732
1733 #ifdef __sysV68__
1734
1735 #include <sys/signal.h>
1736 #include <errno.h>
1737
1738 /* Motorola forgot to put memctl.o in the libp version of libc881.a,
1739 so define it here, because we need it in __clear_insn_cache below */
1740 /* On older versions of this OS, no memctl or MCT_TEXT are defined;
1741 hence we enable this stuff only if MCT_TEXT is #define'd. */
1742
1743 #ifdef MCT_TEXT
1744 asm("\n\
1745 global memctl\n\
1746 memctl:\n\
1747 movq &75,%d0\n\
1748 trap &0\n\
1749 bcc.b noerror\n\
1750 jmp cerror%\n\
1751 noerror:\n\
1752 movq &0,%d0\n\
1753 rts");
1754 #endif
1755
1756 /* Clear instruction cache so we can call trampolines on stack.
1757 This is called from FINALIZE_TRAMPOLINE in mot3300.h. */
1758
1759 void
1760 __clear_insn_cache (void)
1761 {
1762 #ifdef MCT_TEXT
1763 int save_errno;
1764
1765 /* Preserve errno, because users would be surprised to have
1766 errno changing without explicitly calling any system-call. */
1767 save_errno = errno;
1768
1769 /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache.
1770 No need to use an address derived from _start or %sp, as 0 works also. */
1771 memctl(0, 4096, MCT_TEXT);
1772 errno = save_errno;
1773 #endif
1774 }
1775
1776 #endif /* __sysV68__ */
1777
1778 #ifdef __pyr__
1779
1780 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1781 #include <stdio.h>
1782 #include <sys/mman.h>
1783 #include <sys/types.h>
1784 #include <sys/param.h>
1785 #include <sys/vmmac.h>
1786
1787 /* Modified from the convex -code above.
1788 mremap promises to clear the i-cache. */
1789
1790 void
1791 __enable_execute_stack (void)
1792 {
1793 int fp;
1794 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
1795 PROT_READ|PROT_WRITE|PROT_EXEC))
1796 {
1797 perror ("mprotect in __enable_execute_stack");
1798 fflush (stderr);
1799 abort ();
1800 }
1801 }
1802 #endif /* __pyr__ */
1803
1804 #if defined (sony_news) && defined (SYSTYPE_BSD)
1805
1806 #include <stdio.h>
1807 #include <sys/types.h>
1808 #include <sys/param.h>
1809 #include <syscall.h>
1810 #include <machine/sysnews.h>
1811
1812 /* cacheflush function for NEWS-OS 4.2.
1813 This function is called from trampoline-initialize code
1814 defined in config/mips/mips.h. */
1815
1816 void
1817 cacheflush (char *beg, int size, int flag)
1818 {
1819 if (syscall (SYS_sysnews, NEWS_CACHEFLUSH, beg, size, FLUSH_BCACHE))
1820 {
1821 perror ("cache_flush");
1822 fflush (stderr);
1823 abort ();
1824 }
1825 }
1826
1827 #endif /* sony_news */
1828 #endif /* L_trampoline */
1829 \f
1830 #ifndef __CYGWIN__
1831 #ifdef L__main
1832
1833 #include "gbl-ctors.h"
1834 /* Some systems use __main in a way incompatible with its use in gcc, in these
1835 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
1836 give the same symbol without quotes for an alternative entry point. You
1837 must define both, or neither. */
1838 #ifndef NAME__MAIN
1839 #define NAME__MAIN "__main"
1840 #define SYMBOL__MAIN __main
1841 #endif
1842
1843 #ifdef INIT_SECTION_ASM_OP
1844 #undef HAS_INIT_SECTION
1845 #define HAS_INIT_SECTION
1846 #endif
1847
1848 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
1849
1850 /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
1851 code to run constructors. In that case, we need to handle EH here, too. */
1852
1853 #ifdef EH_FRAME_SECTION_NAME
1854 #include "unwind-dw2-fde.h"
1855 extern unsigned char __EH_FRAME_BEGIN__[];
1856 #endif
1857
1858 /* Run all the global destructors on exit from the program. */
1859
1860 void
1861 __do_global_dtors (void)
1862 {
1863 #ifdef DO_GLOBAL_DTORS_BODY
1864 DO_GLOBAL_DTORS_BODY;
1865 #else
1866 static func_ptr *p = __DTOR_LIST__ + 1;
1867 while (*p)
1868 {
1869 p++;
1870 (*(p-1)) ();
1871 }
1872 #endif
1873 #if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION)
1874 {
1875 static int completed = 0;
1876 if (! completed)
1877 {
1878 completed = 1;
1879 __deregister_frame_info (__EH_FRAME_BEGIN__);
1880 }
1881 }
1882 #endif
1883 }
1884 #endif
1885
1886 #ifndef HAS_INIT_SECTION
1887 /* Run all the global constructors on entry to the program. */
1888
1889 void
1890 __do_global_ctors (void)
1891 {
1892 #ifdef EH_FRAME_SECTION_NAME
1893 {
1894 static struct object object;
1895 __register_frame_info (__EH_FRAME_BEGIN__, &object);
1896 }
1897 #endif
1898 DO_GLOBAL_CTORS_BODY;
1899 atexit (__do_global_dtors);
1900 }
1901 #endif /* no HAS_INIT_SECTION */
1902
1903 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
1904 /* Subroutine called automatically by `main'.
1905 Compiling a global function named `main'
1906 produces an automatic call to this function at the beginning.
1907
1908 For many systems, this routine calls __do_global_ctors.
1909 For systems which support a .init section we use the .init section
1910 to run __do_global_ctors, so we need not do anything here. */
1911
1912 void
1913 SYMBOL__MAIN ()
1914 {
1915 /* Support recursive calls to `main': run initializers just once. */
1916 static int initialized;
1917 if (! initialized)
1918 {
1919 initialized = 1;
1920 __do_global_ctors ();
1921 }
1922 }
1923 #endif /* no HAS_INIT_SECTION or INVOKE__main */
1924
1925 #endif /* L__main */
1926 #endif /* __CYGWIN__ */
1927 \f
1928 #ifdef L_ctors
1929
1930 #include "gbl-ctors.h"
1931
1932 /* Provide default definitions for the lists of constructors and
1933 destructors, so that we don't get linker errors. These symbols are
1934 intentionally bss symbols, so that gld and/or collect will provide
1935 the right values. */
1936
1937 /* We declare the lists here with two elements each,
1938 so that they are valid empty lists if no other definition is loaded.
1939
1940 If we are using the old "set" extensions to have the gnu linker
1941 collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
1942 must be in the bss/common section.
1943
1944 Long term no port should use those extensions. But many still do. */
1945 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
1946 #if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2)
1947 func_ptr __CTOR_LIST__[2] = {0, 0};
1948 func_ptr __DTOR_LIST__[2] = {0, 0};
1949 #else
1950 func_ptr __CTOR_LIST__[2];
1951 func_ptr __DTOR_LIST__[2];
1952 #endif
1953 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1954 #endif /* L_ctors */
1955 \f
1956 #ifdef L_exit
1957
1958 #include "gbl-ctors.h"
1959
1960 #ifdef NEED_ATEXIT
1961
1962 #ifndef ON_EXIT
1963
1964 # include <errno.h>
1965
1966 static func_ptr *atexit_chain = 0;
1967 static long atexit_chain_length = 0;
1968 static volatile long last_atexit_chain_slot = -1;
1969
1970 int
1971 atexit (func_ptr func)
1972 {
1973 if (++last_atexit_chain_slot == atexit_chain_length)
1974 {
1975 atexit_chain_length += 32;
1976 if (atexit_chain)
1977 atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
1978 * sizeof (func_ptr));
1979 else
1980 atexit_chain = (func_ptr *) malloc (atexit_chain_length
1981 * sizeof (func_ptr));
1982 if (! atexit_chain)
1983 {
1984 atexit_chain_length = 0;
1985 last_atexit_chain_slot = -1;
1986 errno = ENOMEM;
1987 return (-1);
1988 }
1989 }
1990 atexit_chain[last_atexit_chain_slot] = func;
1991 return (0);
1992 }
1993
1994 extern void _cleanup (void);
1995 extern void _exit (int) __attribute__ ((__noreturn__));
1996
1997 void
1998 exit (int status)
1999 {
2000 if (atexit_chain)
2001 {
2002 for ( ; last_atexit_chain_slot-- >= 0; )
2003 {
2004 (*atexit_chain[last_atexit_chain_slot + 1]) ();
2005 atexit_chain[last_atexit_chain_slot + 1] = 0;
2006 }
2007 free (atexit_chain);
2008 atexit_chain = 0;
2009 }
2010 #ifdef EXIT_BODY
2011 EXIT_BODY;
2012 #else
2013 _cleanup ();
2014 #endif
2015 _exit (status);
2016 }
2017
2018 #else /* ON_EXIT */
2019
2020 /* Simple; we just need a wrapper for ON_EXIT. */
2021 int
2022 atexit (func_ptr func)
2023 {
2024 return ON_EXIT (func);
2025 }
2026
2027 #endif /* ON_EXIT */
2028 #endif /* NEED_ATEXIT */
2029
2030 #endif /* L_exit */