OSDN Git Service

2003-09-19 Joel Sherrill <joel@oarcorp.com>
[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, 2003  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
33 /* We include auto-host.h here to get HAVE_GAS_HIDDEN.  This is
34    supposedly valid even though this is a "target" file.  */
35 #include "auto-host.h"
36
37 /* It is incorrect to include config.h here, because this file is being
38    compiled for the target, and hence definitions concerning only the host
39    do not apply.  */
40 #include "tconfig.h"
41 #include "tsystem.h"
42 #include "coretypes.h"
43 #include "tm.h"
44
45 /* Don't use `fancy_abort' here even if config.h says to use it.  */
46 #ifdef abort
47 #undef abort
48 #endif
49
50 #ifdef HAVE_GAS_HIDDEN
51 #define ATTRIBUTE_HIDDEN  __attribute__ ((__visibility__ ("hidden")))
52 #else
53 #define ATTRIBUTE_HIDDEN
54 #endif
55
56 #include "libgcc2.h"
57 \f
58 #ifdef DECLARE_LIBRARY_RENAMES
59   DECLARE_LIBRARY_RENAMES
60 #endif
61
62 #if defined (L_negdi2)
63 DWtype
64 __negdi2 (DWtype u)
65 {
66   DWunion w;
67   DWunion uu;
68
69   uu.ll = u;
70
71   w.s.low = -uu.s.low;
72   w.s.high = -uu.s.high - ((UWtype) w.s.low > 0);
73
74   return w.ll;
75 }
76 #endif
77
78 #ifdef L_addvsi3
79 Wtype
80 __addvsi3 (Wtype a, Wtype b)
81 {
82   Wtype w;
83
84   w = a + b;
85
86   if (b >= 0 ? w < a : w > a)
87     abort ();
88
89   return w;
90 }
91 #endif
92 \f
93 #ifdef L_addvdi3
94 DWtype
95 __addvdi3 (DWtype a, DWtype b)
96 {
97   DWtype w;
98
99   w = a + b;
100
101   if (b >= 0 ? w < a : w > a)
102     abort ();
103
104   return w;
105 }
106 #endif
107 \f
108 #ifdef L_subvsi3
109 Wtype
110 __subvsi3 (Wtype a, Wtype b)
111 {
112   DWtype w;
113
114   w = a - b;
115
116   if (b >= 0 ? w > a : w < a)
117     abort ();
118
119   return w;
120 }
121 #endif
122 \f
123 #ifdef L_subvdi3
124 DWtype
125 __subvdi3 (DWtype a, DWtype b)
126 {
127   DWtype w;
128
129   w = a - b;
130
131   if (b >= 0 ? w > a : w < a)
132     abort ();
133
134   return w;
135 }
136 #endif
137 \f
138 #ifdef L_mulvsi3
139 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
140 Wtype
141 __mulvsi3 (Wtype a, Wtype b)
142 {
143   DWtype w;
144
145   w = (DWtype) a * (DWtype) b;
146
147   if (((a >= 0) == (b >= 0))
148       ? (UDWtype) w > (UDWtype) (((DWtype) 1 << (WORD_SIZE - 1)) - 1)
149       : (UDWtype) w < (UDWtype) ((DWtype) -1 << (WORD_SIZE - 1)))
150     abort ();
151
152   return w;
153 }
154 #endif
155 \f
156 #ifdef L_negvsi2
157 Wtype
158 __negvsi2 (Wtype a)
159 {
160   Wtype w;
161
162   w  = -a;
163
164   if (a >= 0 ? w > 0 : w < 0)
165     abort ();
166
167    return w;
168 }
169 #endif
170 \f
171 #ifdef L_negvdi2
172 DWtype
173 __negvdi2 (DWtype a)
174 {
175   DWtype w;
176
177   w  = -a;
178
179   if (a >= 0 ? w > 0 : w < 0)
180     abort ();
181
182   return w;
183 }
184 #endif
185 \f
186 #ifdef L_absvsi2
187 Wtype
188 __absvsi2 (Wtype a)
189 {
190   Wtype w = a;
191
192   if (a < 0)
193 #ifdef L_negvsi2
194     w = __negvsi2 (a);
195 #else
196     w = -a;
197
198   if (w < 0)
199     abort ();
200 #endif
201
202    return w;
203 }
204 #endif
205 \f
206 #ifdef L_absvdi2
207 DWtype
208 __absvdi2 (DWtype a)
209 {
210   DWtype w = a;
211
212   if (a < 0)
213 #ifdef L_negvdi2
214     w = __negvdi2 (a);
215 #else
216     w = -a;
217
218   if (w < 0)
219     abort ();
220 #endif
221
222   return w;
223 }
224 #endif
225 \f
226 #ifdef L_mulvdi3
227 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
228 DWtype
229 __mulvdi3 (DWtype u, DWtype v)
230 {
231   /* The unchecked multiplication needs 3 Wtype x Wtype multiplications,
232      but the checked multiplication needs only two.  */
233   DWunion uu, vv;
234
235   uu.ll = u;
236   vv.ll = v;
237
238   if (__builtin_expect (uu.s.high == uu.s.low >> (WORD_SIZE - 1), 1))
239     {
240       /* u fits in a single Wtype.  */
241       if (__builtin_expect (vv.s.high == vv.s.low >> (WORD_SIZE - 1), 1))
242         {
243           /* v fits in a single Wtype as well.  */
244           /* A single multiplication.  No overflow risk.  */
245           return (DWtype) uu.s.low * (DWtype) vv.s.low;
246         }
247       else
248         {
249           /* Two multiplications.  */
250           DWunion w0, w1;
251
252           w0.ll = (UDWtype) (UWtype) uu.s.low * (UDWtype) (UWtype) vv.s.low;
253           w1.ll = (UDWtype) (UWtype) uu.s.low * (UDWtype) (UWtype) vv.s.high;
254           if (vv.s.high < 0)
255             w1.s.high -= uu.s.low;
256           if (uu.s.low < 0)
257             w1.ll -= vv.ll;
258           w1.ll += (UWtype) w0.s.high;
259           if (__builtin_expect (w1.s.high == w1.s.low >> (WORD_SIZE - 1), 1))
260             {
261               w0.s.high = w1.s.low;
262               return w0.ll;
263             }
264         }
265     }
266   else
267     {
268       if (__builtin_expect (vv.s.high == vv.s.low >> (WORD_SIZE - 1), 1))
269         {
270           /* v fits into a single Wtype.  */
271           /* Two multiplications.  */
272           DWunion w0, w1;
273
274           w0.ll = (UDWtype) (UWtype) uu.s.low * (UDWtype) (UWtype) vv.s.low;
275           w1.ll = (UDWtype) (UWtype) uu.s.high * (UDWtype) (UWtype) vv.s.low;
276           if (uu.s.high < 0)
277             w1.s.high -= vv.s.low;
278           if (vv.s.low < 0)
279             w1.ll -= uu.ll;
280           w1.ll += (UWtype) w0.s.high;
281           if (__builtin_expect (w1.s.high == w1.s.low >> (WORD_SIZE - 1), 1))
282             {
283               w0.s.high = w1.s.low;
284               return w0.ll;
285             }
286         }
287       else
288         {
289           /* A few sign checks and a single multiplication.  */
290           if (uu.s.high >= 0)
291             {
292               if (vv.s.high >= 0)
293                 {
294                   if (uu.s.high == 0 && vv.s.high == 0)
295                     {
296                       DWtype w;
297
298                       w = (UDWtype) (UWtype) uu.s.low
299                           * (UDWtype) (UWtype) vv.s.low;
300                       if (__builtin_expect (w >= 0, 1))
301                         return w;
302                     }
303                 }
304               else
305                 {
306                   if (uu.s.high == 0 && vv.s.high == (Wtype) -1)
307                     {
308                       DWunion ww;
309
310                       ww.ll = (UDWtype) (UWtype) uu.s.low
311                               * (UDWtype) (UWtype) vv.s.low;
312                       ww.s.high -= uu.s.low;
313                       if (__builtin_expect (ww.s.high < 0, 1))
314                         return ww.ll;
315                     }
316                 }
317             }
318           else
319             {
320               if (vv.s.high >= 0)
321                 {
322                   if (uu.s.high == (Wtype) -1 && vv.s.high == 0)
323                     {
324                       DWunion ww;
325
326                       ww.ll = (UDWtype) (UWtype) uu.s.low
327                               * (UDWtype) (UWtype) vv.s.low;
328                       ww.s.high -= vv.s.low;
329                       if (__builtin_expect (ww.s.high < 0, 1))
330                         return ww.ll;
331                     }
332                 }
333               else
334                 {
335                   if (uu.s.high == (Wtype) -1 && vv.s.high == (Wtype) - 1)
336                     {
337                       DWunion ww;
338
339                       ww.ll = (UDWtype) (UWtype) uu.s.low
340                               * (UDWtype) (UWtype) vv.s.low;
341                       ww.s.high -= uu.s.low;
342                       ww.s.high -= vv.s.low;
343                       if (__builtin_expect (ww.s.high >= 0, 1))
344                         return ww.ll;
345                     }
346                 }
347             }
348         }
349     }
350
351   /* Overflow.  */
352   abort ();
353 }
354 #endif
355 \f
356
357 /* Unless shift functions are defined with full ANSI prototypes,
358    parameter b will be promoted to int if word_type is smaller than an int.  */
359 #ifdef L_lshrdi3
360 DWtype
361 __lshrdi3 (DWtype u, word_type b)
362 {
363   DWunion w;
364   word_type bm;
365   DWunion uu;
366
367   if (b == 0)
368     return u;
369
370   uu.ll = u;
371
372   bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
373   if (bm <= 0)
374     {
375       w.s.high = 0;
376       w.s.low = (UWtype) uu.s.high >> -bm;
377     }
378   else
379     {
380       UWtype carries = (UWtype) uu.s.high << bm;
381
382       w.s.high = (UWtype) uu.s.high >> b;
383       w.s.low = ((UWtype) uu.s.low >> b) | carries;
384     }
385
386   return w.ll;
387 }
388 #endif
389
390 #ifdef L_ashldi3
391 DWtype
392 __ashldi3 (DWtype u, word_type b)
393 {
394   DWunion w;
395   word_type bm;
396   DWunion uu;
397
398   if (b == 0)
399     return u;
400
401   uu.ll = u;
402
403   bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
404   if (bm <= 0)
405     {
406       w.s.low = 0;
407       w.s.high = (UWtype) uu.s.low << -bm;
408     }
409   else
410     {
411       UWtype carries = (UWtype) uu.s.low >> bm;
412
413       w.s.low = (UWtype) uu.s.low << b;
414       w.s.high = ((UWtype) uu.s.high << b) | carries;
415     }
416
417   return w.ll;
418 }
419 #endif
420
421 #ifdef L_ashrdi3
422 DWtype
423 __ashrdi3 (DWtype u, word_type b)
424 {
425   DWunion w;
426   word_type bm;
427   DWunion uu;
428
429   if (b == 0)
430     return u;
431
432   uu.ll = u;
433
434   bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
435   if (bm <= 0)
436     {
437       /* w.s.high = 1..1 or 0..0 */
438       w.s.high = uu.s.high >> (sizeof (Wtype) * BITS_PER_UNIT - 1);
439       w.s.low = uu.s.high >> -bm;
440     }
441   else
442     {
443       UWtype carries = (UWtype) uu.s.high << bm;
444
445       w.s.high = uu.s.high >> b;
446       w.s.low = ((UWtype) uu.s.low >> b) | carries;
447     }
448
449   return w.ll;
450 }
451 #endif
452 \f
453 #ifdef L_ffssi2
454 #undef int
455 extern int __ffsSI2 (UWtype u);
456 int
457 __ffsSI2 (UWtype u)
458 {
459   UWtype count;
460
461   if (u == 0)
462     return 0;
463
464   count_trailing_zeros (count, u);
465   return count + 1;
466 }
467 #endif
468 \f
469 #ifdef L_ffsdi2
470 #undef int
471 extern int __ffsDI2 (DWtype u);
472 int
473 __ffsDI2 (DWtype u)
474 {
475   DWunion uu;
476   UWtype word, count, add;
477
478   uu.ll = u;
479   if (uu.s.low != 0)
480     word = uu.s.low, add = 0;
481   else if (uu.s.high != 0)
482     word = uu.s.high, add = BITS_PER_UNIT * sizeof (Wtype);
483   else
484     return 0;
485
486   count_trailing_zeros (count, word);
487   return count + add + 1;
488 }
489 #endif
490 \f
491 #ifdef L_muldi3
492 DWtype
493 __muldi3 (DWtype u, DWtype v)
494 {
495   DWunion w;
496   DWunion uu, vv;
497
498   uu.ll = u,
499   vv.ll = v;
500
501   w.ll = __umulsidi3 (uu.s.low, vv.s.low);
502   w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
503                + (UWtype) uu.s.high * (UWtype) vv.s.low);
504
505   return w.ll;
506 }
507 #endif
508 \f
509 #if (defined (L_udivdi3) || defined (L_divdi3) || \
510      defined (L_umoddi3) || defined (L_moddi3))
511 #if defined (sdiv_qrnnd)
512 #define L_udiv_w_sdiv
513 #endif
514 #endif
515
516 #ifdef L_udiv_w_sdiv
517 #if defined (sdiv_qrnnd)
518 #if (defined (L_udivdi3) || defined (L_divdi3) || \
519      defined (L_umoddi3) || defined (L_moddi3))
520 static inline __attribute__ ((__always_inline__))
521 #endif
522 UWtype
523 __udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d)
524 {
525   UWtype q, r;
526   UWtype c0, c1, b1;
527
528   if ((Wtype) d >= 0)
529     {
530       if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1)))
531         {
532           /* dividend, divisor, and quotient are nonnegative */
533           sdiv_qrnnd (q, r, a1, a0, d);
534         }
535       else
536         {
537           /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
538           sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1));
539           /* Divide (c1*2^32 + c0) by d */
540           sdiv_qrnnd (q, r, c1, c0, d);
541           /* Add 2^31 to quotient */
542           q += (UWtype) 1 << (W_TYPE_SIZE - 1);
543         }
544     }
545   else
546     {
547       b1 = d >> 1;                      /* d/2, between 2^30 and 2^31 - 1 */
548       c1 = a1 >> 1;                     /* A/2 */
549       c0 = (a1 << (W_TYPE_SIZE - 1)) + (a0 >> 1);
550
551       if (a1 < b1)                      /* A < 2^32*b1, so A/2 < 2^31*b1 */
552         {
553           sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
554
555           r = 2*r + (a0 & 1);           /* Remainder from A/(2*b1) */
556           if ((d & 1) != 0)
557             {
558               if (r >= q)
559                 r = r - q;
560               else if (q - r <= d)
561                 {
562                   r = r - q + d;
563                   q--;
564                 }
565               else
566                 {
567                   r = r - q + 2*d;
568                   q -= 2;
569                 }
570             }
571         }
572       else if (c1 < b1)                 /* So 2^31 <= (A/2)/b1 < 2^32 */
573         {
574           c1 = (b1 - 1) - c1;
575           c0 = ~c0;                     /* logical NOT */
576
577           sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
578
579           q = ~q;                       /* (A/2)/b1 */
580           r = (b1 - 1) - r;
581
582           r = 2*r + (a0 & 1);           /* A/(2*b1) */
583
584           if ((d & 1) != 0)
585             {
586               if (r >= q)
587                 r = r - q;
588               else if (q - r <= d)
589                 {
590                   r = r - q + d;
591                   q--;
592                 }
593               else
594                 {
595                   r = r - q + 2*d;
596                   q -= 2;
597                 }
598             }
599         }
600       else                              /* Implies c1 = b1 */
601         {                               /* Hence a1 = d - 1 = 2*b1 - 1 */
602           if (a0 >= -d)
603             {
604               q = -1;
605               r = a0 + d;
606             }
607           else
608             {
609               q = -2;
610               r = a0 + 2*d;
611             }
612         }
613     }
614
615   *rp = r;
616   return q;
617 }
618 #else
619 /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv.  */
620 UWtype
621 __udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)),
622                UWtype a1 __attribute__ ((__unused__)),
623                UWtype a0 __attribute__ ((__unused__)),
624                UWtype d __attribute__ ((__unused__)))
625 {
626   return 0;
627 }
628 #endif
629 #endif
630 \f
631 #if (defined (L_udivdi3) || defined (L_divdi3) || \
632      defined (L_umoddi3) || defined (L_moddi3))
633 #define L_udivmoddi4
634 #endif
635
636 #ifdef L_clz
637 const UQItype __clz_tab[] =
638 {
639   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,
640   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,
641   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,
642   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,
643   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,
644   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,
645   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,
646   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,
647 };
648 #endif
649 \f
650 #ifdef L_clzsi2
651 #undef int
652 extern int __clzSI2 (UWtype x);
653 int
654 __clzSI2 (UWtype x)
655 {
656   Wtype ret;
657
658   count_leading_zeros (ret, x);
659
660   return ret;
661 }
662 #endif
663 \f
664 #ifdef L_clzdi2
665 #undef int
666 extern int __clzDI2 (UDWtype x);
667 int
668 __clzDI2 (UDWtype x)
669 {
670   DWunion uu;
671   UWtype word;
672   Wtype ret, add;
673
674   uu.ll = x;
675   if (uu.s.high)
676     word = uu.s.high, add = 0;
677   else
678     word = uu.s.low, add = W_TYPE_SIZE;
679
680   count_leading_zeros (ret, word);
681   return ret + add;
682 }
683 #endif
684 \f
685 #ifdef L_ctzsi2
686 #undef int
687 extern int __ctzSI2 (UWtype x);
688 int
689 __ctzSI2 (UWtype x)
690 {
691   Wtype ret;
692
693   count_trailing_zeros (ret, x);
694
695   return ret;
696 }
697 #endif
698 \f
699 #ifdef L_ctzdi2
700 #undef int
701 extern int __ctzDI2 (UDWtype x);
702 int
703 __ctzDI2 (UDWtype x)
704 {
705   DWunion uu;
706   UWtype word;
707   Wtype ret, add;
708
709   uu.ll = x;
710   if (uu.s.low)
711     word = uu.s.low, add = 0;
712   else
713     word = uu.s.high, add = W_TYPE_SIZE;
714
715   count_trailing_zeros (ret, word);
716   return ret + add;
717 }
718 #endif
719
720 #if (defined (L_popcountsi2) || defined (L_popcountdi2) \
721      || defined (L_popcount_tab))
722 extern const UQItype __popcount_tab[] ATTRIBUTE_HIDDEN;
723 #endif
724
725 #ifdef L_popcount_tab
726 const UQItype __popcount_tab[] =
727 {
728     0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
729     1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
730     1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
731     2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
732     1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
733     2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
734     2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
735     3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
736 };
737 #endif
738 \f
739 #ifdef L_popcountsi2
740 #undef int
741 extern int __popcountSI2 (UWtype x);
742 int
743 __popcountSI2 (UWtype x)
744 {
745   UWtype i, ret = 0;
746
747   for (i = 0; i < W_TYPE_SIZE; i += 8)
748     ret += __popcount_tab[(x >> i) & 0xff];
749
750   return ret;
751 }
752 #endif
753 \f
754 #ifdef L_popcountdi2
755 #undef int
756 extern int __popcountDI2 (UDWtype x);
757 int
758 __popcountDI2 (UDWtype x)
759 {
760   UWtype i, ret = 0;
761
762   for (i = 0; i < 2*W_TYPE_SIZE; i += 8)
763     ret += __popcount_tab[(x >> i) & 0xff];
764
765   return ret;
766 }
767 #endif
768 \f
769 #ifdef L_paritysi2
770 #undef int
771 extern int __paritySI2 (UWtype x);
772 int
773 __paritySI2 (UWtype x)
774 {
775 #if W_TYPE_SIZE > 64
776 # error "fill out the table"
777 #endif
778 #if W_TYPE_SIZE > 32
779   x ^= x >> 32;
780 #endif
781 #if W_TYPE_SIZE > 16
782   x ^= x >> 16;
783 #endif
784   x ^= x >> 8;
785   x ^= x >> 4;
786   x &= 0xf;
787   return (0x6996 >> x) & 1;
788 }
789 #endif
790 \f
791 #ifdef L_paritydi2
792 #undef int
793 extern int __parityDI2 (UDWtype x);
794 int
795 __parityDI2 (UDWtype x)
796 {
797   DWunion uu;
798   UWtype nx;
799
800   uu.ll = x;
801   nx = uu.s.low ^ uu.s.high;
802
803 #if W_TYPE_SIZE > 64
804 # error "fill out the table"
805 #endif
806 #if W_TYPE_SIZE > 32
807   nx ^= nx >> 32;
808 #endif
809 #if W_TYPE_SIZE > 16
810   nx ^= nx >> 16;
811 #endif
812   nx ^= nx >> 8;
813   nx ^= nx >> 4;
814   nx &= 0xf;
815   return (0x6996 >> nx) & 1;
816 }
817 #endif
818
819 #ifdef L_udivmoddi4
820
821 #if (defined (L_udivdi3) || defined (L_divdi3) || \
822      defined (L_umoddi3) || defined (L_moddi3))
823 static inline __attribute__ ((__always_inline__))
824 #endif
825 UDWtype
826 __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
827 {
828   DWunion ww;
829   DWunion nn, dd;
830   DWunion rr;
831   UWtype d0, d1, n0, n1, n2;
832   UWtype q0, q1;
833   UWtype b, bm;
834
835   nn.ll = n;
836   dd.ll = d;
837
838   d0 = dd.s.low;
839   d1 = dd.s.high;
840   n0 = nn.s.low;
841   n1 = nn.s.high;
842
843 #if !UDIV_NEEDS_NORMALIZATION
844   if (d1 == 0)
845     {
846       if (d0 > n1)
847         {
848           /* 0q = nn / 0D */
849
850           udiv_qrnnd (q0, n0, n1, n0, d0);
851           q1 = 0;
852
853           /* Remainder in n0.  */
854         }
855       else
856         {
857           /* qq = NN / 0d */
858
859           if (d0 == 0)
860             d0 = 1 / d0;        /* Divide intentionally by zero.  */
861
862           udiv_qrnnd (q1, n1, 0, n1, d0);
863           udiv_qrnnd (q0, n0, n1, n0, d0);
864
865           /* Remainder in n0.  */
866         }
867
868       if (rp != 0)
869         {
870           rr.s.low = n0;
871           rr.s.high = 0;
872           *rp = rr.ll;
873         }
874     }
875
876 #else /* UDIV_NEEDS_NORMALIZATION */
877
878   if (d1 == 0)
879     {
880       if (d0 > n1)
881         {
882           /* 0q = nn / 0D */
883
884           count_leading_zeros (bm, d0);
885
886           if (bm != 0)
887             {
888               /* Normalize, i.e. make the most significant bit of the
889                  denominator set.  */
890
891               d0 = d0 << bm;
892               n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
893               n0 = n0 << bm;
894             }
895
896           udiv_qrnnd (q0, n0, n1, n0, d0);
897           q1 = 0;
898
899           /* Remainder in n0 >> bm.  */
900         }
901       else
902         {
903           /* qq = NN / 0d */
904
905           if (d0 == 0)
906             d0 = 1 / d0;        /* Divide intentionally by zero.  */
907
908           count_leading_zeros (bm, d0);
909
910           if (bm == 0)
911             {
912               /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
913                  conclude (the most significant bit of n1 is set) /\ (the
914                  leading quotient digit q1 = 1).
915
916                  This special case is necessary, not an optimization.
917                  (Shifts counts of W_TYPE_SIZE are undefined.)  */
918
919               n1 -= d0;
920               q1 = 1;
921             }
922           else
923             {
924               /* Normalize.  */
925
926               b = W_TYPE_SIZE - bm;
927
928               d0 = d0 << bm;
929               n2 = n1 >> b;
930               n1 = (n1 << bm) | (n0 >> b);
931               n0 = n0 << bm;
932
933               udiv_qrnnd (q1, n1, n2, n1, d0);
934             }
935
936           /* n1 != d0...  */
937
938           udiv_qrnnd (q0, n0, n1, n0, d0);
939
940           /* Remainder in n0 >> bm.  */
941         }
942
943       if (rp != 0)
944         {
945           rr.s.low = n0 >> bm;
946           rr.s.high = 0;
947           *rp = rr.ll;
948         }
949     }
950 #endif /* UDIV_NEEDS_NORMALIZATION */
951
952   else
953     {
954       if (d1 > n1)
955         {
956           /* 00 = nn / DD */
957
958           q0 = 0;
959           q1 = 0;
960
961           /* Remainder in n1n0.  */
962           if (rp != 0)
963             {
964               rr.s.low = n0;
965               rr.s.high = n1;
966               *rp = rr.ll;
967             }
968         }
969       else
970         {
971           /* 0q = NN / dd */
972
973           count_leading_zeros (bm, d1);
974           if (bm == 0)
975             {
976               /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
977                  conclude (the most significant bit of n1 is set) /\ (the
978                  quotient digit q0 = 0 or 1).
979
980                  This special case is necessary, not an optimization.  */
981
982               /* The condition on the next line takes advantage of that
983                  n1 >= d1 (true due to program flow).  */
984               if (n1 > d1 || n0 >= d0)
985                 {
986                   q0 = 1;
987                   sub_ddmmss (n1, n0, n1, n0, d1, d0);
988                 }
989               else
990                 q0 = 0;
991
992               q1 = 0;
993
994               if (rp != 0)
995                 {
996                   rr.s.low = n0;
997                   rr.s.high = n1;
998                   *rp = rr.ll;
999                 }
1000             }
1001           else
1002             {
1003               UWtype m1, m0;
1004               /* Normalize.  */
1005
1006               b = W_TYPE_SIZE - bm;
1007
1008               d1 = (d1 << bm) | (d0 >> b);
1009               d0 = d0 << bm;
1010               n2 = n1 >> b;
1011               n1 = (n1 << bm) | (n0 >> b);
1012               n0 = n0 << bm;
1013
1014               udiv_qrnnd (q0, n1, n2, n1, d1);
1015               umul_ppmm (m1, m0, q0, d0);
1016
1017               if (m1 > n1 || (m1 == n1 && m0 > n0))
1018                 {
1019                   q0--;
1020                   sub_ddmmss (m1, m0, m1, m0, d1, d0);
1021                 }
1022
1023               q1 = 0;
1024
1025               /* Remainder in (n1n0 - m1m0) >> bm.  */
1026               if (rp != 0)
1027                 {
1028                   sub_ddmmss (n1, n0, n1, n0, m1, m0);
1029                   rr.s.low = (n1 << b) | (n0 >> bm);
1030                   rr.s.high = n1 >> bm;
1031                   *rp = rr.ll;
1032                 }
1033             }
1034         }
1035     }
1036
1037   ww.s.low = q0;
1038   ww.s.high = q1;
1039   return ww.ll;
1040 }
1041 #endif
1042
1043 #ifdef L_divdi3
1044 DWtype
1045 __divdi3 (DWtype u, DWtype v)
1046 {
1047   word_type c = 0;
1048   DWunion uu, vv;
1049   DWtype w;
1050
1051   uu.ll = u;
1052   vv.ll = v;
1053
1054   if (uu.s.high < 0)
1055     c = ~c,
1056     uu.ll = -uu.ll;
1057   if (vv.s.high < 0)
1058     c = ~c,
1059     vv.ll = -vv.ll;
1060
1061   w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
1062   if (c)
1063     w = -w;
1064
1065   return w;
1066 }
1067 #endif
1068
1069 #ifdef L_moddi3
1070 DWtype
1071 __moddi3 (DWtype u, DWtype v)
1072 {
1073   word_type c = 0;
1074   DWunion uu, vv;
1075   DWtype w;
1076
1077   uu.ll = u;
1078   vv.ll = v;
1079
1080   if (uu.s.high < 0)
1081     c = ~c,
1082     uu.ll = -uu.ll;
1083   if (vv.s.high < 0)
1084     vv.ll = -vv.ll;
1085
1086   (void) __udivmoddi4 (uu.ll, vv.ll, &w);
1087   if (c)
1088     w = -w;
1089
1090   return w;
1091 }
1092 #endif
1093
1094 #ifdef L_umoddi3
1095 UDWtype
1096 __umoddi3 (UDWtype u, UDWtype v)
1097 {
1098   UDWtype w;
1099
1100   (void) __udivmoddi4 (u, v, &w);
1101
1102   return w;
1103 }
1104 #endif
1105
1106 #ifdef L_udivdi3
1107 UDWtype
1108 __udivdi3 (UDWtype n, UDWtype d)
1109 {
1110   return __udivmoddi4 (n, d, (UDWtype *) 0);
1111 }
1112 #endif
1113 \f
1114 #ifdef L_cmpdi2
1115 word_type
1116 __cmpdi2 (DWtype a, DWtype b)
1117 {
1118   DWunion au, bu;
1119
1120   au.ll = a, bu.ll = b;
1121
1122   if (au.s.high < bu.s.high)
1123     return 0;
1124   else if (au.s.high > bu.s.high)
1125     return 2;
1126   if ((UWtype) au.s.low < (UWtype) bu.s.low)
1127     return 0;
1128   else if ((UWtype) au.s.low > (UWtype) bu.s.low)
1129     return 2;
1130   return 1;
1131 }
1132 #endif
1133
1134 #ifdef L_ucmpdi2
1135 word_type
1136 __ucmpdi2 (DWtype a, DWtype b)
1137 {
1138   DWunion au, bu;
1139
1140   au.ll = a, bu.ll = b;
1141
1142   if ((UWtype) au.s.high < (UWtype) bu.s.high)
1143     return 0;
1144   else if ((UWtype) au.s.high > (UWtype) bu.s.high)
1145     return 2;
1146   if ((UWtype) au.s.low < (UWtype) bu.s.low)
1147     return 0;
1148   else if ((UWtype) au.s.low > (UWtype) bu.s.low)
1149     return 2;
1150   return 1;
1151 }
1152 #endif
1153 \f
1154 #if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
1155 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1156 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1157
1158 DWtype
1159 __fixunstfDI (TFtype a)
1160 {
1161   TFtype b;
1162   UDWtype v;
1163
1164   if (a < 0)
1165     return 0;
1166
1167   /* Compute high word of result, as a flonum.  */
1168   b = (a / HIGH_WORD_COEFF);
1169   /* Convert that to fixed (but not to DWtype!),
1170      and shift it into the high word.  */
1171   v = (UWtype) b;
1172   v <<= WORD_SIZE;
1173   /* Remove high part from the TFtype, leaving the low part as flonum.  */
1174   a -= (TFtype)v;
1175   /* Convert that to fixed (but not to DWtype!) and add it in.
1176      Sometimes A comes out negative.  This is significant, since
1177      A has more bits than a long int does.  */
1178   if (a < 0)
1179     v -= (UWtype) (- a);
1180   else
1181     v += (UWtype) a;
1182   return v;
1183 }
1184 #endif
1185
1186 #if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
1187 DWtype
1188 __fixtfdi (TFtype a)
1189 {
1190   if (a < 0)
1191     return - __fixunstfDI (-a);
1192   return __fixunstfDI (a);
1193 }
1194 #endif
1195
1196 #if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
1197 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1198 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1199
1200 DWtype
1201 __fixunsxfDI (XFtype a)
1202 {
1203   XFtype b;
1204   UDWtype v;
1205
1206   if (a < 0)
1207     return 0;
1208
1209   /* Compute high word of result, as a flonum.  */
1210   b = (a / HIGH_WORD_COEFF);
1211   /* Convert that to fixed (but not to DWtype!),
1212      and shift it into the high word.  */
1213   v = (UWtype) b;
1214   v <<= WORD_SIZE;
1215   /* Remove high part from the XFtype, leaving the low part as flonum.  */
1216   a -= (XFtype)v;
1217   /* Convert that to fixed (but not to DWtype!) and add it in.
1218      Sometimes A comes out negative.  This is significant, since
1219      A has more bits than a long int does.  */
1220   if (a < 0)
1221     v -= (UWtype) (- a);
1222   else
1223     v += (UWtype) a;
1224   return v;
1225 }
1226 #endif
1227
1228 #if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
1229 DWtype
1230 __fixxfdi (XFtype a)
1231 {
1232   if (a < 0)
1233     return - __fixunsxfDI (-a);
1234   return __fixunsxfDI (a);
1235 }
1236 #endif
1237
1238 #ifdef L_fixunsdfdi
1239 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1240 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1241
1242 DWtype
1243 __fixunsdfDI (DFtype a)
1244 {
1245   UWtype hi, lo;
1246
1247   /* Get high part of result.  The division here will just moves the radix
1248      point and will not cause any rounding.  Then the conversion to integral
1249      type chops result as desired.  */
1250   hi = a / HIGH_WORD_COEFF;
1251
1252   /* Get low part of result.  Convert `hi' to floating type and scale it back,
1253      then subtract this from the number being converted.  This leaves the low
1254      part.  Convert that to integral type.  */
1255   lo = (a - ((DFtype) hi) * HIGH_WORD_COEFF);
1256
1257   /* Assemble result from the two parts.  */
1258   return ((UDWtype) hi << WORD_SIZE) | lo;
1259 }
1260 #endif
1261
1262 #ifdef L_fixdfdi
1263 DWtype
1264 __fixdfdi (DFtype a)
1265 {
1266   if (a < 0)
1267     return - __fixunsdfDI (-a);
1268   return __fixunsdfDI (a);
1269 }
1270 #endif
1271
1272 #ifdef L_fixunssfdi
1273 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1274 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1275
1276 DWtype
1277 __fixunssfDI (SFtype original_a)
1278 {
1279   /* Convert the SFtype to a DFtype, because that is surely not going
1280      to lose any bits.  Some day someone else can write a faster version
1281      that avoids converting to DFtype, and verify it really works right.  */
1282   DFtype a = original_a;
1283   UWtype hi, lo;
1284
1285   /* Get high part of result.  The division here will just moves the radix
1286      point and will not cause any rounding.  Then the conversion to integral
1287      type chops result as desired.  */
1288   hi = a / HIGH_WORD_COEFF;
1289
1290   /* Get low part of result.  Convert `hi' to floating type and scale it back,
1291      then subtract this from the number being converted.  This leaves the low
1292      part.  Convert that to integral type.  */
1293   lo = (a - ((DFtype) hi) * HIGH_WORD_COEFF);
1294
1295   /* Assemble result from the two parts.  */
1296   return ((UDWtype) hi << WORD_SIZE) | lo;
1297 }
1298 #endif
1299
1300 #ifdef L_fixsfdi
1301 DWtype
1302 __fixsfdi (SFtype a)
1303 {
1304   if (a < 0)
1305     return - __fixunssfDI (-a);
1306   return __fixunssfDI (a);
1307 }
1308 #endif
1309
1310 #if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
1311 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1312 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1313 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1314
1315 XFtype
1316 __floatdixf (DWtype u)
1317 {
1318   XFtype d;
1319
1320   d = (Wtype) (u >> WORD_SIZE);
1321   d *= HIGH_HALFWORD_COEFF;
1322   d *= HIGH_HALFWORD_COEFF;
1323   d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1324
1325   return d;
1326 }
1327 #endif
1328
1329 #if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
1330 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1331 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1332 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1333
1334 TFtype
1335 __floatditf (DWtype u)
1336 {
1337   TFtype d;
1338
1339   d = (Wtype) (u >> WORD_SIZE);
1340   d *= HIGH_HALFWORD_COEFF;
1341   d *= HIGH_HALFWORD_COEFF;
1342   d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1343
1344   return d;
1345 }
1346 #endif
1347
1348 #ifdef L_floatdidf
1349 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1350 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1351 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1352
1353 DFtype
1354 __floatdidf (DWtype u)
1355 {
1356   DFtype d;
1357
1358   d = (Wtype) (u >> WORD_SIZE);
1359   d *= HIGH_HALFWORD_COEFF;
1360   d *= HIGH_HALFWORD_COEFF;
1361   d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1362
1363   return d;
1364 }
1365 #endif
1366
1367 #ifdef L_floatdisf
1368 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1369 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1370 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1371
1372 #define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT)
1373 #define DF_SIZE DBL_MANT_DIG
1374 #define SF_SIZE FLT_MANT_DIG
1375
1376 SFtype
1377 __floatdisf (DWtype u)
1378 {
1379   /* Do the calculation in DFmode
1380      so that we don't lose any of the precision of the high word
1381      while multiplying it.  */
1382   DFtype f;
1383
1384   /* Protect against double-rounding error.
1385      Represent any low-order bits, that might be truncated in DFmode,
1386      by a bit that won't be lost.  The bit can go in anywhere below the
1387      rounding position of the SFmode.  A fixed mask and bit position
1388      handles all usual configurations.  It doesn't handle the case
1389      of 128-bit DImode, however.  */
1390   if (DF_SIZE < DI_SIZE
1391       && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1392     {
1393 #define REP_BIT ((UDWtype) 1 << (DI_SIZE - DF_SIZE))
1394       if (! (- ((DWtype) 1 << DF_SIZE) < u
1395              && u < ((DWtype) 1 << DF_SIZE)))
1396         {
1397           if ((UDWtype) u & (REP_BIT - 1))
1398             {
1399               u &= ~ (REP_BIT - 1);
1400               u |= REP_BIT;
1401             }
1402         }
1403     }
1404   f = (Wtype) (u >> WORD_SIZE);
1405   f *= HIGH_HALFWORD_COEFF;
1406   f *= HIGH_HALFWORD_COEFF;
1407   f += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1408
1409   return (SFtype) f;
1410 }
1411 #endif
1412
1413 #if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
1414 /* Reenable the normal types, in case limits.h needs them.  */
1415 #undef char
1416 #undef short
1417 #undef int
1418 #undef long
1419 #undef unsigned
1420 #undef float
1421 #undef double
1422 #undef MIN
1423 #undef MAX
1424 #include <limits.h>
1425
1426 UWtype
1427 __fixunsxfSI (XFtype a)
1428 {
1429   if (a >= - (DFtype) Wtype_MIN)
1430     return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1431   return (Wtype) a;
1432 }
1433 #endif
1434
1435 #ifdef L_fixunsdfsi
1436 /* Reenable the normal types, in case limits.h needs them.  */
1437 #undef char
1438 #undef short
1439 #undef int
1440 #undef long
1441 #undef unsigned
1442 #undef float
1443 #undef double
1444 #undef MIN
1445 #undef MAX
1446 #include <limits.h>
1447
1448 UWtype
1449 __fixunsdfSI (DFtype a)
1450 {
1451   if (a >= - (DFtype) Wtype_MIN)
1452     return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1453   return (Wtype) a;
1454 }
1455 #endif
1456
1457 #ifdef L_fixunssfsi
1458 /* Reenable the normal types, in case limits.h needs them.  */
1459 #undef char
1460 #undef short
1461 #undef int
1462 #undef long
1463 #undef unsigned
1464 #undef float
1465 #undef double
1466 #undef MIN
1467 #undef MAX
1468 #include <limits.h>
1469
1470 UWtype
1471 __fixunssfSI (SFtype a)
1472 {
1473   if (a >= - (SFtype) Wtype_MIN)
1474     return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1475   return (Wtype) a;
1476 }
1477 #endif
1478 \f
1479 /* From here on down, the routines use normal data types.  */
1480
1481 #define SItype bogus_type
1482 #define USItype bogus_type
1483 #define DItype bogus_type
1484 #define UDItype bogus_type
1485 #define SFtype bogus_type
1486 #define DFtype bogus_type
1487 #undef Wtype
1488 #undef UWtype
1489 #undef HWtype
1490 #undef UHWtype
1491 #undef DWtype
1492 #undef UDWtype
1493
1494 #undef char
1495 #undef short
1496 #undef int
1497 #undef long
1498 #undef unsigned
1499 #undef float
1500 #undef double
1501 \f
1502 #ifdef L__gcc_bcmp
1503
1504 /* Like bcmp except the sign is meaningful.
1505    Result is negative if S1 is less than S2,
1506    positive if S1 is greater, 0 if S1 and S2 are equal.  */
1507
1508 int
1509 __gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
1510 {
1511   while (size > 0)
1512     {
1513       unsigned char c1 = *s1++, c2 = *s2++;
1514       if (c1 != c2)
1515         return c1 - c2;
1516       size--;
1517     }
1518   return 0;
1519 }
1520
1521 #endif
1522 \f
1523 /* __eprintf used to be used by GCC's private version of <assert.h>.
1524    We no longer provide that header, but this routine remains in libgcc.a
1525    for binary backward compatibility.  Note that it is not included in
1526    the shared version of libgcc.  */
1527 #ifdef L_eprintf
1528 #ifndef inhibit_libc
1529
1530 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1531 #include <stdio.h>
1532
1533 void
1534 __eprintf (const char *string, const char *expression,
1535            unsigned int line, const char *filename)
1536 {
1537   fprintf (stderr, string, expression, line, filename);
1538   fflush (stderr);
1539   abort ();
1540 }
1541
1542 #endif
1543 #endif
1544
1545 \f
1546 #ifdef L_clear_cache
1547 /* Clear part of an instruction cache.  */
1548
1549 void
1550 __clear_cache (char *beg __attribute__((__unused__)),
1551                char *end __attribute__((__unused__)))
1552 {
1553 #ifdef CLEAR_INSN_CACHE
1554   CLEAR_INSN_CACHE (beg, end);
1555 #endif /* CLEAR_INSN_CACHE */
1556 }
1557
1558 #endif /* L_clear_cache */
1559 \f
1560 #ifdef L_trampoline
1561
1562 /* Jump to a trampoline, loading the static chain address.  */
1563
1564 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
1565
1566 long
1567 getpagesize (void)
1568 {
1569 #ifdef _ALPHA_
1570   return 8192;
1571 #else
1572   return 4096;
1573 #endif
1574 }
1575
1576 #ifdef __i386__
1577 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
1578 #endif
1579
1580 int
1581 mprotect (char *addr, int len, int prot)
1582 {
1583   int np, op;
1584
1585   if (prot == 7)
1586     np = 0x40;
1587   else if (prot == 5)
1588     np = 0x20;
1589   else if (prot == 4)
1590     np = 0x10;
1591   else if (prot == 3)
1592     np = 0x04;
1593   else if (prot == 1)
1594     np = 0x02;
1595   else if (prot == 0)
1596     np = 0x01;
1597
1598   if (VirtualProtect (addr, len, np, &op))
1599     return 0;
1600   else
1601     return -1;
1602 }
1603
1604 #endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
1605
1606 #ifdef TRANSFER_FROM_TRAMPOLINE
1607 TRANSFER_FROM_TRAMPOLINE
1608 #endif
1609 #endif /* L_trampoline */
1610 \f
1611 #ifndef __CYGWIN__
1612 #ifdef L__main
1613
1614 #include "gbl-ctors.h"
1615 /* Some systems use __main in a way incompatible with its use in gcc, in these
1616    cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
1617    give the same symbol without quotes for an alternative entry point.  You
1618    must define both, or neither.  */
1619 #ifndef NAME__MAIN
1620 #define NAME__MAIN "__main"
1621 #define SYMBOL__MAIN __main
1622 #endif
1623
1624 #ifdef INIT_SECTION_ASM_OP
1625 #undef HAS_INIT_SECTION
1626 #define HAS_INIT_SECTION
1627 #endif
1628
1629 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
1630
1631 /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
1632    code to run constructors.  In that case, we need to handle EH here, too.  */
1633
1634 #ifdef EH_FRAME_SECTION_NAME
1635 #include "unwind-dw2-fde.h"
1636 extern unsigned char __EH_FRAME_BEGIN__[];
1637 #endif
1638
1639 /* Run all the global destructors on exit from the program.  */
1640
1641 void
1642 __do_global_dtors (void)
1643 {
1644 #ifdef DO_GLOBAL_DTORS_BODY
1645   DO_GLOBAL_DTORS_BODY;
1646 #else
1647   static func_ptr *p = __DTOR_LIST__ + 1;
1648   while (*p)
1649     {
1650       p++;
1651       (*(p-1)) ();
1652     }
1653 #endif
1654 #if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION)
1655   {
1656     static int completed = 0;
1657     if (! completed)
1658       {
1659         completed = 1;
1660         __deregister_frame_info (__EH_FRAME_BEGIN__);
1661       }
1662   }
1663 #endif
1664 }
1665 #endif
1666
1667 #ifndef HAS_INIT_SECTION
1668 /* Run all the global constructors on entry to the program.  */
1669
1670 void
1671 __do_global_ctors (void)
1672 {
1673 #ifdef EH_FRAME_SECTION_NAME
1674   {
1675     static struct object object;
1676     __register_frame_info (__EH_FRAME_BEGIN__, &object);
1677   }
1678 #endif
1679   DO_GLOBAL_CTORS_BODY;
1680   atexit (__do_global_dtors);
1681 }
1682 #endif /* no HAS_INIT_SECTION */
1683
1684 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
1685 /* Subroutine called automatically by `main'.
1686    Compiling a global function named `main'
1687    produces an automatic call to this function at the beginning.
1688
1689    For many systems, this routine calls __do_global_ctors.
1690    For systems which support a .init section we use the .init section
1691    to run __do_global_ctors, so we need not do anything here.  */
1692
1693 void
1694 SYMBOL__MAIN ()
1695 {
1696   /* Support recursive calls to `main': run initializers just once.  */
1697   static int initialized;
1698   if (! initialized)
1699     {
1700       initialized = 1;
1701       __do_global_ctors ();
1702     }
1703 }
1704 #endif /* no HAS_INIT_SECTION or INVOKE__main */
1705
1706 #endif /* L__main */
1707 #endif /* __CYGWIN__ */
1708 \f
1709 #ifdef L_ctors
1710
1711 #include "gbl-ctors.h"
1712
1713 /* Provide default definitions for the lists of constructors and
1714    destructors, so that we don't get linker errors.  These symbols are
1715    intentionally bss symbols, so that gld and/or collect will provide
1716    the right values.  */
1717
1718 /* We declare the lists here with two elements each,
1719    so that they are valid empty lists if no other definition is loaded.
1720
1721    If we are using the old "set" extensions to have the gnu linker
1722    collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
1723    must be in the bss/common section.
1724
1725    Long term no port should use those extensions.  But many still do.  */
1726 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
1727 #if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2)
1728 func_ptr __CTOR_LIST__[2] = {0, 0};
1729 func_ptr __DTOR_LIST__[2] = {0, 0};
1730 #else
1731 func_ptr __CTOR_LIST__[2];
1732 func_ptr __DTOR_LIST__[2];
1733 #endif
1734 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1735 #endif /* L_ctors */
1736