OSDN Git Service

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