OSDN Git Service

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