OSDN Git Service

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