OSDN Git Service

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