OSDN Git Service

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