OSDN Git Service

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