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