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