Fix some Rtl Prototype inconsistencies, more are in ntifs/winddk but i have fixed...
[reactos.git] / freeldr / freeldr / math / 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 /*
37 * This file was taken from the GCC v3.1 source - Brian
38 */
39 #ifdef __i386__
40 #include "i386.h"
41 #endif
42 #define L_clz
43 #define L_udivdi3
44 #define L_umoddi3
45 #include <freeldr.h>
46
47 //#include "tconfig.h"
48 //#include "tsystem.h"
49
50 //#include "machmode.h"
51
52 /* Don't use `fancy_abort' here even if config.h says to use it. */
53 #ifdef abort
54 #undef abort
55 #endif
56
57 #include "libgcc2.h"
58 \f
59 #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
60 #if defined (L_divdi3) || defined (L_moddi3)
61 static inline
62 #endif
63 DWtype
64 __negdi2 (DWtype u)
65 {
66 DWunion w;
67 DWunion uu;
68
69 uu.ll = u;
70
71 w.s.low = -uu.s.low;
72 w.s.high = -uu.s.high - ((UWtype) w.s.low > 0);
73
74 return w.ll;
75 }
76 #endif
77
78 #ifdef L_addvsi3
79 Wtype
80 __addvsi3 (Wtype a, Wtype b)
81 {
82 Wtype w;
83
84 w = a + b;
85
86 if (b >= 0 ? w < a : w > a)
87 abort ();
88
89 return w;
90 }
91 #endif
92 \f
93 #ifdef L_addvdi3
94 DWtype
95 __addvdi3 (DWtype a, DWtype b)
96 {
97 DWtype w;
98
99 w = a + b;
100
101 if (b >= 0 ? w < a : w > a)
102 abort ();
103
104 return w;
105 }
106 #endif
107 \f
108 #ifdef L_subvsi3
109 Wtype
110 __subvsi3 (Wtype a, Wtype b)
111 {
112 #ifdef L_addvsi3
113 return __addvsi3 (a, (-b));
114 #else
115 DWtype w;
116
117 w = a - b;
118
119 if (b >= 0 ? w > a : w < a)
120 abort ();
121
122 return w;
123 #endif
124 }
125 #endif
126 \f
127 #ifdef L_subvdi3
128 DWtype
129 __subvdi3 (DWtype a, DWtype b)
130 {
131 #ifdef L_addvdi3
132 return (a, (-b));
133 #else
134 DWtype w;
135
136 w = a - b;
137
138 if (b >= 0 ? w > a : w < a)
139 abort ();
140
141 return w;
142 #endif
143 }
144 #endif
145 \f
146 #ifdef L_mulvsi3
147 Wtype
148 __mulvsi3 (Wtype a, Wtype b)
149 {
150 DWtype w;
151
152 w = a * b;
153
154 if (((a >= 0) == (b >= 0)) ? w < 0 : w > 0)
155 abort ();
156
157 return w;
158 }
159 #endif
160 \f
161 #ifdef L_negvsi2
162 Wtype
163 __negvsi2 (Wtype a)
164 {
165 Wtype w;
166
167 w = -a;
168
169 if (a >= 0 ? w > 0 : w < 0)
170 abort ();
171
172 return w;
173 }
174 #endif
175 \f
176 #ifdef L_negvdi2
177 DWtype
178 __negvdi2 (DWtype a)
179 {
180 DWtype w;
181
182 w = -a;
183
184 if (a >= 0 ? w > 0 : w < 0)
185 abort ();
186
187 return w;
188 }
189 #endif
190 \f
191 #ifdef L_absvsi2
192 Wtype
193 __absvsi2 (Wtype a)
194 {
195 Wtype w = a;
196
197 if (a < 0)
198 #ifdef L_negvsi2
199 w = __negvsi2 (a);
200 #else
201 w = -a;
202
203 if (w < 0)
204 abort ();
205 #endif
206
207 return w;
208 }
209 #endif
210 \f
211 #ifdef L_absvdi2
212 DWtype
213 __absvdi2 (DWtype a)
214 {
215 DWtype w = a;
216
217 if (a < 0)
218 #ifdef L_negvsi2
219 w = __negvsi2 (a);
220 #else
221 w = -a;
222
223 if (w < 0)
224 abort ();
225 #endif
226
227 return w;
228 }
229 #endif
230 \f
231 #ifdef L_mulvdi3
232 DWtype
233 __mulvdi3 (DWtype u, DWtype v)
234 {
235 DWtype w;
236
237 w = u * v;
238
239 if (((u >= 0) == (v >= 0)) ? w < 0 : w > 0)
240 abort ();
241
242 return w;
243 }
244 #endif
245 \f
246
247 /* Unless shift functions are defined whith full ANSI prototypes,
248 parameter b will be promoted to int if word_type is smaller than an int. */
249 #ifdef L_lshrdi3
250 DWtype
251 __lshrdi3 (DWtype u, word_type b)
252 {
253 DWunion w;
254 word_type bm;
255 DWunion uu;
256
257 if (b == 0)
258 return u;
259
260 uu.ll = u;
261
262 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
263 if (bm <= 0)
264 {
265 w.s.high = 0;
266 w.s.low = (UWtype) uu.s.high >> -bm;
267 }
268 else
269 {
270 UWtype carries = (UWtype) uu.s.high << bm;
271
272 w.s.high = (UWtype) uu.s.high >> b;
273 w.s.low = ((UWtype) uu.s.low >> b) | carries;
274 }
275
276 return w.ll;
277 }
278 #endif
279
280 #ifdef L_ashldi3
281 DWtype
282 __ashldi3 (DWtype u, word_type b)
283 {
284 DWunion w;
285 word_type bm;
286 DWunion uu;
287
288 if (b == 0)
289 return u;
290
291 uu.ll = u;
292
293 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
294 if (bm <= 0)
295 {
296 w.s.low = 0;
297 w.s.high = (UWtype) uu.s.low << -bm;
298 }
299 else
300 {
301 UWtype carries = (UWtype) uu.s.low >> bm;
302
303 w.s.low = (UWtype) uu.s.low << b;
304 w.s.high = ((UWtype) uu.s.high << b) | carries;
305 }
306
307 return w.ll;
308 }
309 #endif
310
311 #ifdef L_ashrdi3
312 DWtype
313 __ashrdi3 (DWtype u, word_type b)
314 {
315 DWunion w;
316 word_type bm;
317 DWunion uu;
318
319 if (b == 0)
320 return u;
321
322 uu.ll = u;
323
324 bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
325 if (bm <= 0)
326 {
327 /* w.s.high = 1..1 or 0..0 */
328 w.s.high = uu.s.high >> (sizeof (Wtype) * BITS_PER_UNIT - 1);
329 w.s.low = uu.s.high >> -bm;
330 }
331 else
332 {
333 UWtype carries = (UWtype) uu.s.high << bm;
334
335 w.s.high = uu.s.high >> b;
336 w.s.low = ((UWtype) uu.s.low >> b) | carries;
337 }
338
339 return w.ll;
340 }
341 #endif
342 \f
343 #ifdef L_ffsdi2
344 DWtype
345 __ffsdi2 (DWtype u)
346 {
347 DWunion uu;
348 UWtype word, count, add;
349
350 uu.ll = u;
351 if (uu.s.low != 0)
352 word = uu.s.low, add = 0;
353 else if (uu.s.high != 0)
354 word = uu.s.high, add = BITS_PER_UNIT * sizeof (Wtype);
355 else
356 return 0;
357
358 count_trailing_zeros (count, word);
359 return count + add + 1;
360 }
361 #endif
362 \f
363 #ifdef L_muldi3
364 DWtype
365 __muldi3 (DWtype u, DWtype v)
366 {
367 DWunion w;
368 DWunion uu, vv;
369
370 uu.ll = u,
371 vv.ll = v;
372
373 w.ll = __umulsidi3 (uu.s.low, vv.s.low);
374 w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
375 + (UWtype) uu.s.high * (UWtype) vv.s.low);
376
377 return w.ll;
378 }
379 #endif
380 \f
381 #ifdef L_udiv_w_sdiv
382 #if defined (sdiv_qrnnd)
383 UWtype
384 __udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d)
385 {
386 UWtype q, r;
387 UWtype c0, c1, b1;
388
389 if ((Wtype) d >= 0)
390 {
391 if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1)))
392 {
393 /* dividend, divisor, and quotient are nonnegative */
394 sdiv_qrnnd (q, r, a1, a0, d);
395 }
396 else
397 {
398 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
399 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1));
400 /* Divide (c1*2^32 + c0) by d */
401 sdiv_qrnnd (q, r, c1, c0, d);
402 /* Add 2^31 to quotient */
403 q += (UWtype) 1 << (W_TYPE_SIZE - 1);
404 }
405 }
406 else
407 {
408 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
409 c1 = a1 >> 1; /* A/2 */
410 c0 = (a1 << (W_TYPE_SIZE - 1)) + (a0 >> 1);
411
412 if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
413 {
414 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
415
416 r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
417 if ((d & 1) != 0)
418 {
419 if (r >= q)
420 r = r - q;
421 else if (q - r <= d)
422 {
423 r = r - q + d;
424 q--;
425 }
426 else
427 {
428 r = r - q + 2*d;
429 q -= 2;
430 }
431 }
432 }
433 else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
434 {
435 c1 = (b1 - 1) - c1;
436 c0 = ~c0; /* logical NOT */
437
438 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
439
440 q = ~q; /* (A/2)/b1 */
441 r = (b1 - 1) - r;
442
443 r = 2*r + (a0 & 1); /* A/(2*b1) */
444
445 if ((d & 1) != 0)
446 {
447 if (r >= q)
448 r = r - q;
449 else if (q - r <= d)
450 {
451 r = r - q + d;
452 q--;
453 }
454 else
455 {
456 r = r - q + 2*d;
457 q -= 2;
458 }
459 }
460 }
461 else /* Implies c1 = b1 */
462 { /* Hence a1 = d - 1 = 2*b1 - 1 */
463 if (a0 >= -d)
464 {
465 q = -1;
466 r = a0 + d;
467 }
468 else
469 {
470 q = -2;
471 r = a0 + 2*d;
472 }
473 }
474 }
475
476 *rp = r;
477 return q;
478 }
479 #else
480 /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */
481 UWtype
482 __udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)),
483 UWtype a1 __attribute__ ((__unused__)),
484 UWtype a0 __attribute__ ((__unused__)),
485 UWtype d __attribute__ ((__unused__)))
486 {
487 return 0;
488 }
489 #endif
490 #endif
491 \f
492 #if (defined (L_udivdi3) || defined (L_divdi3) || \
493 defined (L_umoddi3) || defined (L_moddi3))
494 #define L_udivmoddi4
495 #endif
496
497 #ifdef L_clz
498 const UQItype __clz_tab[] =
499 {
500 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,
501 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,
502 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,
503 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,
504 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
505 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
506 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,
507 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
508 };
509 #endif
510
511 #ifdef L_udivmoddi4
512
513 #if (defined (L_udivdi3) || defined (L_divdi3) || \
514 defined (L_umoddi3) || defined (L_moddi3))
515 static inline
516 #endif
517 UDWtype
518 __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
519 {
520 DWunion ww;
521 DWunion nn, dd;
522 DWunion rr;
523 UWtype d0, d1, n0, n1, n2;
524 UWtype q0, q1;
525 UWtype b, bm;
526
527 nn.ll = n;
528 dd.ll = d;
529
530 d0 = dd.s.low;
531 d1 = dd.s.high;
532 n0 = nn.s.low;
533 n1 = nn.s.high;
534
535 #if !UDIV_NEEDS_NORMALIZATION
536 if (d1 == 0)
537 {
538 if (d0 > n1)
539 {
540 /* 0q = nn / 0D */
541
542 udiv_qrnnd (q0, n0, n1, n0, d0);
543 q1 = 0;
544
545 /* Remainder in n0. */
546 }
547 else
548 {
549 /* qq = NN / 0d */
550
551 if (d0 == 0)
552 d0 = 1 / d0; /* Divide intentionally by zero. */
553
554 udiv_qrnnd (q1, n1, 0, n1, d0);
555 udiv_qrnnd (q0, n0, n1, n0, d0);
556
557 /* Remainder in n0. */
558 }
559
560 if (rp != 0)
561 {
562 rr.s.low = n0;
563 rr.s.high = 0;
564 *rp = rr.ll;
565 }
566 }
567
568 #else /* UDIV_NEEDS_NORMALIZATION */
569
570 if (d1 == 0)
571 {
572 if (d0 > n1)
573 {
574 /* 0q = nn / 0D */
575
576 count_leading_zeros (bm, d0);
577
578 if (bm != 0)
579 {
580 /* Normalize, i.e. make the most significant bit of the
581 denominator set. */
582
583 d0 = d0 << bm;
584 n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
585 n0 = n0 << bm;
586 }
587
588 udiv_qrnnd (q0, n0, n1, n0, d0);
589 q1 = 0;
590
591 /* Remainder in n0 >> bm. */
592 }
593 else
594 {
595 /* qq = NN / 0d */
596
597 if (d0 == 0)
598 d0 = 1 / d0; /* Divide intentionally by zero. */
599
600 count_leading_zeros (bm, d0);
601
602 if (bm == 0)
603 {
604 /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
605 conclude (the most significant bit of n1 is set) /\ (the
606 leading quotient digit q1 = 1).
607
608 This special case is necessary, not an optimization.
609 (Shifts counts of W_TYPE_SIZE are undefined.) */
610
611 n1 -= d0;
612 q1 = 1;
613 }
614 else
615 {
616 /* Normalize. */
617
618 b = W_TYPE_SIZE - bm;
619
620 d0 = d0 << bm;
621 n2 = n1 >> b;
622 n1 = (n1 << bm) | (n0 >> b);
623 n0 = n0 << bm;
624
625 udiv_qrnnd (q1, n1, n2, n1, d0);
626 }
627
628 /* n1 != d0... */
629
630 udiv_qrnnd (q0, n0, n1, n0, d0);
631
632 /* Remainder in n0 >> bm. */
633 }
634
635 if (rp != 0)
636 {
637 rr.s.low = n0 >> bm;
638 rr.s.high = 0;
639 *rp = rr.ll;
640 }
641 }
642 #endif /* UDIV_NEEDS_NORMALIZATION */
643
644 else
645 {
646 if (d1 > n1)
647 {
648 /* 00 = nn / DD */
649
650 q0 = 0;
651 q1 = 0;
652
653 /* Remainder in n1n0. */
654 if (rp != 0)
655 {
656 rr.s.low = n0;
657 rr.s.high = n1;
658 *rp = rr.ll;
659 }
660 }
661 else
662 {
663 /* 0q = NN / dd */
664
665 count_leading_zeros (bm, d1);
666 if (bm == 0)
667 {
668 /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
669 conclude (the most significant bit of n1 is set) /\ (the
670 quotient digit q0 = 0 or 1).
671
672 This special case is necessary, not an optimization. */
673
674 /* The condition on the next line takes advantage of that
675 n1 >= d1 (true due to program flow). */
676 if (n1 > d1 || n0 >= d0)
677 {
678 q0 = 1;
679 sub_ddmmss (n1, n0, n1, n0, d1, d0);
680 }
681 else
682 q0 = 0;
683
684 q1 = 0;
685
686 if (rp != 0)
687 {
688 rr.s.low = n0;
689 rr.s.high = n1;
690 *rp = rr.ll;
691 }
692 }
693 else
694 {
695 UWtype m1, m0;
696 /* Normalize. */
697
698 b = W_TYPE_SIZE - bm;
699
700 d1 = (d1 << bm) | (d0 >> b);
701 d0 = d0 << bm;
702 n2 = n1 >> b;
703 n1 = (n1 << bm) | (n0 >> b);
704 n0 = n0 << bm;
705
706 udiv_qrnnd (q0, n1, n2, n1, d1);
707 umul_ppmm (m1, m0, q0, d0);
708
709 if (m1 > n1 || (m1 == n1 && m0 > n0))
710 {
711 q0--;
712 sub_ddmmss (m1, m0, m1, m0, d1, d0);
713 }
714
715 q1 = 0;
716
717 /* Remainder in (n1n0 - m1m0) >> bm. */
718 if (rp != 0)
719 {
720 sub_ddmmss (n1, n0, n1, n0, m1, m0);
721 rr.s.low = (n1 << b) | (n0 >> bm);
722 rr.s.high = n1 >> bm;
723 *rp = rr.ll;
724 }
725 }
726 }
727 }
728
729 ww.s.low = q0;
730 ww.s.high = q1;
731 return ww.ll;
732 }
733 #endif
734
735 #ifdef L_divdi3
736 DWtype
737 __divdi3 (DWtype u, DWtype v)
738 {
739 word_type c = 0;
740 DWunion uu, vv;
741 DWtype w;
742
743 uu.ll = u;
744 vv.ll = v;
745
746 if (uu.s.high < 0)
747 c = ~c,
748 uu.ll = __negdi2 (uu.ll);
749 if (vv.s.high < 0)
750 c = ~c,
751 vv.ll = __negdi2 (vv.ll);
752
753 w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
754 if (c)
755 w = __negdi2 (w);
756
757 return w;
758 }
759 #endif
760
761 #ifdef L_moddi3
762 DWtype
763 __moddi3 (DWtype u, DWtype v)
764 {
765 word_type c = 0;
766 DWunion uu, vv;
767 DWtype w;
768
769 uu.ll = u;
770 vv.ll = v;
771
772 if (uu.s.high < 0)
773 c = ~c,
774 uu.ll = __negdi2 (uu.ll);
775 if (vv.s.high < 0)
776 vv.ll = __negdi2 (vv.ll);
777
778 (void) __udivmoddi4 (uu.ll, vv.ll, &w);
779 if (c)
780 w = __negdi2 (w);
781
782 return w;
783 }
784 #endif
785
786 #ifdef L_umoddi3
787 UDWtype
788 __umoddi3 (UDWtype u, UDWtype v)
789 {
790 UDWtype w;
791
792 (void) __udivmoddi4 (u, v, &w);
793
794 return w;
795 }
796 #endif
797
798 #ifdef L_udivdi3
799 UDWtype
800 __udivdi3 (UDWtype n, UDWtype d)
801 {
802 return __udivmoddi4 (n, d, (UDWtype *) 0);
803 }
804 #endif
805 \f
806 #ifdef L_cmpdi2
807 word_type
808 __cmpdi2 (DWtype a, DWtype b)
809 {
810 DWunion au, bu;
811
812 au.ll = a, bu.ll = b;
813
814 if (au.s.high < bu.s.high)
815 return 0;
816 else if (au.s.high > bu.s.high)
817 return 2;
818 if ((UWtype) au.s.low < (UWtype) bu.s.low)
819 return 0;
820 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
821 return 2;
822 return 1;
823 }
824 #endif
825
826 #ifdef L_ucmpdi2
827 word_type
828 __ucmpdi2 (DWtype a, DWtype b)
829 {
830 DWunion au, bu;
831
832 au.ll = a, bu.ll = b;
833
834 if ((UWtype) au.s.high < (UWtype) bu.s.high)
835 return 0;
836 else if ((UWtype) au.s.high > (UWtype) bu.s.high)
837 return 2;
838 if ((UWtype) au.s.low < (UWtype) bu.s.low)
839 return 0;
840 else if ((UWtype) au.s.low > (UWtype) bu.s.low)
841 return 2;
842 return 1;
843 }
844 #endif
845 \f
846 #if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
847 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
848 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
849
850 DWtype
851 __fixunstfDI (TFtype a)
852 {
853 TFtype b;
854 UDWtype v;
855
856 if (a < 0)
857 return 0;
858
859 /* Compute high word of result, as a flonum. */
860 b = (a / HIGH_WORD_COEFF);
861 /* Convert that to fixed (but not to DWtype!),
862 and shift it into the high word. */
863 v = (UWtype) b;
864 v <<= WORD_SIZE;
865 /* Remove high part from the TFtype, leaving the low part as flonum. */
866 a -= (TFtype)v;
867 /* Convert that to fixed (but not to DWtype!) and add it in.
868 Sometimes A comes out negative. This is significant, since
869 A has more bits than a long int does. */
870 if (a < 0)
871 v -= (UWtype) (- a);
872 else
873 v += (UWtype) a;
874 return v;
875 }
876 #endif
877
878 #if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
879 DWtype
880 __fixtfdi (TFtype a)
881 {
882 if (a < 0)
883 return - __fixunstfDI (-a);
884 return __fixunstfDI (a);
885 }
886 #endif
887
888 #if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
889 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
890 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
891
892 DWtype
893 __fixunsxfDI (XFtype a)
894 {
895 XFtype b;
896 UDWtype v;
897
898 if (a < 0)
899 return 0;
900
901 /* Compute high word of result, as a flonum. */
902 b = (a / HIGH_WORD_COEFF);
903 /* Convert that to fixed (but not to DWtype!),
904 and shift it into the high word. */
905 v = (UWtype) b;
906 v <<= WORD_SIZE;
907 /* Remove high part from the XFtype, leaving the low part as flonum. */
908 a -= (XFtype)v;
909 /* Convert that to fixed (but not to DWtype!) and add it in.
910 Sometimes A comes out negative. This is significant, since
911 A has more bits than a long int does. */
912 if (a < 0)
913 v -= (UWtype) (- a);
914 else
915 v += (UWtype) a;
916 return v;
917 }
918 #endif
919
920 #if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
921 DWtype
922 __fixxfdi (XFtype a)
923 {
924 if (a < 0)
925 return - __fixunsxfDI (-a);
926 return __fixunsxfDI (a);
927 }
928 #endif
929
930 #ifdef L_fixunsdfdi
931 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
932 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
933
934 DWtype
935 __fixunsdfDI (DFtype a)
936 {
937 DFtype b;
938 UDWtype v;
939
940 if (a < 0)
941 return 0;
942
943 /* Compute high word of result, as a flonum. */
944 b = (a / HIGH_WORD_COEFF);
945 /* Convert that to fixed (but not to DWtype!),
946 and shift it into the high word. */
947 v = (UWtype) b;
948 v <<= WORD_SIZE;
949 /* Remove high part from the DFtype, leaving the low part as flonum. */
950 a -= (DFtype)v;
951 /* Convert that to fixed (but not to DWtype!) and add it in.
952 Sometimes A comes out negative. This is significant, since
953 A has more bits than a long int does. */
954 if (a < 0)
955 v -= (UWtype) (- a);
956 else
957 v += (UWtype) a;
958 return v;
959 }
960 #endif
961
962 #ifdef L_fixdfdi
963 DWtype
964 __fixdfdi (DFtype a)
965 {
966 if (a < 0)
967 return - __fixunsdfDI (-a);
968 return __fixunsdfDI (a);
969 }
970 #endif
971
972 #ifdef L_fixunssfdi
973 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
974 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
975
976 DWtype
977 __fixunssfDI (SFtype original_a)
978 {
979 /* Convert the SFtype to a DFtype, because that is surely not going
980 to lose any bits. Some day someone else can write a faster version
981 that avoids converting to DFtype, and verify it really works right. */
982 DFtype a = original_a;
983 DFtype b;
984 UDWtype v;
985
986 if (a < 0)
987 return 0;
988
989 /* Compute high word of result, as a flonum. */
990 b = (a / HIGH_WORD_COEFF);
991 /* Convert that to fixed (but not to DWtype!),
992 and shift it into the high word. */
993 v = (UWtype) b;
994 v <<= WORD_SIZE;
995 /* Remove high part from the DFtype, leaving the low part as flonum. */
996 a -= (DFtype) v;
997 /* Convert that to fixed (but not to DWtype!) and add it in.
998 Sometimes A comes out negative. This is significant, since
999 A has more bits than a long int does. */
1000 if (a < 0)
1001 v -= (UWtype) (- a);
1002 else
1003 v += (UWtype) a;
1004 return v;
1005 }
1006 #endif
1007
1008 #ifdef L_fixsfdi
1009 DWtype
1010 __fixsfdi (SFtype a)
1011 {
1012 if (a < 0)
1013 return - __fixunssfDI (-a);
1014 return __fixunssfDI (a);
1015 }
1016 #endif
1017
1018 #if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
1019 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1020 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1021 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1022
1023 XFtype
1024 __floatdixf (DWtype u)
1025 {
1026 XFtype d;
1027
1028 d = (Wtype) (u >> WORD_SIZE);
1029 d *= HIGH_HALFWORD_COEFF;
1030 d *= HIGH_HALFWORD_COEFF;
1031 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1032
1033 return d;
1034 }
1035 #endif
1036
1037 #if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
1038 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1039 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1040 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1041
1042 TFtype
1043 __floatditf (DWtype u)
1044 {
1045 TFtype d;
1046
1047 d = (Wtype) (u >> WORD_SIZE);
1048 d *= HIGH_HALFWORD_COEFF;
1049 d *= HIGH_HALFWORD_COEFF;
1050 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1051
1052 return d;
1053 }
1054 #endif
1055
1056 #ifdef L_floatdidf
1057 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1058 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1059 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1060
1061 DFtype
1062 __floatdidf (DWtype u)
1063 {
1064 DFtype d;
1065
1066 d = (Wtype) (u >> WORD_SIZE);
1067 d *= HIGH_HALFWORD_COEFF;
1068 d *= HIGH_HALFWORD_COEFF;
1069 d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1070
1071 return d;
1072 }
1073 #endif
1074
1075 #ifdef L_floatdisf
1076 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1077 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1078 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1079 #define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT)
1080
1081 /* Define codes for all the float formats that we know of. Note
1082 that this is copied from real.h. */
1083
1084 #define UNKNOWN_FLOAT_FORMAT 0
1085 #define IEEE_FLOAT_FORMAT 1
1086 #define VAX_FLOAT_FORMAT 2
1087 #define IBM_FLOAT_FORMAT 3
1088
1089 /* Default to IEEE float if not specified. Nearly all machines use it. */
1090 #ifndef HOST_FLOAT_FORMAT
1091 #define HOST_FLOAT_FORMAT IEEE_FLOAT_FORMAT
1092 #endif
1093
1094 #if HOST_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1095 #define DF_SIZE 53
1096 #define SF_SIZE 24
1097 #endif
1098
1099 #if HOST_FLOAT_FORMAT == IBM_FLOAT_FORMAT
1100 #define DF_SIZE 56
1101 #define SF_SIZE 24
1102 #endif
1103
1104 #if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
1105 #define DF_SIZE 56
1106 #define SF_SIZE 24
1107 #endif
1108
1109 SFtype
1110 __floatdisf (DWtype u)
1111 {
1112 /* Do the calculation in DFmode
1113 so that we don't lose any of the precision of the high word
1114 while multiplying it. */
1115 DFtype f;
1116
1117 /* Protect against double-rounding error.
1118 Represent any low-order bits, that might be truncated in DFmode,
1119 by a bit that won't be lost. The bit can go in anywhere below the
1120 rounding position of the SFmode. A fixed mask and bit position
1121 handles all usual configurations. It doesn't handle the case
1122 of 128-bit DImode, however. */
1123 if (DF_SIZE < DI_SIZE
1124 && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1125 {
1126 #define REP_BIT ((UDWtype) 1 << (DI_SIZE - DF_SIZE))
1127 if (! (- ((DWtype) 1 << DF_SIZE) < u
1128 && u < ((DWtype) 1 << DF_SIZE)))
1129 {
1130 if ((UDWtype) u & (REP_BIT - 1))
1131 u |= REP_BIT;
1132 }
1133 }
1134 f = (Wtype) (u >> WORD_SIZE);
1135 f *= HIGH_HALFWORD_COEFF;
1136 f *= HIGH_HALFWORD_COEFF;
1137 f += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1138
1139 return (SFtype) f;
1140 }
1141 #endif
1142
1143 #if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
1144 /* Reenable the normal types, in case limits.h needs them. */
1145 #undef char
1146 #undef short
1147 #undef int
1148 #undef long
1149 #undef unsigned
1150 #undef float
1151 #undef double
1152 #undef MIN
1153 #undef MAX
1154 #include <limits.h>
1155
1156 UWtype
1157 __fixunsxfSI (XFtype a)
1158 {
1159 if (a >= - (DFtype) Wtype_MIN)
1160 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1161 return (Wtype) a;
1162 }
1163 #endif
1164
1165 #ifdef L_fixunsdfsi
1166 /* Reenable the normal types, in case limits.h needs them. */
1167 #undef char
1168 #undef short
1169 #undef int
1170 #undef long
1171 #undef unsigned
1172 #undef float
1173 #undef double
1174 #undef MIN
1175 #undef MAX
1176 #include <limits.h>
1177
1178 UWtype
1179 __fixunsdfSI (DFtype a)
1180 {
1181 if (a >= - (DFtype) Wtype_MIN)
1182 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1183 return (Wtype) a;
1184 }
1185 #endif
1186
1187 #ifdef L_fixunssfsi
1188 /* Reenable the normal types, in case limits.h needs them. */
1189 #undef char
1190 #undef short
1191 #undef int
1192 #undef long
1193 #undef unsigned
1194 #undef float
1195 #undef double
1196 #undef MIN
1197 #undef MAX
1198 #include <limits.h>
1199
1200 UWtype
1201 __fixunssfSI (SFtype a)
1202 {
1203 if (a >= - (SFtype) Wtype_MIN)
1204 return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1205 return (Wtype) a;
1206 }
1207 #endif
1208 \f
1209 /* From here on down, the routines use normal data types. */
1210
1211 #define SItype bogus_type
1212 #define USItype bogus_type
1213 #define DItype bogus_type
1214 #define UDItype bogus_type
1215 #define SFtype bogus_type
1216 #define DFtype bogus_type
1217 #undef Wtype
1218 #undef UWtype
1219 #undef HWtype
1220 #undef UHWtype
1221 #undef DWtype
1222 #undef UDWtype
1223
1224 #undef char
1225 #undef short
1226 #undef int
1227 #undef long
1228 #undef unsigned
1229 #undef float
1230 #undef double
1231 \f
1232 #ifdef L__gcc_bcmp
1233
1234 /* Like bcmp except the sign is meaningful.
1235 Result is negative if S1 is less than S2,
1236 positive if S1 is greater, 0 if S1 and S2 are equal. */
1237
1238 int
1239 __gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
1240 {
1241 while (size > 0)
1242 {
1243 unsigned char c1 = *s1++, c2 = *s2++;
1244 if (c1 != c2)
1245 return c1 - c2;
1246 size--;
1247 }
1248 return 0;
1249 }
1250
1251 #endif
1252 \f
1253 /* __eprintf used to be used by GCC's private version of <assert.h>.
1254 We no longer provide that header, but this routine remains in libgcc.a
1255 for binary backward compatibility. Note that it is not included in
1256 the shared version of libgcc. */
1257 #ifdef L_eprintf
1258 #ifndef inhibit_libc
1259
1260 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1261 #include <stdio.h>
1262
1263 void
1264 __eprintf (const char *string, const char *expression,
1265 unsigned int line, const char *filename)
1266 {
1267 fprintf (stderr, string, expression, line, filename);
1268 fflush (stderr);
1269 abort ();
1270 }
1271
1272 #endif
1273 #endif
1274
1275 #ifdef L_bb
1276
1277 #if LONG_TYPE_SIZE == GCOV_TYPE_SIZE
1278 typedef long gcov_type;
1279 #else
1280 typedef long long gcov_type;
1281 #endif
1282
1283
1284 /* Structure emitted by -a */
1285 struct bb
1286 {
1287 long zero_word;
1288 const char *filename;
1289 gcov_type *counts;
1290 long ncounts;
1291 struct bb *next;
1292 const unsigned long *addresses;
1293
1294 /* Older GCC's did not emit these fields. */
1295 long nwords;
1296 const char **functions;
1297 const long *line_nums;
1298 const char **filenames;
1299 char *flags;
1300 };
1301
1302 #ifdef BLOCK_PROFILER_CODE
1303 BLOCK_PROFILER_CODE
1304 #else
1305 #ifndef inhibit_libc
1306
1307 /* Simple minded basic block profiling output dumper for
1308 systems that don't provide tcov support. At present,
1309 it requires atexit and stdio. */
1310
1311 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1312 #include <stdio.h>
1313
1314 #include "gbl-ctors.h"
1315 #include "gcov-io.h"
1316 #include <string.h>
1317 #ifdef TARGET_HAS_F_SETLKW
1318 #include <fcntl.h>
1319 #include <errno.h>
1320 #endif
1321
1322 static struct bb *bb_head;
1323
1324 void
1325 __bb_exit_func (void)
1326 {
1327 FILE *da_file;
1328 int i;
1329 struct bb *ptr;
1330
1331 if (bb_head == 0)
1332 return;
1333
1334 i = strlen (bb_head->filename) - 3;
1335
1336
1337 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1338 {
1339 int firstchar;
1340
1341 /* Make sure the output file exists -
1342 but don't clobber exiting data. */
1343 if ((da_file = fopen (ptr->filename, "a")) != 0)
1344 fclose (da_file);
1345
1346 /* Need to re-open in order to be able to write from the start. */
1347 da_file = fopen (ptr->filename, "r+b");
1348 /* Some old systems might not allow the 'b' mode modifier.
1349 Therefore, try to open without it. This can lead to a race
1350 condition so that when you delete and re-create the file, the
1351 file might be opened in text mode, but then, you shouldn't
1352 delete the file in the first place. */
1353 if (da_file == 0)
1354 da_file = fopen (ptr->filename, "r+");
1355 if (da_file == 0)
1356 {
1357 fprintf (stderr, "arc profiling: Can't open output file %s.\n",
1358 ptr->filename);
1359 continue;
1360 }
1361
1362 /* After a fork, another process might try to read and/or write
1363 the same file simultanously. So if we can, lock the file to
1364 avoid race conditions. */
1365 #if defined (TARGET_HAS_F_SETLKW)
1366 {
1367 struct flock s_flock;
1368
1369 s_flock.l_type = F_WRLCK;
1370 s_flock.l_whence = SEEK_SET;
1371 s_flock.l_start = 0;
1372 s_flock.l_len = 1;
1373 s_flock.l_pid = getpid ();
1374
1375 while (fcntl (fileno (da_file), F_SETLKW, &s_flock)
1376 && errno == EINTR);
1377 }
1378 #endif
1379
1380 /* If the file is not empty, and the number of counts in it is the
1381 same, then merge them in. */
1382 firstchar = fgetc (da_file);
1383 if (firstchar == EOF)
1384 {
1385 if (ferror (da_file))
1386 {
1387 fprintf (stderr, "arc profiling: Can't read output file ");
1388 perror (ptr->filename);
1389 }
1390 }
1391 else
1392 {
1393 long n_counts = 0;
1394
1395 if (ungetc (firstchar, da_file) == EOF)
1396 rewind (da_file);
1397 if (__read_long (&n_counts, da_file, 8) != 0)
1398 {
1399 fprintf (stderr, "arc profiling: Can't read output file %s.\n",
1400 ptr->filename);
1401 continue;
1402 }
1403
1404 if (n_counts == ptr->ncounts)
1405 {
1406 int i;
1407
1408 for (i = 0; i < n_counts; i++)
1409 {
1410 gcov_type v = 0;
1411
1412 if (__read_gcov_type (&v, da_file, 8) != 0)
1413 {
1414 fprintf (stderr,
1415 "arc profiling: Can't read output file %s.\n",
1416 ptr->filename);
1417 break;
1418 }
1419 ptr->counts[i] += v;
1420 }
1421 }
1422
1423 }
1424
1425 rewind (da_file);
1426
1427 /* ??? Should first write a header to the file. Preferably, a 4 byte
1428 magic number, 4 bytes containing the time the program was
1429 compiled, 4 bytes containing the last modification time of the
1430 source file, and 4 bytes indicating the compiler options used.
1431
1432 That way we can easily verify that the proper source/executable/
1433 data file combination is being used from gcov. */
1434
1435 if (__write_gcov_type (ptr->ncounts, da_file, 8) != 0)
1436 {
1437
1438 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1439 ptr->filename);
1440 }
1441 else
1442 {
1443 int j;
1444 gcov_type *count_ptr = ptr->counts;
1445 int ret = 0;
1446 for (j = ptr->ncounts; j > 0; j--)
1447 {
1448 if (__write_gcov_type (*count_ptr, da_file, 8) != 0)
1449 {
1450 ret = 1;
1451 break;
1452 }
1453 count_ptr++;
1454 }
1455 if (ret)
1456 fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1457 ptr->filename);
1458 }
1459
1460 if (fclose (da_file) == EOF)
1461 fprintf (stderr, "arc profiling: Error closing output file %s.\n",
1462 ptr->filename);
1463 }
1464
1465 return;
1466 }
1467
1468 void
1469 __bb_init_func (struct bb *blocks)
1470 {
1471 /* User is supposed to check whether the first word is non-0,
1472 but just in case.... */
1473
1474 if (blocks->zero_word)
1475 return;
1476
1477 /* Initialize destructor. */
1478 if (!bb_head)
1479 atexit (__bb_exit_func);
1480
1481 /* Set up linked list. */
1482 blocks->zero_word = 1;
1483 blocks->next = bb_head;
1484 bb_head = blocks;
1485 }
1486
1487 /* Called before fork or exec - write out profile information gathered so
1488 far and reset it to zero. This avoids duplication or loss of the
1489 profile information gathered so far. */
1490 void
1491 __bb_fork_func (void)
1492 {
1493 struct bb *ptr;
1494
1495 __bb_exit_func ();
1496 for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1497 {
1498 long i;
1499 for (i = ptr->ncounts - 1; i >= 0; i--)
1500 ptr->counts[i] = 0;
1501 }
1502 }
1503
1504 #endif /* not inhibit_libc */
1505 #endif /* not BLOCK_PROFILER_CODE */
1506 #endif /* L_bb */
1507 \f
1508 #ifdef L_clear_cache
1509 /* Clear part of an instruction cache. */
1510
1511 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1512
1513 void
1514 __clear_cache (char *beg __attribute__((__unused__)),
1515 char *end __attribute__((__unused__)))
1516 {
1517 #ifdef CLEAR_INSN_CACHE
1518 CLEAR_INSN_CACHE (beg, end);
1519 #else
1520 #ifdef INSN_CACHE_SIZE
1521 static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1522 static int initialized;
1523 int offset;
1524 void *start_addr
1525 void *end_addr;
1526 typedef (*function_ptr) (void);
1527
1528 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1529 /* It's cheaper to clear the whole cache.
1530 Put in a series of jump instructions so that calling the beginning
1531 of the cache will clear the whole thing. */
1532
1533 if (! initialized)
1534 {
1535 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1536 & -INSN_CACHE_LINE_WIDTH);
1537 int end_ptr = ptr + INSN_CACHE_SIZE;
1538
1539 while (ptr < end_ptr)
1540 {
1541 *(INSTRUCTION_TYPE *)ptr
1542 = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1543 ptr += INSN_CACHE_LINE_WIDTH;
1544 }
1545 *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1546
1547 initialized = 1;
1548 }
1549
1550 /* Call the beginning of the sequence. */
1551 (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1552 & -INSN_CACHE_LINE_WIDTH))
1553 ());
1554
1555 #else /* Cache is large. */
1556
1557 if (! initialized)
1558 {
1559 int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1560 & -INSN_CACHE_LINE_WIDTH);
1561
1562 while (ptr < (int) array + sizeof array)
1563 {
1564 *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1565 ptr += INSN_CACHE_LINE_WIDTH;
1566 }
1567
1568 initialized = 1;
1569 }
1570
1571 /* Find the location in array that occupies the same cache line as BEG. */
1572
1573 offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1574 start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1575 & -INSN_CACHE_PLANE_SIZE)
1576 + offset);
1577
1578 /* Compute the cache alignment of the place to stop clearing. */
1579 #if 0 /* This is not needed for gcc's purposes. */
1580 /* If the block to clear is bigger than a cache plane,
1581 we clear the entire cache, and OFFSET is already correct. */
1582 if (end < beg + INSN_CACHE_PLANE_SIZE)
1583 #endif
1584 offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1585 & -INSN_CACHE_LINE_WIDTH)
1586 & (INSN_CACHE_PLANE_SIZE - 1));
1587
1588 #if INSN_CACHE_DEPTH > 1
1589 end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1590 if (end_addr <= start_addr)
1591 end_addr += INSN_CACHE_PLANE_SIZE;
1592
1593 for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1594 {
1595 int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1596 int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1597
1598 while (addr != stop)
1599 {
1600 /* Call the return instruction at ADDR. */
1601 ((function_ptr) addr) ();
1602
1603 addr += INSN_CACHE_LINE_WIDTH;
1604 }
1605 }
1606 #else /* just one plane */
1607 do
1608 {
1609 /* Call the return instruction at START_ADDR. */
1610 ((function_ptr) start_addr) ();
1611
1612 start_addr += INSN_CACHE_LINE_WIDTH;
1613 }
1614 while ((start_addr % INSN_CACHE_SIZE) != offset);
1615 #endif /* just one plane */
1616 #endif /* Cache is large */
1617 #endif /* Cache exists */
1618 #endif /* CLEAR_INSN_CACHE */
1619 }
1620
1621 #endif /* L_clear_cache */
1622 \f
1623 #ifdef L_trampoline
1624
1625 /* Jump to a trampoline, loading the static chain address. */
1626
1627 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
1628
1629 long
1630 getpagesize (void)
1631 {
1632 #ifdef _ALPHA_
1633 return 8192;
1634 #else
1635 return 4096;
1636 #endif
1637 }
1638
1639 #ifdef __i386__
1640 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
1641 #endif
1642
1643 int
1644 mprotect (char *addr, int len, int prot)
1645 {
1646 int np, op;
1647
1648 if (prot == 7)
1649 np = 0x40;
1650 else if (prot == 5)
1651 np = 0x20;
1652 else if (prot == 4)
1653 np = 0x10;
1654 else if (prot == 3)
1655 np = 0x04;
1656 else if (prot == 1)
1657 np = 0x02;
1658 else if (prot == 0)
1659 np = 0x01;
1660
1661 if (VirtualProtect (addr, len, np, &op))
1662 return 0;
1663 else
1664 return -1;
1665 }
1666
1667 #endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
1668
1669 #ifdef TRANSFER_FROM_TRAMPOLINE
1670 TRANSFER_FROM_TRAMPOLINE
1671 #endif
1672
1673 #if defined (NeXT) && defined (__MACH__)
1674
1675 /* Make stack executable so we can call trampolines on stack.
1676 This is called from INITIALIZE_TRAMPOLINE in next.h. */
1677 #ifdef NeXTStep21
1678 #include <mach.h>
1679 #else
1680 #include <mach/mach.h>
1681 #endif
1682
1683 void
1684 __enable_execute_stack (char *addr)
1685 {
1686 kern_return_t r;
1687 char *eaddr = addr + TRAMPOLINE_SIZE;
1688 vm_address_t a = (vm_address_t) addr;
1689
1690 /* turn on execute access on stack */
1691 r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
1692 if (r != KERN_SUCCESS)
1693 {
1694 mach_error("vm_protect VM_PROT_ALL", r);
1695 exit(1);
1696 }
1697
1698 /* We inline the i-cache invalidation for speed */
1699
1700 #ifdef CLEAR_INSN_CACHE
1701 CLEAR_INSN_CACHE (addr, eaddr);
1702 #else
1703 __clear_cache ((int) addr, (int) eaddr);
1704 #endif
1705 }
1706
1707 #endif /* defined (NeXT) && defined (__MACH__) */
1708
1709 #ifdef __convex__
1710
1711 /* Make stack executable so we can call trampolines on stack.
1712 This is called from INITIALIZE_TRAMPOLINE in convex.h. */
1713
1714 #include <sys/mman.h>
1715 #include <sys/vmparam.h>
1716 #include <machine/machparam.h>
1717
1718 void
1719 __enable_execute_stack (void)
1720 {
1721 int fp;
1722 static unsigned lowest = USRSTACK;
1723 unsigned current = (unsigned) &fp & -NBPG;
1724
1725 if (lowest > current)
1726 {
1727 unsigned len = lowest - current;
1728 mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
1729 lowest = current;
1730 }
1731
1732 /* Clear instruction cache in case an old trampoline is in it. */
1733 asm ("pich");
1734 }
1735 #endif /* __convex__ */
1736
1737 #ifdef __sysV88__
1738
1739 /* Modified from the convex -code above. */
1740
1741 #include <sys/param.h>
1742 #include <errno.h>
1743 #include <sys/m88kbcs.h>
1744
1745 void
1746 __enable_execute_stack (void)
1747 {
1748 int save_errno;
1749 static unsigned long lowest = USRSTACK;
1750 unsigned long current = (unsigned long) &save_errno & -NBPC;
1751
1752 /* Ignore errno being set. memctl sets errno to EINVAL whenever the
1753 address is seen as 'negative'. That is the case with the stack. */
1754
1755 save_errno=errno;
1756 if (lowest > current)
1757 {
1758 unsigned len=lowest-current;
1759 memctl(current,len,MCT_TEXT);
1760 lowest = current;
1761 }
1762 else
1763 memctl(current,NBPC,MCT_TEXT);
1764 errno=save_errno;
1765 }
1766
1767 #endif /* __sysV88__ */
1768
1769 #ifdef __sysV68__
1770
1771 #include <sys/signal.h>
1772 #include <errno.h>
1773
1774 /* Motorola forgot to put memctl.o in the libp version of libc881.a,
1775 so define it here, because we need it in __clear_insn_cache below */
1776 /* On older versions of this OS, no memctl or MCT_TEXT are defined;
1777 hence we enable this stuff only if MCT_TEXT is #define'd. */
1778
1779 #ifdef MCT_TEXT
1780 asm("\n\
1781 global memctl\n\
1782 memctl:\n\
1783 movq &75,%d0\n\
1784 trap &0\n\
1785 bcc.b noerror\n\
1786 jmp cerror%\n\
1787 noerror:\n\
1788 movq &0,%d0\n\
1789 rts");
1790 #endif
1791
1792 /* Clear instruction cache so we can call trampolines on stack.
1793 This is called from FINALIZE_TRAMPOLINE in mot3300.h. */
1794
1795 void
1796 __clear_insn_cache (void)
1797 {
1798 #ifdef MCT_TEXT
1799 int save_errno;
1800
1801 /* Preserve errno, because users would be surprised to have
1802 errno changing without explicitly calling any system-call. */
1803 save_errno = errno;
1804
1805 /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache.
1806 No need to use an address derived from _start or %sp, as 0 works also. */
1807 memctl(0, 4096, MCT_TEXT);
1808 errno = save_errno;
1809 #endif
1810 }
1811
1812 #endif /* __sysV68__ */
1813
1814 #ifdef __pyr__
1815
1816 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
1817 #include <stdio.h>
1818 #include <sys/mman.h>
1819 #include <sys/types.h>
1820 #include <sys/param.h>
1821 #include <sys/vmmac.h>
1822
1823 /* Modified from the convex -code above.
1824 mremap promises to clear the i-cache. */
1825
1826 void
1827 __enable_execute_stack (void)
1828 {
1829 int fp;
1830 if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
1831 PROT_READ|PROT_WRITE|PROT_EXEC))
1832 {
1833 perror ("mprotect in __enable_execute_stack");
1834 fflush (stderr);
1835 abort ();
1836 }
1837 }
1838 #endif /* __pyr__ */
1839
1840 #if defined (sony_news) && defined (SYSTYPE_BSD)
1841
1842 #include <stdio.h>
1843 #include <sys/types.h>
1844 #include <sys/param.h>
1845 #include <syscall.h>
1846 #include <machine/sysnews.h>
1847
1848 /* cacheflush function for NEWS-OS 4.2.
1849 This function is called from trampoline-initialize code
1850 defined in config/mips/mips.h. */
1851
1852 void
1853 cacheflush (char *beg, int size, int flag)
1854 {
1855 if (syscall (SYS_sysnews, NEWS_CACHEFLUSH, beg, size, FLUSH_BCACHE))
1856 {
1857 perror ("cache_flush");
1858 fflush (stderr);
1859 abort ();
1860 }
1861 }
1862
1863 #endif /* sony_news */
1864 #endif /* L_trampoline */
1865 \f
1866 #ifndef __CYGWIN__
1867 #ifdef L__main
1868
1869 #include "gbl-ctors.h"
1870 /* Some systems use __main in a way incompatible with its use in gcc, in these
1871 cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
1872 give the same symbol without quotes for an alternative entry point. You
1873 must define both, or neither. */
1874 #ifndef NAME__MAIN
1875 #define NAME__MAIN "__main"
1876 #define SYMBOL__MAIN __main
1877 #endif
1878
1879 #ifdef INIT_SECTION_ASM_OP
1880 #undef HAS_INIT_SECTION
1881 #define HAS_INIT_SECTION
1882 #endif
1883
1884 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
1885
1886 /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
1887 code to run constructors. In that case, we need to handle EH here, too. */
1888
1889 #ifdef EH_FRAME_SECTION_NAME
1890 #include "unwind-dw2-fde.h"
1891 extern unsigned char __EH_FRAME_BEGIN__[];
1892 #endif
1893
1894 /* Run all the global destructors on exit from the program. */
1895
1896 void
1897 __do_global_dtors (void)
1898 {
1899 #ifdef DO_GLOBAL_DTORS_BODY
1900 DO_GLOBAL_DTORS_BODY;
1901 #else
1902 static func_ptr *p = __DTOR_LIST__ + 1;
1903 while (*p)
1904 {
1905 p++;
1906 (*(p-1)) ();
1907 }
1908 #endif
1909 #if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION)
1910 {
1911 static int completed = 0;
1912 if (! completed)
1913 {
1914 completed = 1;
1915 __deregister_frame_info (__EH_FRAME_BEGIN__);
1916 }
1917 }
1918 #endif
1919 }
1920 #endif
1921
1922 #ifndef HAS_INIT_SECTION
1923 /* Run all the global constructors on entry to the program. */
1924
1925 void
1926 __do_global_ctors (void)
1927 {
1928 #ifdef EH_FRAME_SECTION_NAME
1929 {
1930 static struct object object;
1931 __register_frame_info (__EH_FRAME_BEGIN__, &object);
1932 }
1933 #endif
1934 DO_GLOBAL_CTORS_BODY;
1935 atexit (__do_global_dtors);
1936 }
1937 #endif /* no HAS_INIT_SECTION */
1938
1939 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
1940 /* Subroutine called automatically by `main'.
1941 Compiling a global function named `main'
1942 produces an automatic call to this function at the beginning.
1943
1944 For many systems, this routine calls __do_global_ctors.
1945 For systems which support a .init section we use the .init section
1946 to run __do_global_ctors, so we need not do anything here. */
1947
1948 void
1949 SYMBOL__MAIN ()
1950 {
1951 /* Support recursive calls to `main': run initializers just once. */
1952 static int initialized;
1953 if (! initialized)
1954 {
1955 initialized = 1;
1956 __do_global_ctors ();
1957 }
1958 }
1959 #endif /* no HAS_INIT_SECTION or INVOKE__main */
1960
1961 #endif /* L__main */
1962 #endif /* __CYGWIN__ */
1963 \f
1964 #ifdef L_ctors
1965
1966 #include "gbl-ctors.h"
1967
1968 /* Provide default definitions for the lists of constructors and
1969 destructors, so that we don't get linker errors. These symbols are
1970 intentionally bss symbols, so that gld and/or collect will provide
1971 the right values. */
1972
1973 /* We declare the lists here with two elements each,
1974 so that they are valid empty lists if no other definition is loaded.
1975
1976 If we are using the old "set" extensions to have the gnu linker
1977 collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
1978 must be in the bss/common section.
1979
1980 Long term no port should use those extensions. But many still do. */
1981 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
1982 #if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2)
1983 func_ptr __CTOR_LIST__[2] = {0, 0};
1984 func_ptr __DTOR_LIST__[2] = {0, 0};
1985 #else
1986 func_ptr __CTOR_LIST__[2];
1987 func_ptr __DTOR_LIST__[2];
1988 #endif
1989 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1990 #endif /* L_ctors */
1991 \f
1992 #ifdef L_exit
1993
1994 #include "gbl-ctors.h"
1995
1996 #ifdef NEED_ATEXIT
1997
1998 #ifndef ON_EXIT
1999
2000 # include <errno.h>
2001
2002 static func_ptr *atexit_chain = 0;
2003 static long atexit_chain_length = 0;
2004 static volatile long last_atexit_chain_slot = -1;
2005
2006 int
2007 atexit (func_ptr func)
2008 {
2009 if (++last_atexit_chain_slot == atexit_chain_length)
2010 {
2011 atexit_chain_length += 32;
2012 if (atexit_chain)
2013 atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
2014 * sizeof (func_ptr));
2015 else
2016 atexit_chain = (func_ptr *) malloc (atexit_chain_length
2017 * sizeof (func_ptr));
2018 if (! atexit_chain)
2019 {
2020 atexit_chain_length = 0;
2021 last_atexit_chain_slot = -1;
2022 errno = ENOMEM;
2023 return (-1);
2024 }
2025 }
2026 atexit_chain[last_atexit_chain_slot] = func;
2027 return (0);
2028 }
2029
2030 extern void _cleanup (void);
2031 extern void _exit (int) __attribute__ ((__noreturn__));
2032
2033 void
2034 exit (int status)
2035 {
2036 if (atexit_chain)
2037 {
2038 for ( ; last_atexit_chain_slot-- >= 0; )
2039 {
2040 (*atexit_chain[last_atexit_chain_slot + 1]) ();
2041 atexit_chain[last_atexit_chain_slot + 1] = 0;
2042 }
2043 free (atexit_chain);
2044 atexit_chain = 0;
2045 }
2046 #ifdef EXIT_BODY
2047 EXIT_BODY;
2048 #else
2049 _cleanup ();
2050 #endif
2051 _exit (status);
2052 }
2053
2054 #else /* ON_EXIT */
2055
2056 /* Simple; we just need a wrapper for ON_EXIT. */
2057 int
2058 atexit (func_ptr func)
2059 {
2060 return ON_EXIT (func);
2061 }
2062
2063 #endif /* ON_EXIT */
2064 #endif /* NEED_ATEXIT */
2065
2066 #endif /* L_exit */