OSDN Git Service

* libgcc2.c (__subvdi3): Fix typo.
[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 ^= nx >> 2;
668   nx ^= nx >> 1;
669   return nx & 1;
670 }
671 #endif
672 \f
673 #ifdef L_paritydi2
674 #undef int
675 extern int __paritydi2 (UDItype x);
676 int
677 __paritydi2 (UDItype x)
678 {
679   UWtype nx = x ^ (x >> 32);
680   nx ^= nx >> 16;
681   nx ^= nx >> 8;
682   nx ^= nx >> 4;
683   nx ^= nx >> 2;
684   nx ^= nx >> 1;
685   return nx & 1;
686 }
687 #endif
688
689 #ifdef L_udivmoddi4
690
691 #if (defined (L_udivdi3) || defined (L_divdi3) || \
692      defined (L_umoddi3) || defined (L_moddi3))
693 static inline __attribute__ ((__always_inline__))
694 #endif
695 UDWtype
696 __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
697 {
698   DWunion ww;
699   DWunion nn, dd;
700   DWunion rr;
701   UWtype d0, d1, n0, n1, n2;
702   UWtype q0, q1;
703   UWtype b, bm;
704
705   nn.ll = n;
706   dd.ll = d;
707
708   d0 = dd.s.low;
709   d1 = dd.s.high;
710   n0 = nn.s.low;
711   n1 = nn.s.high;
712
713 #if !UDIV_NEEDS_NORMALIZATION
714   if (d1 == 0)
715     {
716       if (d0 > n1)
717         {
718           /* 0q = nn / 0D */
719
720           udiv_qrnnd (q0, n0, n1, n0, d0);
721           q1 = 0;
722
723           /* Remainder in n0.  */
724         }
725       else
726         {
727           /* qq = NN / 0d */
728
729           if (d0 == 0)
730             d0 = 1 / d0;        /* Divide intentionally by zero.  */
731
732           udiv_qrnnd (q1, n1, 0, n1, d0);
733           udiv_qrnnd (q0, n0, n1, n0, d0);
734
735           /* Remainder in n0.  */
736         }
737
738       if (rp != 0)
739         {
740           rr.s.low = n0;
741           rr.s.high = 0;
742           *rp = rr.ll;
743         }
744     }
745
746 #else /* UDIV_NEEDS_NORMALIZATION */
747
748   if (d1 == 0)
749     {
750       if (d0 > n1)
751         {
752           /* 0q = nn / 0D */
753
754           count_leading_zeros (bm, d0);
755
756           if (bm != 0)
757             {
758               /* Normalize, i.e. make the most significant bit of the
759                  denominator set.  */
760
761               d0 = d0 << bm;
762               n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
763               n0 = n0 << bm;
764             }
765
766           udiv_qrnnd (q0, n0, n1, n0, d0);
767           q1 = 0;
768
769           /* Remainder in n0 >> bm.  */
770         }
771       else
772         {
773           /* qq = NN / 0d */
774
775           if (d0 == 0)
776             d0 = 1 / d0;        /* Divide intentionally by zero.  */
777
778           count_leading_zeros (bm, d0);
779
780           if (bm == 0)
781             {
782               /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
783                  conclude (the most significant bit of n1 is set) /\ (the
784                  leading quotient digit q1 = 1).
785
786                  This special case is necessary, not an optimization.
787                  (Shifts counts of W_TYPE_SIZE are undefined.)  */
788
789               n1 -= d0;
790               q1 = 1;
791             }
792           else
793             {
794               /* Normalize.  */
795
796               b = W_TYPE_SIZE - bm;
797
798               d0 = d0 << bm;
799               n2 = n1 >> b;
800               n1 = (n1 << bm) | (n0 >> b);
801               n0 = n0 << bm;
802
803               udiv_qrnnd (q1, n1, n2, n1, d0);
804             }
805
806           /* n1 != d0...  */
807
808           udiv_qrnnd (q0, n0, n1, n0, d0);
809
810           /* Remainder in n0 >> bm.  */
811         }
812
813       if (rp != 0)
814         {
815           rr.s.low = n0 >> bm;
816           rr.s.high = 0;
817           *rp = rr.ll;
818         }
819     }
820 #endif /* UDIV_NEEDS_NORMALIZATION */
821
822   else
823     {
824       if (d1 > n1)
825         {
826           /* 00 = nn / DD */
827
828           q0 = 0;
829           q1 = 0;
830
831           /* Remainder in n1n0.  */
832           if (rp != 0)
833             {
834               rr.s.low = n0;
835               rr.s.high = n1;
836               *rp = rr.ll;
837             }
838         }
839       else
840         {
841           /* 0q = NN / dd */
842
843           count_leading_zeros (bm, d1);
844           if (bm == 0)
845             {
846               /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
847                  conclude (the most significant bit of n1 is set) /\ (the
848                  quotient digit q0 = 0 or 1).
849
850                  This special case is necessary, not an optimization.  */
851
852               /* The condition on the next line takes advantage of that
853                  n1 >= d1 (true due to program flow).  */
854               if (n1 > d1 || n0 >= d0)
855                 {
856                   q0 = 1;
857                   sub_ddmmss (n1, n0, n1, n0, d1, d0);
858                 }
859               else
860                 q0 = 0;
861
862               q1 = 0;
863
864               if (rp != 0)
865                 {
866                   rr.s.low = n0;
867                   rr.s.high = n1;
868                   *rp = rr.ll;
869                 }
870             }
871           else
872             {
873               UWtype m1, m0;
874               /* Normalize.  */
875
876               b = W_TYPE_SIZE - bm;
877
878               d1 = (d1 << bm) | (d0 >> b);
879               d0 = d0 << bm;
880               n2 = n1 >> b;
881               n1 = (n1 << bm) | (n0 >> b);
882               n0 = n0 << bm;
883
884               udiv_qrnnd (q0, n1, n2, n1, d1);
885               umul_ppmm (m1, m0, q0, d0);
886
887               if (m1 > n1 || (m1 == n1 && m0 > n0))
888                 {
889                   q0--;
890                   sub_ddmmss (m1, m0, m1, m0, d1, d0);
891                 }
892
893               q1 = 0;
894
895               /* Remainder in (n1n0 - m1m0) >> bm.  */
896               if (rp != 0)
897                 {
898                   sub_ddmmss (n1, n0, n1, n0, m1, m0);
899                   rr.s.low = (n1 << b) | (n0 >> bm);
900                   rr.s.high = n1 >> bm;
901                   *rp = rr.ll;
902                 }
903             }
904         }
905     }
906
907   ww.s.low = q0;
908   ww.s.high = q1;
909   return ww.ll;
910 }
911 #endif
912
913 #ifdef L_divdi3
914 DWtype
915 __divdi3 (DWtype u, DWtype v)
916 {
917   word_type c = 0;
918   DWunion uu, vv;
919   DWtype w;
920
921   uu.ll = u;
922   vv.ll = v;
923
924   if (uu.s.high < 0)
925     c = ~c,
926     uu.ll = -uu.ll;
927   if (vv.s.high < 0)
928     c = ~c,
929     vv.ll = -vv.ll;
930
931   w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
932   if (c)
933     w = -w;
934
935   return w;
936 }
937 #endif
938
939 #ifdef L_moddi3
940 DWtype
941 __moddi3 (DWtype u, DWtype v)
942 {
943   word_type c = 0;
944   DWunion uu, vv;
945   DWtype w;
946
947   uu.ll = u;
948   vv.ll = v;
949
950   if (uu.s.high < 0)
951     c = ~c,
952     uu.ll = -uu.ll;
953   if (vv.s.high < 0)
954     vv.ll = -vv.ll;
955
956   (void) __udivmoddi4 (uu.ll, vv.ll, &w);
957   if (c)
958     w = -w;
959
960   return w;
961 }
962 #endif
963
964 #ifdef L_umoddi3
965 UDWtype
966 __umoddi3 (UDWtype u, UDWtype v)
967 {
968   UDWtype w;
969
970   (void) __udivmoddi4 (u, v, &w);
971
972   return w;
973 }
974 #endif
975
976 #ifdef L_udivdi3
977 UDWtype
978 __udivdi3 (UDWtype n, UDWtype d)
979 {
980   return __udivmoddi4 (n, d, (UDWtype *) 0);
981 }
982 #endif
983 \f
984 #ifdef L_cmpdi2
985 word_type
986 __cmpdi2 (DWtype a, DWtype b)
987 {
988   DWunion au, bu;
989
990   au.ll = a, bu.ll = b;
991
992   if (au.s.high < bu.s.high)
993     return 0;
994   else if (au.s.high > bu.s.high)
995     return 2;
996   if ((UWtype) au.s.low < (UWtype) bu.s.low)
997     return 0;
998   else if ((UWtype) au.s.low > (UWtype) bu.s.low)
999     return 2;
1000   return 1;
1001 }
1002 #endif
1003
1004 #ifdef L_ucmpdi2
1005 word_type
1006 __ucmpdi2 (DWtype a, DWtype b)
1007 {
1008   DWunion au, bu;
1009
1010   au.ll = a, bu.ll = b;
1011
1012   if ((UWtype) au.s.high < (UWtype) bu.s.high)
1013     return 0;
1014   else if ((UWtype) au.s.high > (UWtype) bu.s.high)
1015     return 2;
1016   if ((UWtype) au.s.low < (UWtype) bu.s.low)
1017     return 0;
1018   else if ((UWtype) au.s.low > (UWtype) bu.s.low)
1019     return 2;
1020   return 1;
1021 }
1022 #endif
1023 \f
1024 #if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
1025 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1026 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1027
1028 DWtype
1029 __fixunstfDI (TFtype a)
1030 {
1031   TFtype b;
1032   UDWtype v;
1033
1034   if (a < 0)
1035     return 0;
1036
1037   /* Compute high word of result, as a flonum.  */
1038   b = (a / HIGH_WORD_COEFF);
1039   /* Convert that to fixed (but not to DWtype!),
1040      and shift it into the high word.  */
1041   v = (UWtype) b;
1042   v <<= WORD_SIZE;
1043   /* Remove high part from the TFtype, leaving the low part as flonum.  */
1044   a -= (TFtype)v;
1045   /* Convert that to fixed (but not to DWtype!) and add it in.
1046      Sometimes A comes out negative.  This is significant, since
1047      A has more bits than a long int does.  */
1048   if (a < 0)
1049     v -= (UWtype) (- a);
1050   else
1051     v += (UWtype) a;
1052   return v;
1053 }
1054 #endif
1055
1056 #if defined(L_fixtfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
1057 DWtype
1058 __fixtfdi (TFtype a)
1059 {
1060   if (a < 0)
1061     return - __fixunstfDI (-a);
1062   return __fixunstfDI (a);
1063 }
1064 #endif
1065
1066 #if defined(L_fixunsxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
1067 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1068 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1069
1070 DWtype
1071 __fixunsxfDI (XFtype a)
1072 {
1073   XFtype b;
1074   UDWtype v;
1075
1076   if (a < 0)
1077     return 0;
1078
1079   /* Compute high word of result, as a flonum.  */
1080   b = (a / HIGH_WORD_COEFF);
1081   /* Convert that to fixed (but not to DWtype!),
1082      and shift it into the high word.  */
1083   v = (UWtype) b;
1084   v <<= WORD_SIZE;
1085   /* Remove high part from the XFtype, leaving the low part as flonum.  */
1086   a -= (XFtype)v;
1087   /* Convert that to fixed (but not to DWtype!) and add it in.
1088      Sometimes A comes out negative.  This is significant, since
1089      A has more bits than a long int does.  */
1090   if (a < 0)
1091     v -= (UWtype) (- a);
1092   else
1093     v += (UWtype) a;
1094   return v;
1095 }
1096 #endif
1097
1098 #if defined(L_fixxfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
1099 DWtype
1100 __fixxfdi (XFtype a)
1101 {
1102   if (a < 0)
1103     return - __fixunsxfDI (-a);
1104   return __fixunsxfDI (a);
1105 }
1106 #endif
1107
1108 #ifdef L_fixunsdfdi
1109 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1110 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1111
1112 DWtype
1113 __fixunsdfDI (DFtype a)
1114 {
1115   UWtype hi, lo;
1116
1117   /* Get high part of result.  The division here will just moves the radix
1118      point and will not cause any rounding.  Then the conversion to integral
1119      type chops result as desired.  */
1120   hi = a / HIGH_WORD_COEFF;
1121
1122   /* Get low part of result.  Convert `hi' to floating type and scale it back,
1123      then subtract this from the number being converted.  This leaves the low
1124      part.  Convert that to integral type.  */
1125   lo = (a - ((DFtype) hi) * HIGH_WORD_COEFF);
1126
1127   /* Assemble result from the two parts.  */
1128   return ((UDWtype) hi << WORD_SIZE) | lo;
1129 }
1130 #endif
1131
1132 #ifdef L_fixdfdi
1133 DWtype
1134 __fixdfdi (DFtype a)
1135 {
1136   if (a < 0)
1137     return - __fixunsdfDI (-a);
1138   return __fixunsdfDI (a);
1139 }
1140 #endif
1141
1142 #ifdef L_fixunssfdi
1143 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1144 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1145
1146 DWtype
1147 __fixunssfDI (SFtype original_a)
1148 {
1149   /* Convert the SFtype to a DFtype, because that is surely not going
1150      to lose any bits.  Some day someone else can write a faster version
1151      that avoids converting to DFtype, and verify it really works right.  */
1152   DFtype a = original_a;
1153   UWtype hi, lo;
1154
1155   /* Get high part of result.  The division here will just moves the radix
1156      point and will not cause any rounding.  Then the conversion to integral
1157      type chops result as desired.  */
1158   hi = a / HIGH_WORD_COEFF;
1159
1160   /* Get low part of result.  Convert `hi' to floating type and scale it back,
1161      then subtract this from the number being converted.  This leaves the low
1162      part.  Convert that to integral type.  */
1163   lo = (a - ((DFtype) hi) * HIGH_WORD_COEFF);
1164
1165   /* Assemble result from the two parts.  */
1166   return ((UDWtype) hi << WORD_SIZE) | lo;
1167 }
1168 #endif
1169
1170 #ifdef L_fixsfdi
1171 DWtype
1172 __fixsfdi (SFtype a)
1173 {
1174   if (a < 0)
1175     return - __fixunssfDI (-a);
1176   return __fixunssfDI (a);
1177 }
1178 #endif
1179
1180 #if defined(L_floatdixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
1181 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1182 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1183 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1184
1185 XFtype
1186 __floatdixf (DWtype u)
1187 {
1188   XFtype d;
1189
1190   d = (Wtype) (u >> WORD_SIZE);
1191   d *= HIGH_HALFWORD_COEFF;
1192   d *= HIGH_HALFWORD_COEFF;
1193   d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1194
1195   return d;
1196 }
1197 #endif
1198
1199 #if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
1200 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1201 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1202 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1203
1204 TFtype
1205 __floatditf (DWtype u)
1206 {
1207   TFtype d;
1208
1209   d = (Wtype) (u >> WORD_SIZE);
1210   d *= HIGH_HALFWORD_COEFF;
1211   d *= HIGH_HALFWORD_COEFF;
1212   d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1213
1214   return d;
1215 }
1216 #endif
1217
1218 #ifdef L_floatdidf
1219 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1220 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1221 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1222
1223 DFtype
1224 __floatdidf (DWtype u)
1225 {
1226   DFtype d;
1227
1228   d = (Wtype) (u >> WORD_SIZE);
1229   d *= HIGH_HALFWORD_COEFF;
1230   d *= HIGH_HALFWORD_COEFF;
1231   d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1232
1233   return d;
1234 }
1235 #endif
1236
1237 #ifdef L_floatdisf
1238 #define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
1239 #define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
1240 #define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
1241
1242 #define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT)
1243 #define DF_SIZE DBL_MANT_DIG
1244 #define SF_SIZE FLT_MANT_DIG
1245
1246 SFtype
1247 __floatdisf (DWtype u)
1248 {
1249   /* Do the calculation in DFmode
1250      so that we don't lose any of the precision of the high word
1251      while multiplying it.  */
1252   DFtype f;
1253
1254   /* Protect against double-rounding error.
1255      Represent any low-order bits, that might be truncated in DFmode,
1256      by a bit that won't be lost.  The bit can go in anywhere below the
1257      rounding position of the SFmode.  A fixed mask and bit position
1258      handles all usual configurations.  It doesn't handle the case
1259      of 128-bit DImode, however.  */
1260   if (DF_SIZE < DI_SIZE
1261       && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
1262     {
1263 #define REP_BIT ((UDWtype) 1 << (DI_SIZE - DF_SIZE))
1264       if (! (- ((DWtype) 1 << DF_SIZE) < u
1265              && u < ((DWtype) 1 << DF_SIZE)))
1266         {
1267           if ((UDWtype) u & (REP_BIT - 1))
1268             {
1269               u &= ~ (REP_BIT - 1);
1270               u |= REP_BIT;
1271             }
1272         }
1273     }
1274   f = (Wtype) (u >> WORD_SIZE);
1275   f *= HIGH_HALFWORD_COEFF;
1276   f *= HIGH_HALFWORD_COEFF;
1277   f += (UWtype) (u & (HIGH_WORD_COEFF - 1));
1278
1279   return (SFtype) f;
1280 }
1281 #endif
1282
1283 #if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
1284 /* Reenable the normal types, in case limits.h needs them.  */
1285 #undef char
1286 #undef short
1287 #undef int
1288 #undef long
1289 #undef unsigned
1290 #undef float
1291 #undef double
1292 #undef MIN
1293 #undef MAX
1294 #include <limits.h>
1295
1296 UWtype
1297 __fixunsxfSI (XFtype a)
1298 {
1299   if (a >= - (DFtype) Wtype_MIN)
1300     return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1301   return (Wtype) a;
1302 }
1303 #endif
1304
1305 #ifdef L_fixunsdfsi
1306 /* Reenable the normal types, in case limits.h needs them.  */
1307 #undef char
1308 #undef short
1309 #undef int
1310 #undef long
1311 #undef unsigned
1312 #undef float
1313 #undef double
1314 #undef MIN
1315 #undef MAX
1316 #include <limits.h>
1317
1318 UWtype
1319 __fixunsdfSI (DFtype a)
1320 {
1321   if (a >= - (DFtype) Wtype_MIN)
1322     return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1323   return (Wtype) a;
1324 }
1325 #endif
1326
1327 #ifdef L_fixunssfsi
1328 /* Reenable the normal types, in case limits.h needs them.  */
1329 #undef char
1330 #undef short
1331 #undef int
1332 #undef long
1333 #undef unsigned
1334 #undef float
1335 #undef double
1336 #undef MIN
1337 #undef MAX
1338 #include <limits.h>
1339
1340 UWtype
1341 __fixunssfSI (SFtype a)
1342 {
1343   if (a >= - (SFtype) Wtype_MIN)
1344     return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1345   return (Wtype) a;
1346 }
1347 #endif
1348 \f
1349 /* From here on down, the routines use normal data types.  */
1350
1351 #define SItype bogus_type
1352 #define USItype bogus_type
1353 #define DItype bogus_type
1354 #define UDItype bogus_type
1355 #define SFtype bogus_type
1356 #define DFtype bogus_type
1357 #undef Wtype
1358 #undef UWtype
1359 #undef HWtype
1360 #undef UHWtype
1361 #undef DWtype
1362 #undef UDWtype
1363
1364 #undef char
1365 #undef short
1366 #undef int
1367 #undef long
1368 #undef unsigned
1369 #undef float
1370 #undef double
1371 \f
1372 #ifdef L__gcc_bcmp
1373
1374 /* Like bcmp except the sign is meaningful.
1375    Result is negative if S1 is less than S2,
1376    positive if S1 is greater, 0 if S1 and S2 are equal.  */
1377
1378 int
1379 __gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
1380 {
1381   while (size > 0)
1382     {
1383       unsigned char c1 = *s1++, c2 = *s2++;
1384       if (c1 != c2)
1385         return c1 - c2;
1386       size--;
1387     }
1388   return 0;
1389 }
1390
1391 #endif
1392 \f
1393 /* __eprintf used to be used by GCC's private version of <assert.h>.
1394    We no longer provide that header, but this routine remains in libgcc.a
1395    for binary backward compatibility.  Note that it is not included in
1396    the shared version of libgcc.  */
1397 #ifdef L_eprintf
1398 #ifndef inhibit_libc
1399
1400 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
1401 #include <stdio.h>
1402
1403 void
1404 __eprintf (const char *string, const char *expression,
1405            unsigned int line, const char *filename)
1406 {
1407   fprintf (stderr, string, expression, line, filename);
1408   fflush (stderr);
1409   abort ();
1410 }
1411
1412 #endif
1413 #endif
1414
1415 \f
1416 #ifdef L_clear_cache
1417 /* Clear part of an instruction cache.  */
1418
1419 #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
1420
1421 void
1422 __clear_cache (char *beg __attribute__((__unused__)),
1423                char *end __attribute__((__unused__)))
1424 {
1425 #ifdef CLEAR_INSN_CACHE
1426   CLEAR_INSN_CACHE (beg, end);
1427 #else
1428 #ifdef INSN_CACHE_SIZE
1429   static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
1430   static int initialized;
1431   int offset;
1432   void *start_addr
1433   void *end_addr;
1434   typedef (*function_ptr) (void);
1435
1436 #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
1437   /* It's cheaper to clear the whole cache.
1438      Put in a series of jump instructions so that calling the beginning
1439      of the cache will clear the whole thing.  */
1440
1441   if (! initialized)
1442     {
1443       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1444                  & -INSN_CACHE_LINE_WIDTH);
1445       int end_ptr = ptr + INSN_CACHE_SIZE;
1446
1447       while (ptr < end_ptr)
1448         {
1449           *(INSTRUCTION_TYPE *)ptr
1450             = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
1451           ptr += INSN_CACHE_LINE_WIDTH;
1452         }
1453       *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
1454
1455       initialized = 1;
1456     }
1457
1458   /* Call the beginning of the sequence.  */
1459   (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1460                     & -INSN_CACHE_LINE_WIDTH))
1461    ());
1462
1463 #else /* Cache is large.  */
1464
1465   if (! initialized)
1466     {
1467       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
1468                  & -INSN_CACHE_LINE_WIDTH);
1469
1470       while (ptr < (int) array + sizeof array)
1471         {
1472           *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
1473           ptr += INSN_CACHE_LINE_WIDTH;
1474         }
1475
1476       initialized = 1;
1477     }
1478
1479   /* Find the location in array that occupies the same cache line as BEG.  */
1480
1481   offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
1482   start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
1483                  & -INSN_CACHE_PLANE_SIZE)
1484                 + offset);
1485
1486   /* Compute the cache alignment of the place to stop clearing.  */
1487 #if 0  /* This is not needed for gcc's purposes.  */
1488   /* If the block to clear is bigger than a cache plane,
1489      we clear the entire cache, and OFFSET is already correct.  */
1490   if (end < beg + INSN_CACHE_PLANE_SIZE)
1491 #endif
1492     offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
1493                & -INSN_CACHE_LINE_WIDTH)
1494               & (INSN_CACHE_PLANE_SIZE - 1));
1495
1496 #if INSN_CACHE_DEPTH > 1
1497   end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
1498   if (end_addr <= start_addr)
1499     end_addr += INSN_CACHE_PLANE_SIZE;
1500
1501   for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
1502     {
1503       int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
1504       int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
1505
1506       while (addr != stop)
1507         {
1508           /* Call the return instruction at ADDR.  */
1509           ((function_ptr) addr) ();
1510
1511           addr += INSN_CACHE_LINE_WIDTH;
1512         }
1513     }
1514 #else /* just one plane */
1515   do
1516     {
1517       /* Call the return instruction at START_ADDR.  */
1518       ((function_ptr) start_addr) ();
1519
1520       start_addr += INSN_CACHE_LINE_WIDTH;
1521     }
1522   while ((start_addr % INSN_CACHE_SIZE) != offset);
1523 #endif /* just one plane */
1524 #endif /* Cache is large */
1525 #endif /* Cache exists */
1526 #endif /* CLEAR_INSN_CACHE */
1527 }
1528
1529 #endif /* L_clear_cache */
1530 \f
1531 #ifdef L_trampoline
1532
1533 /* Jump to a trampoline, loading the static chain address.  */
1534
1535 #if defined(WINNT) && ! defined(__CYGWIN__) && ! defined (_UWIN)
1536
1537 long
1538 getpagesize (void)
1539 {
1540 #ifdef _ALPHA_
1541   return 8192;
1542 #else
1543   return 4096;
1544 #endif
1545 }
1546
1547 #ifdef __i386__
1548 extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall));
1549 #endif
1550
1551 int
1552 mprotect (char *addr, int len, int prot)
1553 {
1554   int np, op;
1555
1556   if (prot == 7)
1557     np = 0x40;
1558   else if (prot == 5)
1559     np = 0x20;
1560   else if (prot == 4)
1561     np = 0x10;
1562   else if (prot == 3)
1563     np = 0x04;
1564   else if (prot == 1)
1565     np = 0x02;
1566   else if (prot == 0)
1567     np = 0x01;
1568
1569   if (VirtualProtect (addr, len, np, &op))
1570     return 0;
1571   else
1572     return -1;
1573 }
1574
1575 #endif /* WINNT && ! __CYGWIN__ && ! _UWIN */
1576
1577 #ifdef TRANSFER_FROM_TRAMPOLINE
1578 TRANSFER_FROM_TRAMPOLINE
1579 #endif
1580
1581 #ifdef __sysV68__
1582
1583 #include <sys/signal.h>
1584 #include <errno.h>
1585
1586 /* Motorola forgot to put memctl.o in the libp version of libc881.a,
1587    so define it here, because we need it in __clear_insn_cache below */
1588 /* On older versions of this OS, no memctl or MCT_TEXT are defined;
1589    hence we enable this stuff only if MCT_TEXT is #define'd.  */
1590
1591 #ifdef MCT_TEXT
1592 asm("\n\
1593         global memctl\n\
1594 memctl:\n\
1595         movq &75,%d0\n\
1596         trap &0\n\
1597         bcc.b noerror\n\
1598         jmp cerror%\n\
1599 noerror:\n\
1600         movq &0,%d0\n\
1601         rts");
1602 #endif
1603
1604 /* Clear instruction cache so we can call trampolines on stack.
1605    This is called from FINALIZE_TRAMPOLINE in mot3300.h.  */
1606
1607 void
1608 __clear_insn_cache (void)
1609 {
1610 #ifdef MCT_TEXT
1611   int save_errno;
1612
1613   /* Preserve errno, because users would be surprised to have
1614   errno changing without explicitly calling any system-call.  */
1615   save_errno = errno;
1616
1617   /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache.
1618      No need to use an address derived from _start or %sp, as 0 works also.  */
1619   memctl(0, 4096, MCT_TEXT);
1620   errno = save_errno;
1621 #endif
1622 }
1623
1624 #endif /* __sysV68__ */
1625 #endif /* L_trampoline */
1626 \f
1627 #ifndef __CYGWIN__
1628 #ifdef L__main
1629
1630 #include "gbl-ctors.h"
1631 /* Some systems use __main in a way incompatible with its use in gcc, in these
1632    cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
1633    give the same symbol without quotes for an alternative entry point.  You
1634    must define both, or neither.  */
1635 #ifndef NAME__MAIN
1636 #define NAME__MAIN "__main"
1637 #define SYMBOL__MAIN __main
1638 #endif
1639
1640 #ifdef INIT_SECTION_ASM_OP
1641 #undef HAS_INIT_SECTION
1642 #define HAS_INIT_SECTION
1643 #endif
1644
1645 #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
1646
1647 /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
1648    code to run constructors.  In that case, we need to handle EH here, too.  */
1649
1650 #ifdef EH_FRAME_SECTION_NAME
1651 #include "unwind-dw2-fde.h"
1652 extern unsigned char __EH_FRAME_BEGIN__[];
1653 #endif
1654
1655 /* Run all the global destructors on exit from the program.  */
1656
1657 void
1658 __do_global_dtors (void)
1659 {
1660 #ifdef DO_GLOBAL_DTORS_BODY
1661   DO_GLOBAL_DTORS_BODY;
1662 #else
1663   static func_ptr *p = __DTOR_LIST__ + 1;
1664   while (*p)
1665     {
1666       p++;
1667       (*(p-1)) ();
1668     }
1669 #endif
1670 #if defined (EH_FRAME_SECTION_NAME) && !defined (HAS_INIT_SECTION)
1671   {
1672     static int completed = 0;
1673     if (! completed)
1674       {
1675         completed = 1;
1676         __deregister_frame_info (__EH_FRAME_BEGIN__);
1677       }
1678   }
1679 #endif
1680 }
1681 #endif
1682
1683 #ifndef HAS_INIT_SECTION
1684 /* Run all the global constructors on entry to the program.  */
1685
1686 void
1687 __do_global_ctors (void)
1688 {
1689 #ifdef EH_FRAME_SECTION_NAME
1690   {
1691     static struct object object;
1692     __register_frame_info (__EH_FRAME_BEGIN__, &object);
1693   }
1694 #endif
1695   DO_GLOBAL_CTORS_BODY;
1696   atexit (__do_global_dtors);
1697 }
1698 #endif /* no HAS_INIT_SECTION */
1699
1700 #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
1701 /* Subroutine called automatically by `main'.
1702    Compiling a global function named `main'
1703    produces an automatic call to this function at the beginning.
1704
1705    For many systems, this routine calls __do_global_ctors.
1706    For systems which support a .init section we use the .init section
1707    to run __do_global_ctors, so we need not do anything here.  */
1708
1709 void
1710 SYMBOL__MAIN ()
1711 {
1712   /* Support recursive calls to `main': run initializers just once.  */
1713   static int initialized;
1714   if (! initialized)
1715     {
1716       initialized = 1;
1717       __do_global_ctors ();
1718     }
1719 }
1720 #endif /* no HAS_INIT_SECTION or INVOKE__main */
1721
1722 #endif /* L__main */
1723 #endif /* __CYGWIN__ */
1724 \f
1725 #ifdef L_ctors
1726
1727 #include "gbl-ctors.h"
1728
1729 /* Provide default definitions for the lists of constructors and
1730    destructors, so that we don't get linker errors.  These symbols are
1731    intentionally bss symbols, so that gld and/or collect will provide
1732    the right values.  */
1733
1734 /* We declare the lists here with two elements each,
1735    so that they are valid empty lists if no other definition is loaded.
1736
1737    If we are using the old "set" extensions to have the gnu linker
1738    collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
1739    must be in the bss/common section.
1740
1741    Long term no port should use those extensions.  But many still do.  */
1742 #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
1743 #if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2)
1744 func_ptr __CTOR_LIST__[2] = {0, 0};
1745 func_ptr __DTOR_LIST__[2] = {0, 0};
1746 #else
1747 func_ptr __CTOR_LIST__[2];
1748 func_ptr __DTOR_LIST__[2];
1749 #endif
1750 #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
1751 #endif /* L_ctors */
1752 \f
1753 #ifdef L_exit
1754
1755 #include "gbl-ctors.h"
1756
1757 #ifdef NEED_ATEXIT
1758
1759 #ifndef ON_EXIT
1760
1761 # include <errno.h>
1762
1763 static func_ptr *atexit_chain = 0;
1764 static long atexit_chain_length = 0;
1765 static volatile long last_atexit_chain_slot = -1;
1766
1767 int
1768 atexit (func_ptr func)
1769 {
1770   if (++last_atexit_chain_slot == atexit_chain_length)
1771     {
1772       atexit_chain_length += 32;
1773       if (atexit_chain)
1774         atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
1775                                              * sizeof (func_ptr));
1776       else
1777         atexit_chain = (func_ptr *) malloc (atexit_chain_length
1778                                             * sizeof (func_ptr));
1779       if (! atexit_chain)
1780         {
1781           atexit_chain_length = 0;
1782           last_atexit_chain_slot = -1;
1783           errno = ENOMEM;
1784           return (-1);
1785         }
1786     }
1787   atexit_chain[last_atexit_chain_slot] = func;
1788   return (0);
1789 }
1790
1791 extern void _cleanup (void);
1792 extern void _exit (int) __attribute__ ((__noreturn__));
1793
1794 void
1795 exit (int status)
1796 {
1797   if (atexit_chain)
1798     {
1799       for ( ; last_atexit_chain_slot-- >= 0; )
1800         {
1801           (*atexit_chain[last_atexit_chain_slot + 1]) ();
1802           atexit_chain[last_atexit_chain_slot + 1] = 0;
1803         }
1804       free (atexit_chain);
1805       atexit_chain = 0;
1806     }
1807 #ifdef EXIT_BODY
1808   EXIT_BODY;
1809 #else
1810   _cleanup ();
1811 #endif
1812   _exit (status);
1813 }
1814
1815 #else /* ON_EXIT */
1816
1817 /* Simple; we just need a wrapper for ON_EXIT.  */
1818 int
1819 atexit (func_ptr func)
1820 {
1821   return ON_EXIT (func);
1822 }
1823
1824 #endif /* ON_EXIT */
1825 #endif /* NEED_ATEXIT */
1826
1827 #endif /* L_exit */