OSDN Git Service

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