OSDN Git Service

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