OSDN Git Service

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