]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/gcc/libgcc2.c
This commit was generated by cvs2svn to compensate for changes in r98038,
[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 #ifdef BLOCK_PROFILER_CODE
1294 BLOCK_PROFILER_CODE
1295 #else
1296 #ifndef inhibit_libc
1297
1298 /* Simple minded basic block profiling output dumper for
1299    systems that don't provide tcov support.  At present,
1300    it requires atexit and stdio.  */
1301
1302 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1303 #include <stdio.h>
1304
1305 #include "gbl-ctors.h"
1306 #include "gcov-io.h"
1307 #include <string.h>
1308 #ifdef TARGET_HAS_F_SETLKW
1309 #include <fcntl.h>
1310 #include <errno.h>
1311 #endif
1312
1313 static struct bb *bb_head;
1314
1315 void
1316 __bb_exit_func (void)
1317 {
1318   FILE *da_file;
1319   int i;
1320   struct bb *ptr;
1321
1322   if (bb_head == 0)
1323     return;
1324
1325   i = strlen (bb_head->filename) - 3;
1326
1327
1328   for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1329     {
1330       int firstchar;
1331
1332       /* Make sure the output file exists -
1333          but don't clobber exiting data.  */
1334       if ((da_file = fopen (ptr->filename, "a")) != 0)
1335         fclose (da_file);
1336
1337       /* Need to re-open in order to be able to write from the start.  */
1338       da_file = fopen (ptr->filename, "r+b");
1339       /* Some old systems might not allow the 'b' mode modifier.
1340          Therefore, try to open without it.  This can lead to a race
1341          condition so that when you delete and re-create the file, the
1342          file might be opened in text mode, but then, you shouldn't
1343          delete the file in the first place.  */
1344       if (da_file == 0)
1345         da_file = fopen (ptr->filename, "r+");
1346       if (da_file == 0)
1347         {
1348           fprintf (stderr, "arc profiling: Can't open output file %s.\n",
1349                    ptr->filename);
1350           continue;
1351         }
1352
1353       /* After a fork, another process might try to read and/or write
1354          the same file simultanously.  So if we can, lock the file to
1355          avoid race conditions.  */
1356 #if defined (TARGET_HAS_F_SETLKW)
1357       {
1358         struct flock s_flock;
1359
1360         s_flock.l_type = F_WRLCK;
1361         s_flock.l_whence = SEEK_SET;
1362         s_flock.l_start = 0;
1363         s_flock.l_len = 1;
1364         s_flock.l_pid = getpid ();
1365
1366         while (fcntl (fileno (da_file), F_SETLKW, &s_flock)
1367                && errno == EINTR);
1368       }
1369 #endif
1370
1371       /* If the file is not empty, and the number of counts in it is the
1372          same, then merge them in.  */
1373       firstchar = fgetc (da_file);
1374       if (firstchar == EOF)
1375         {
1376           if (ferror (da_file))
1377             {
1378               fprintf (stderr, "arc profiling: Can't read output file ");
1379               perror (ptr->filename);
1380             }
1381         }
1382       else
1383         {
1384           long n_counts = 0;
1385
1386           if (ungetc (firstchar, da_file) == EOF)
1387             rewind (da_file);
1388           if (__read_long (&n_counts, da_file, 8) != 0)
1389             {
1390               fprintf (stderr, "arc profiling: Can't read output file %s.\n",
1391                        ptr->filename);
1392               continue;
1393             }
1394
1395           if (n_counts == ptr->ncounts)
1396             {
1397               int i;
1398
1399               for (i = 0; i < n_counts; i++)
1400                 {
1401                   gcov_type v = 0;
1402
1403                   if (__read_gcov_type (&v, da_file, 8) != 0)
1404                     {
1405                       fprintf (stderr,
1406                                "arc profiling: Can't read output file %s.\n",
1407                                ptr->filename);
1408                       break;
1409                     }
1410                   ptr->counts[i] += v;
1411                 }
1412             }
1413
1414         }
1415
1416       rewind (da_file);
1417
1418       /* ??? Should first write a header to the file.  Preferably, a 4 byte
1419          magic number, 4 bytes containing the time the program was
1420          compiled, 4 bytes containing the last modification time of the
1421          source file, and 4 bytes indicating the compiler options used.
1422
1423          That way we can easily verify that the proper source/executable/
1424          data file combination is being used from gcov.  */
1425
1426       if (__write_gcov_type (ptr->ncounts, da_file, 8) != 0)
1427         {
1428
1429           fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1430                    ptr->filename);
1431         }
1432       else
1433         {
1434           int j;
1435           gcov_type *count_ptr = ptr->counts;
1436           int ret = 0;
1437           for (j = ptr->ncounts; j > 0; j--)
1438             {
1439               if (__write_gcov_type (*count_ptr, da_file, 8) != 0)
1440                 {
1441                   ret = 1;
1442                   break;
1443                 }
1444               count_ptr++;
1445             }
1446           if (ret)
1447             fprintf (stderr, "arc profiling: Error writing output file %s.\n",
1448                      ptr->filename);
1449         }
1450
1451       if (fclose (da_file) == EOF)
1452         fprintf (stderr, "arc profiling: Error closing output file %s.\n",
1453                  ptr->filename);
1454     }
1455
1456   return;
1457 }
1458
1459 void
1460 __bb_init_func (struct bb *blocks)
1461 {
1462   /* User is supposed to check whether the first word is non-0,
1463      but just in case....  */
1464
1465   if (blocks->zero_word)
1466     return;
1467
1468   /* Initialize destructor.  */
1469   if (!bb_head)
1470     atexit (__bb_exit_func);
1471
1472   /* Set up linked list.  */
1473   blocks->zero_word = 1;
1474   blocks->next = bb_head;
1475   bb_head = blocks;
1476 }
1477
1478 /* Called before fork or exec - write out profile information gathered so
1479    far and reset it to zero.  This avoids duplication or loss of the
1480    profile information gathered so far.  */
1481 void
1482 __bb_fork_func (void)
1483 {
1484   struct bb *ptr;
1485
1486   __bb_exit_func ();
1487   for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
1488     {
1489       long i;
1490       for (i = ptr->ncounts - 1; i >= 0; i--)
1491         ptr->counts[i] = 0;
1492     }
1493 }
1494
1495 #endif /* not inhibit_libc */
1496 #endif /* not BLOCK_PROFILER_CODE */
1497 #endif /* L_bb */
1498 \f
1499 #ifdef L_clear_cache
1500 /* Clear part of an instruction cache.  */
1501
1502 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1503
1504 void
1505 __clear_cache (char *beg __attribute__((__unused__)),
1506                char *end __attribute__((__unused__)))
1507 {
1508 #ifdef CLEAR_INSN_CACHE
1509   CLEAR_INSN_CACHE (beg, end);
1510 #else
1511 #ifdef INSN_CACHE_SIZE
1512   static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1513   static int initialized;
1514   int offset;
1515   void *start_addr
1516   void *end_addr;
1517   typedef (*function_ptr) (void);
1518
1519 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1520   /* It's cheaper to clear the whole cache.
1521      Put in a series of jump instructions so that calling the beginning
1522      of the cache will clear the whole thing.  */
1523
1524   if (! initialized)
1525     {
1526       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1527                  & -INSN_CACHE_LINE_WIDTH);
1528       int end_ptr = ptr + INSN_CACHE_SIZE;
1529
1530       while (ptr < end_ptr)
1531         {
1532           *(INSTRUCTION_TYPE *)ptr
1533             = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1534           ptr += INSN_CACHE_LINE_WIDTH;
1535         }
1536       *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1537
1538       initialized = 1;
1539     }
1540
1541   /* Call the beginning of the sequence.  */
1542   (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1543                     & -INSN_CACHE_LINE_WIDTH))
1544    ());
1545
1546 #else /* Cache is large.  */
1547
1548   if (! initialized)
1549     {
1550       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1551                  & -INSN_CACHE_LINE_WIDTH);
1552
1553       while (ptr < (int) array + sizeof array)
1554         {
1555           *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1556           ptr += INSN_CACHE_LINE_WIDTH;
1557         }
1558
1559       initialized = 1;
1560     }
1561
1562   /* Find the location in array that occupies the same cache line as BEG.  */
1563
1564   offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1565   start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1566                  & -INSN_CACHE_PLANE_SIZE)
1567                 + offset);
1568
1569   /* Compute the cache alignment of the place to stop clearing.  */
1570 #if 0  /* This is not needed for gcc's purposes.  */
1571   /* If the block to clear is bigger than a cache plane,
1572      we clear the entire cache, and OFFSET is already correct.  */
1573   if (end < beg + INSN_CACHE_PLANE_SIZE)
1574 #endif
1575     offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1576                & -INSN_CACHE_LINE_WIDTH)
1577               & (INSN_CACHE_PLANE_SIZE - 1));
1578
1579 #if INSN_CACHE_DEPTH > 1
1580   end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1581   if (end_addr <= start_addr)
1582     end_addr += INSN_CACHE_PLANE_SIZE;
1583
1584   for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1585     {
1586       int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1587       int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1588
1589       while (addr != stop)
1590         {
1591           /* Call the return instruction at ADDR.  */
1592           ((function_ptr) addr) ();
1593
1594           addr += INSN_CACHE_LINE_WIDTH;
1595         }
1596     }
1597 #else /* just one plane */
1598   do
1599     {
1600       /* Call the return instruction at START_ADDR.  */
1601       ((function_ptr) start_addr) ();
1602
1603       start_addr += INSN_CACHE_LINE_WIDTH;
1604     }
1605   while ((start_addr % INSN_CACHE_SIZE) != offset);
1606 #endif /* just one plane */
1607 #endif /* Cache is large */
1608 #endif /* Cache exists */
1609 #endif /* CLEAR_INSN_CACHE */
1610 }
1611
1612 #endif /* L_clear_cache */
1613 \f
1614 #ifdef L_trampoline
1615
1616 /* Jump to a trampoline, loading the static chain address.  */
1617
1618 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
1619
1620 long
1621 getpagesize (void)
1622 {
1623 #ifdef _ALPHA_
1624   return 8192;
1625 #else
1626   return 4096;
1627 #endif
1628 }
1629
1630 #ifdef __i386__
1631 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
1632 #endif
1633
1634 int
1635 mprotect (char *addr, int len, int prot)
1636 {
1637   int np, op;
1638
1639   if (prot == 7)
1640     np = 0x40;
1641   else if (prot == 5)
1642     np = 0x20;
1643   else if (prot == 4)
1644     np = 0x10;
1645   else if (prot == 3)
1646     np = 0x04;
1647   else if (prot == 1)
1648     np = 0x02;
1649   else if (prot == 0)
1650     np = 0x01;
1651
1652   if (VirtualProtect (addr, len, np, &op))
1653     return 0;
1654   else
1655     return -1;
1656 }
1657
1658 #endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
1659
1660 #ifdef TRANSFER_FROM_TRAMPOLINE
1661 TRANSFER_FROM_TRAMPOLINE
1662 #endif
1663
1664 #if defined (NeXT) && defined (__MACH__)
1665
1666 /* Make stack executable so we can call trampolines on stack.
1667    This is called from INITIALIZE_TRAMPOLINE in next.h.  */
1668 #ifdef NeXTStep21
1669  #include <mach.h>
1670 #else
1671  #include <mach/mach.h>
1672 #endif
1673
1674 void
1675 __enable_execute_stack (char *addr)
1676 {
1677   kern_return_t r;
1678   char *eaddr = addr + TRAMPOLINE_SIZE;
1679   vm_address_t a = (vm_address_t) addr;
1680
1681   /* turn on execute access on stack */
1682   r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL);
1683   if (r != KERN_SUCCESS)
1684     {
1685       mach_error("vm_protect VM_PROT_ALL", r);
1686       exit(1);
1687     }
1688
1689   /* We inline the i-cache invalidation for speed */
1690
1691 #ifdef CLEAR_INSN_CACHE
1692   CLEAR_INSN_CACHE (addr, eaddr);
1693 #else
1694   __clear_cache ((int) addr, (int) eaddr);
1695 #endif
1696 }
1697
1698 #endif /* defined (NeXT) && defined (__MACH__) */
1699
1700 #ifdef __convex__
1701
1702 /* Make stack executable so we can call trampolines on stack.
1703    This is called from INITIALIZE_TRAMPOLINE in convex.h.  */
1704
1705 #include <sys/mman.h>
1706 #include <sys/vmparam.h>
1707 #include <machine/machparam.h>
1708
1709 void
1710 __enable_execute_stack (void)
1711 {
1712   int fp;
1713   static unsigned lowest = USRSTACK;
1714   unsigned current = (unsigned) &fp & -NBPG;
1715
1716   if (lowest > current)
1717     {
1718       unsigned len = lowest - current;
1719       mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
1720       lowest = current;
1721     }
1722
1723   /* Clear instruction cache in case an old trampoline is in it.  */
1724   asm ("pich");
1725 }
1726 #endif /* __convex__ */
1727
1728 #ifdef __sysV88__
1729
1730 /* Modified from the convex -code above.  */
1731
1732 #include <sys/param.h>
1733 #include <errno.h>
1734 #include <sys/m88kbcs.h>
1735
1736 void
1737 __enable_execute_stack (void)
1738 {
1739   int save_errno;
1740   static unsigned long lowest = USRSTACK;
1741   unsigned long current = (unsigned long) &save_errno & -NBPC;
1742
1743   /* Ignore errno being set. memctl sets errno to EINVAL whenever the
1744      address is seen as 'negative'. That is the case with the stack.  */
1745
1746   save_errno=errno;
1747   if (lowest > current)
1748     {
1749       unsigned len=lowest-current;
1750       memctl(current,len,MCT_TEXT);
1751       lowest = current;
1752     }
1753   else
1754     memctl(current,NBPC,MCT_TEXT);
1755   errno=save_errno;
1756 }
1757
1758 #endif /* __sysV88__ */
1759
1760 #ifdef __sysV68__
1761
1762 #include <sys/signal.h>
1763 #include <errno.h>
1764
1765 /* Motorola forgot to put memctl.o in the libp version of libc881.a,
1766    so define it here, because we need it in __clear_insn_cache below */
1767 /* On older versions of this OS, no memctl or MCT_TEXT are defined;
1768    hence we enable this stuff only if MCT_TEXT is #define'd.  */
1769
1770 #ifdef MCT_TEXT
1771 asm("\n\
1772         global memctl\n\
1773 memctl:\n\
1774         movq &75,%d0\n\
1775         trap &0\n\
1776         bcc.b noerror\n\
1777         jmp cerror%\n\
1778 noerror:\n\
1779         movq &0,%d0\n\
1780         rts");
1781 #endif
1782
1783 /* Clear instruction cache so we can call trampolines on stack.
1784    This is called from FINALIZE_TRAMPOLINE in mot3300.h.  */
1785
1786 void
1787 __clear_insn_cache (void)
1788 {
1789 #ifdef MCT_TEXT
1790   int save_errno;
1791
1792   /* Preserve errno, because users would be surprised to have
1793   errno changing without explicitly calling any system-call.  */
1794   save_errno = errno;
1795
1796   /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache.
1797      No need to use an address derived from _start or %sp, as 0 works also.  */
1798   memctl(0, 4096, MCT_TEXT);
1799   errno = save_errno;
1800 #endif
1801 }
1802
1803 #endif /* __sysV68__ */
1804
1805 #ifdef __pyr__
1806
1807 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1808 #include <stdio.h>
1809 #include <sys/mman.h>
1810 #include <sys/types.h>
1811 #include <sys/param.h>
1812 #include <sys/vmmac.h>
1813
1814 /* Modified from the convex -code above.
1815    mremap promises to clear the i-cache.  */
1816
1817 void
1818 __enable_execute_stack (void)
1819 {
1820   int fp;
1821   if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
1822                 PROT_READ|PROT_WRITE|PROT_EXEC))
1823     {
1824       perror ("mprotect in __enable_execute_stack");
1825       fflush (stderr);
1826       abort ();
1827     }
1828 }
1829 #endif /* __pyr__ */
1830
1831 #if defined (sony_news) && defined (SYSTYPE_BSD)
1832
1833 #include <stdio.h>
1834 #include <sys/types.h>
1835 #include <sys/param.h>
1836 #include <syscall.h>
1837 #include <machine/sysnews.h>
1838
1839 /* cacheflush function for NEWS-OS 4.2.
1840    This function is called from trampoline-initialize code
1841    defined in config/mips/mips.h.  */
1842
1843 void
1844 cacheflush (char *beg, int size, int flag)
1845 {
1846   if (syscall (SYS_sysnews, NEWS_CACHEFLUSH, beg, size, FLUSH_BCACHE))
1847     {
1848       perror ("cache_flush");
1849       fflush (stderr);
1850       abort ();
1851     }
1852 }
1853
1854 #endif /* sony_news */
1855 #endif /* L_trampoline */
1856 \f
1857 #ifndef __CYGWIN__
1858 #ifdef L__main
1859
1860 #include "gbl-ctors.h"
1861 /* Some systems use __main in a way incompatible with its use in gcc, in these
1862    cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
1863    give the same symbol without quotes for an alternative entry point.  You
1864    must define both, or neither.  */
1865 #ifndef NAME__MAIN
1866 #define NAME__MAIN "__main"
1867 #define SYMBOL__MAIN __main
1868 #endif
1869
1870 #ifdef INIT_SECTION_ASM_OP
1871 #undef HAS_INIT_SECTION
1872 #define HAS_INIT_SECTION
1873 #endif
1874
1875 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
1876
1877 /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
1878    code to run constructors.  In that case, we need to handle EH here, too.  */
1879
1880 #ifdef EH_FRAME_SECTION_NAME
1881 #include "unwind-dw2-fde.h"
1882 extern unsigned char __EH_FRAME_BEGIN__[];
1883 #endif
1884
1885 /* Run all the global destructors on exit from the program.  */
1886
1887 void
1888 __do_global_dtors (void)
1889 {
1890 #ifdef DO_GLOBAL_DTORS_BODY
1891   DO_GLOBAL_DTORS_BODY;
1892 #else
1893   static func_ptr *p = __DTOR_LIST__ + 1;
1894   while (*p)
1895     {
1896       p++;
1897       (*(p-1)) ();
1898     }
1899 #endif
1900 #if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION)
1901   {
1902     static int completed = 0;
1903     if (! completed)
1904       {
1905         completed = 1;
1906         __deregister_frame_info (__EH_FRAME_BEGIN__);
1907       }
1908   }
1909 #endif
1910 }
1911 #endif
1912
1913 #ifndef HAS_INIT_SECTION
1914 /* Run all the global constructors on entry to the program.  */
1915
1916 void
1917 __do_global_ctors (void)
1918 {
1919 #ifdef EH_FRAME_SECTION_NAME
1920   {
1921     static struct object object;
1922     __register_frame_info (__EH_FRAME_BEGIN__, &object);
1923   }
1924 #endif
1925   DO_GLOBAL_CTORS_BODY;
1926   atexit (__do_global_dtors);
1927 }
1928 #endif /* no HAS_INIT_SECTION */
1929
1930 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
1931 /* Subroutine called automatically by `main'.
1932    Compiling a global function named `main'
1933    produces an automatic call to this function at the beginning.
1934
1935    For many systems, this routine calls __do_global_ctors.
1936    For systems which support a .init section we use the .init section
1937    to run __do_global_ctors, so we need not do anything here.  */
1938
1939 void
1940 SYMBOL__MAIN ()
1941 {
1942   /* Support recursive calls to `main': run initializers just once.  */
1943   static int initialized;
1944   if (! initialized)
1945     {
1946       initialized = 1;
1947       __do_global_ctors ();
1948     }
1949 }
1950 #endif /* no HAS_INIT_SECTION or INVOKE__main */
1951
1952 #endif /* L__main */
1953 #endif /* __CYGWIN__ */
1954 \f
1955 #ifdef L_ctors
1956
1957 #include "gbl-ctors.h"
1958
1959 /* Provide default definitions for the lists of constructors and
1960    destructors, so that we don't get linker errors.  These symbols are
1961    intentionally bss symbols, so that gld and/or collect will provide
1962    the right values.  */
1963
1964 /* We declare the lists here with two elements each,
1965    so that they are valid empty lists if no other definition is loaded.
1966
1967    If we are using the old "set" extensions to have the gnu linker
1968    collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
1969    must be in the bss/common section.
1970
1971    Long term no port should use those extensions.  But many still do.  */
1972 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
1973 #if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2)
1974 func_ptr __CTOR_LIST__[2] = {0, 0};
1975 func_ptr __DTOR_LIST__[2] = {0, 0};
1976 #else
1977 func_ptr __CTOR_LIST__[2];
1978 func_ptr __DTOR_LIST__[2];
1979 #endif
1980 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1981 #endif /* L_ctors */
1982 \f
1983 #ifdef L_exit
1984
1985 #include "gbl-ctors.h"
1986
1987 #ifdef NEED_ATEXIT
1988
1989 #ifndef ON_EXIT
1990
1991 # include <errno.h>
1992
1993 static func_ptr *atexit_chain = 0;
1994 static long atexit_chain_length = 0;
1995 static volatile long last_atexit_chain_slot = -1;
1996
1997 int
1998 atexit (func_ptr func)
1999 {
2000   if (++last_atexit_chain_slot == atexit_chain_length)
2001     {
2002       atexit_chain_length += 32;
2003       if (atexit_chain)
2004         atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
2005                                              * sizeof (func_ptr));
2006       else
2007         atexit_chain = (func_ptr *) malloc (atexit_chain_length
2008                                             * sizeof (func_ptr));
2009       if (! atexit_chain)
2010         {
2011           atexit_chain_length = 0;
2012           last_atexit_chain_slot = -1;
2013           errno = ENOMEM;
2014           return (-1);
2015         }
2016     }
2017   atexit_chain[last_atexit_chain_slot] = func;
2018   return (0);
2019 }
2020
2021 extern void _cleanup (void);
2022 extern void _exit (int) __attribute__ ((__noreturn__));
2023
2024 void
2025 exit (int status)
2026 {
2027   if (atexit_chain)
2028     {
2029       for ( ; last_atexit_chain_slot-- >= 0; )
2030         {
2031           (*atexit_chain[last_atexit_chain_slot + 1]) ();
2032           atexit_chain[last_atexit_chain_slot + 1] = 0;
2033         }
2034       free (atexit_chain);
2035       atexit_chain = 0;
2036     }
2037 #ifdef EXIT_BODY
2038   EXIT_BODY;
2039 #else
2040   _cleanup ();
2041 #endif
2042   _exit (status);
2043 }
2044
2045 #else /* ON_EXIT */
2046
2047 /* Simple; we just need a wrapper for ON_EXIT.  */
2048 int
2049 atexit (func_ptr func)
2050 {
2051   return ON_EXIT (func);
2052 }
2053
2054 #endif /* ON_EXIT */
2055 #endif /* NEED_ATEXIT */
2056
2057 #endif /* L_exit */