1*38fd1498Szrj /* More subroutines needed by GCC output code on some machines. */
2*38fd1498Szrj /* Compile this one with gcc. */
3*38fd1498Szrj /* Copyright (C) 1989-2018 Free Software Foundation, Inc.
4*38fd1498Szrj
5*38fd1498Szrj This file is part of GCC.
6*38fd1498Szrj
7*38fd1498Szrj GCC is free software; you can redistribute it and/or modify it under
8*38fd1498Szrj the terms of the GNU General Public License as published by the Free
9*38fd1498Szrj Software Foundation; either version 3, or (at your option) any later
10*38fd1498Szrj version.
11*38fd1498Szrj
12*38fd1498Szrj GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13*38fd1498Szrj WARRANTY; without even the implied warranty of MERCHANTABILITY or
14*38fd1498Szrj FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15*38fd1498Szrj for more details.
16*38fd1498Szrj
17*38fd1498Szrj Under Section 7 of GPL version 3, you are granted additional
18*38fd1498Szrj permissions described in the GCC Runtime Library Exception, version
19*38fd1498Szrj 3.1, as published by the Free Software Foundation.
20*38fd1498Szrj
21*38fd1498Szrj You should have received a copy of the GNU General Public License and
22*38fd1498Szrj a copy of the GCC Runtime Library Exception along with this program;
23*38fd1498Szrj see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24*38fd1498Szrj <http://www.gnu.org/licenses/>. */
25*38fd1498Szrj
26*38fd1498Szrj #include "tconfig.h"
27*38fd1498Szrj #include "tsystem.h"
28*38fd1498Szrj #include "coretypes.h"
29*38fd1498Szrj #include "tm.h"
30*38fd1498Szrj #include "libgcc_tm.h"
31*38fd1498Szrj
32*38fd1498Szrj #ifdef HAVE_GAS_HIDDEN
33*38fd1498Szrj #define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
34*38fd1498Szrj #else
35*38fd1498Szrj #define ATTRIBUTE_HIDDEN
36*38fd1498Szrj #endif
37*38fd1498Szrj
38*38fd1498Szrj /* Work out the largest "word" size that we can deal with on this target. */
39*38fd1498Szrj #if MIN_UNITS_PER_WORD > 4
40*38fd1498Szrj # define LIBGCC2_MAX_UNITS_PER_WORD 8
41*38fd1498Szrj #elif (MIN_UNITS_PER_WORD > 2 \
42*38fd1498Szrj || (MIN_UNITS_PER_WORD > 1 && __SIZEOF_LONG_LONG__ > 4))
43*38fd1498Szrj # define LIBGCC2_MAX_UNITS_PER_WORD 4
44*38fd1498Szrj #else
45*38fd1498Szrj # define LIBGCC2_MAX_UNITS_PER_WORD MIN_UNITS_PER_WORD
46*38fd1498Szrj #endif
47*38fd1498Szrj
48*38fd1498Szrj /* Work out what word size we are using for this compilation.
49*38fd1498Szrj The value can be set on the command line. */
50*38fd1498Szrj #ifndef LIBGCC2_UNITS_PER_WORD
51*38fd1498Szrj #define LIBGCC2_UNITS_PER_WORD LIBGCC2_MAX_UNITS_PER_WORD
52*38fd1498Szrj #endif
53*38fd1498Szrj
54*38fd1498Szrj #if LIBGCC2_UNITS_PER_WORD <= LIBGCC2_MAX_UNITS_PER_WORD
55*38fd1498Szrj
56*38fd1498Szrj #include "libgcc2.h"
57*38fd1498Szrj
58*38fd1498Szrj #ifdef DECLARE_LIBRARY_RENAMES
59*38fd1498Szrj DECLARE_LIBRARY_RENAMES
60*38fd1498Szrj #endif
61*38fd1498Szrj
62*38fd1498Szrj #if defined (L_negdi2)
63*38fd1498Szrj DWtype
__negdi2(DWtype u)64*38fd1498Szrj __negdi2 (DWtype u)
65*38fd1498Szrj {
66*38fd1498Szrj const DWunion uu = {.ll = u};
67*38fd1498Szrj const DWunion w = { {.low = -uu.s.low,
68*38fd1498Szrj .high = -uu.s.high - ((UWtype) -uu.s.low > 0) } };
69*38fd1498Szrj
70*38fd1498Szrj return w.ll;
71*38fd1498Szrj }
72*38fd1498Szrj #endif
73*38fd1498Szrj
74*38fd1498Szrj #ifdef L_addvsi3
75*38fd1498Szrj Wtype
__addvSI3(Wtype a,Wtype b)76*38fd1498Szrj __addvSI3 (Wtype a, Wtype b)
77*38fd1498Szrj {
78*38fd1498Szrj const Wtype w = (UWtype) a + (UWtype) b;
79*38fd1498Szrj
80*38fd1498Szrj if (b >= 0 ? w < a : w > a)
81*38fd1498Szrj abort ();
82*38fd1498Szrj
83*38fd1498Szrj return w;
84*38fd1498Szrj }
85*38fd1498Szrj #ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
86*38fd1498Szrj SItype
__addvsi3(SItype a,SItype b)87*38fd1498Szrj __addvsi3 (SItype a, SItype b)
88*38fd1498Szrj {
89*38fd1498Szrj const SItype w = (USItype) a + (USItype) b;
90*38fd1498Szrj
91*38fd1498Szrj if (b >= 0 ? w < a : w > a)
92*38fd1498Szrj abort ();
93*38fd1498Szrj
94*38fd1498Szrj return w;
95*38fd1498Szrj }
96*38fd1498Szrj #endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
97*38fd1498Szrj #endif
98*38fd1498Szrj
99*38fd1498Szrj #ifdef L_addvdi3
100*38fd1498Szrj DWtype
__addvDI3(DWtype a,DWtype b)101*38fd1498Szrj __addvDI3 (DWtype a, DWtype b)
102*38fd1498Szrj {
103*38fd1498Szrj const DWtype w = (UDWtype) a + (UDWtype) b;
104*38fd1498Szrj
105*38fd1498Szrj if (b >= 0 ? w < a : w > a)
106*38fd1498Szrj abort ();
107*38fd1498Szrj
108*38fd1498Szrj return w;
109*38fd1498Szrj }
110*38fd1498Szrj #endif
111*38fd1498Szrj
112*38fd1498Szrj #ifdef L_subvsi3
113*38fd1498Szrj Wtype
__subvSI3(Wtype a,Wtype b)114*38fd1498Szrj __subvSI3 (Wtype a, Wtype b)
115*38fd1498Szrj {
116*38fd1498Szrj const Wtype w = (UWtype) a - (UWtype) b;
117*38fd1498Szrj
118*38fd1498Szrj if (b >= 0 ? w > a : w < a)
119*38fd1498Szrj abort ();
120*38fd1498Szrj
121*38fd1498Szrj return w;
122*38fd1498Szrj }
123*38fd1498Szrj #ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
124*38fd1498Szrj SItype
__subvsi3(SItype a,SItype b)125*38fd1498Szrj __subvsi3 (SItype a, SItype b)
126*38fd1498Szrj {
127*38fd1498Szrj const SItype w = (USItype) a - (USItype) b;
128*38fd1498Szrj
129*38fd1498Szrj if (b >= 0 ? w > a : w < a)
130*38fd1498Szrj abort ();
131*38fd1498Szrj
132*38fd1498Szrj return w;
133*38fd1498Szrj }
134*38fd1498Szrj #endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
135*38fd1498Szrj #endif
136*38fd1498Szrj
137*38fd1498Szrj #ifdef L_subvdi3
138*38fd1498Szrj DWtype
__subvDI3(DWtype a,DWtype b)139*38fd1498Szrj __subvDI3 (DWtype a, DWtype b)
140*38fd1498Szrj {
141*38fd1498Szrj const DWtype w = (UDWtype) a - (UDWtype) b;
142*38fd1498Szrj
143*38fd1498Szrj if (b >= 0 ? w > a : w < a)
144*38fd1498Szrj abort ();
145*38fd1498Szrj
146*38fd1498Szrj return w;
147*38fd1498Szrj }
148*38fd1498Szrj #endif
149*38fd1498Szrj
150*38fd1498Szrj #ifdef L_mulvsi3
151*38fd1498Szrj Wtype
__mulvSI3(Wtype a,Wtype b)152*38fd1498Szrj __mulvSI3 (Wtype a, Wtype b)
153*38fd1498Szrj {
154*38fd1498Szrj const DWtype w = (DWtype) a * (DWtype) b;
155*38fd1498Szrj
156*38fd1498Szrj if ((Wtype) (w >> W_TYPE_SIZE) != (Wtype) w >> (W_TYPE_SIZE - 1))
157*38fd1498Szrj abort ();
158*38fd1498Szrj
159*38fd1498Szrj return w;
160*38fd1498Szrj }
161*38fd1498Szrj #ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
162*38fd1498Szrj #undef WORD_SIZE
163*38fd1498Szrj #define WORD_SIZE (sizeof (SItype) * __CHAR_BIT__)
164*38fd1498Szrj SItype
__mulvsi3(SItype a,SItype b)165*38fd1498Szrj __mulvsi3 (SItype a, SItype b)
166*38fd1498Szrj {
167*38fd1498Szrj const DItype w = (DItype) a * (DItype) b;
168*38fd1498Szrj
169*38fd1498Szrj if ((SItype) (w >> WORD_SIZE) != (SItype) w >> (WORD_SIZE-1))
170*38fd1498Szrj abort ();
171*38fd1498Szrj
172*38fd1498Szrj return w;
173*38fd1498Szrj }
174*38fd1498Szrj #endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
175*38fd1498Szrj #endif
176*38fd1498Szrj
177*38fd1498Szrj #ifdef L_negvsi2
178*38fd1498Szrj Wtype
__negvSI2(Wtype a)179*38fd1498Szrj __negvSI2 (Wtype a)
180*38fd1498Szrj {
181*38fd1498Szrj const Wtype w = -(UWtype) a;
182*38fd1498Szrj
183*38fd1498Szrj if (a >= 0 ? w > 0 : w < 0)
184*38fd1498Szrj abort ();
185*38fd1498Szrj
186*38fd1498Szrj return w;
187*38fd1498Szrj }
188*38fd1498Szrj #ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
189*38fd1498Szrj SItype
__negvsi2(SItype a)190*38fd1498Szrj __negvsi2 (SItype a)
191*38fd1498Szrj {
192*38fd1498Szrj const SItype w = -(USItype) a;
193*38fd1498Szrj
194*38fd1498Szrj if (a >= 0 ? w > 0 : w < 0)
195*38fd1498Szrj abort ();
196*38fd1498Szrj
197*38fd1498Szrj return w;
198*38fd1498Szrj }
199*38fd1498Szrj #endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
200*38fd1498Szrj #endif
201*38fd1498Szrj
202*38fd1498Szrj #ifdef L_negvdi2
203*38fd1498Szrj DWtype
__negvDI2(DWtype a)204*38fd1498Szrj __negvDI2 (DWtype a)
205*38fd1498Szrj {
206*38fd1498Szrj const DWtype w = -(UDWtype) a;
207*38fd1498Szrj
208*38fd1498Szrj if (a >= 0 ? w > 0 : w < 0)
209*38fd1498Szrj abort ();
210*38fd1498Szrj
211*38fd1498Szrj return w;
212*38fd1498Szrj }
213*38fd1498Szrj #endif
214*38fd1498Szrj
215*38fd1498Szrj #ifdef L_absvsi2
216*38fd1498Szrj Wtype
__absvSI2(Wtype a)217*38fd1498Szrj __absvSI2 (Wtype a)
218*38fd1498Szrj {
219*38fd1498Szrj Wtype w = a;
220*38fd1498Szrj
221*38fd1498Szrj if (a < 0)
222*38fd1498Szrj #ifdef L_negvsi2
223*38fd1498Szrj w = __negvSI2 (a);
224*38fd1498Szrj #else
225*38fd1498Szrj w = -(UWtype) a;
226*38fd1498Szrj
227*38fd1498Szrj if (w < 0)
228*38fd1498Szrj abort ();
229*38fd1498Szrj #endif
230*38fd1498Szrj
231*38fd1498Szrj return w;
232*38fd1498Szrj }
233*38fd1498Szrj #ifdef COMPAT_SIMODE_TRAPPING_ARITHMETIC
234*38fd1498Szrj SItype
__absvsi2(SItype a)235*38fd1498Szrj __absvsi2 (SItype a)
236*38fd1498Szrj {
237*38fd1498Szrj SItype w = a;
238*38fd1498Szrj
239*38fd1498Szrj if (a < 0)
240*38fd1498Szrj #ifdef L_negvsi2
241*38fd1498Szrj w = __negvsi2 (a);
242*38fd1498Szrj #else
243*38fd1498Szrj w = -(USItype) a;
244*38fd1498Szrj
245*38fd1498Szrj if (w < 0)
246*38fd1498Szrj abort ();
247*38fd1498Szrj #endif
248*38fd1498Szrj
249*38fd1498Szrj return w;
250*38fd1498Szrj }
251*38fd1498Szrj #endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
252*38fd1498Szrj #endif
253*38fd1498Szrj
254*38fd1498Szrj #ifdef L_absvdi2
255*38fd1498Szrj DWtype
__absvDI2(DWtype a)256*38fd1498Szrj __absvDI2 (DWtype a)
257*38fd1498Szrj {
258*38fd1498Szrj DWtype w = a;
259*38fd1498Szrj
260*38fd1498Szrj if (a < 0)
261*38fd1498Szrj #ifdef L_negvdi2
262*38fd1498Szrj w = __negvDI2 (a);
263*38fd1498Szrj #else
264*38fd1498Szrj w = -(UDWtype) a;
265*38fd1498Szrj
266*38fd1498Szrj if (w < 0)
267*38fd1498Szrj abort ();
268*38fd1498Szrj #endif
269*38fd1498Szrj
270*38fd1498Szrj return w;
271*38fd1498Szrj }
272*38fd1498Szrj #endif
273*38fd1498Szrj
274*38fd1498Szrj #ifdef L_mulvdi3
275*38fd1498Szrj DWtype
__mulvDI3(DWtype u,DWtype v)276*38fd1498Szrj __mulvDI3 (DWtype u, DWtype v)
277*38fd1498Szrj {
278*38fd1498Szrj /* The unchecked multiplication needs 3 Wtype x Wtype multiplications,
279*38fd1498Szrj but the checked multiplication needs only two. */
280*38fd1498Szrj const DWunion uu = {.ll = u};
281*38fd1498Szrj const DWunion vv = {.ll = v};
282*38fd1498Szrj
283*38fd1498Szrj if (__builtin_expect (uu.s.high == uu.s.low >> (W_TYPE_SIZE - 1), 1))
284*38fd1498Szrj {
285*38fd1498Szrj /* u fits in a single Wtype. */
286*38fd1498Szrj if (__builtin_expect (vv.s.high == vv.s.low >> (W_TYPE_SIZE - 1), 1))
287*38fd1498Szrj {
288*38fd1498Szrj /* v fits in a single Wtype as well. */
289*38fd1498Szrj /* A single multiplication. No overflow risk. */
290*38fd1498Szrj return (DWtype) uu.s.low * (DWtype) vv.s.low;
291*38fd1498Szrj }
292*38fd1498Szrj else
293*38fd1498Szrj {
294*38fd1498Szrj /* Two multiplications. */
295*38fd1498Szrj DWunion w0 = {.ll = (UDWtype) (UWtype) uu.s.low
296*38fd1498Szrj * (UDWtype) (UWtype) vv.s.low};
297*38fd1498Szrj DWunion w1 = {.ll = (UDWtype) (UWtype) uu.s.low
298*38fd1498Szrj * (UDWtype) (UWtype) vv.s.high};
299*38fd1498Szrj
300*38fd1498Szrj if (vv.s.high < 0)
301*38fd1498Szrj w1.s.high -= uu.s.low;
302*38fd1498Szrj if (uu.s.low < 0)
303*38fd1498Szrj w1.ll -= vv.ll;
304*38fd1498Szrj w1.ll += (UWtype) w0.s.high;
305*38fd1498Szrj if (__builtin_expect (w1.s.high == w1.s.low >> (W_TYPE_SIZE - 1), 1))
306*38fd1498Szrj {
307*38fd1498Szrj w0.s.high = w1.s.low;
308*38fd1498Szrj return w0.ll;
309*38fd1498Szrj }
310*38fd1498Szrj }
311*38fd1498Szrj }
312*38fd1498Szrj else
313*38fd1498Szrj {
314*38fd1498Szrj if (__builtin_expect (vv.s.high == vv.s.low >> (W_TYPE_SIZE - 1), 1))
315*38fd1498Szrj {
316*38fd1498Szrj /* v fits into a single Wtype. */
317*38fd1498Szrj /* Two multiplications. */
318*38fd1498Szrj DWunion w0 = {.ll = (UDWtype) (UWtype) uu.s.low
319*38fd1498Szrj * (UDWtype) (UWtype) vv.s.low};
320*38fd1498Szrj DWunion w1 = {.ll = (UDWtype) (UWtype) uu.s.high
321*38fd1498Szrj * (UDWtype) (UWtype) vv.s.low};
322*38fd1498Szrj
323*38fd1498Szrj if (uu.s.high < 0)
324*38fd1498Szrj w1.s.high -= vv.s.low;
325*38fd1498Szrj if (vv.s.low < 0)
326*38fd1498Szrj w1.ll -= uu.ll;
327*38fd1498Szrj w1.ll += (UWtype) w0.s.high;
328*38fd1498Szrj if (__builtin_expect (w1.s.high == w1.s.low >> (W_TYPE_SIZE - 1), 1))
329*38fd1498Szrj {
330*38fd1498Szrj w0.s.high = w1.s.low;
331*38fd1498Szrj return w0.ll;
332*38fd1498Szrj }
333*38fd1498Szrj }
334*38fd1498Szrj else
335*38fd1498Szrj {
336*38fd1498Szrj /* A few sign checks and a single multiplication. */
337*38fd1498Szrj if (uu.s.high >= 0)
338*38fd1498Szrj {
339*38fd1498Szrj if (vv.s.high >= 0)
340*38fd1498Szrj {
341*38fd1498Szrj if (uu.s.high == 0 && vv.s.high == 0)
342*38fd1498Szrj {
343*38fd1498Szrj const DWtype w = (UDWtype) (UWtype) uu.s.low
344*38fd1498Szrj * (UDWtype) (UWtype) vv.s.low;
345*38fd1498Szrj if (__builtin_expect (w >= 0, 1))
346*38fd1498Szrj return w;
347*38fd1498Szrj }
348*38fd1498Szrj }
349*38fd1498Szrj else
350*38fd1498Szrj {
351*38fd1498Szrj if (uu.s.high == 0 && vv.s.high == (Wtype) -1)
352*38fd1498Szrj {
353*38fd1498Szrj DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low
354*38fd1498Szrj * (UDWtype) (UWtype) vv.s.low};
355*38fd1498Szrj
356*38fd1498Szrj ww.s.high -= uu.s.low;
357*38fd1498Szrj if (__builtin_expect (ww.s.high < 0, 1))
358*38fd1498Szrj return ww.ll;
359*38fd1498Szrj }
360*38fd1498Szrj }
361*38fd1498Szrj }
362*38fd1498Szrj else
363*38fd1498Szrj {
364*38fd1498Szrj if (vv.s.high >= 0)
365*38fd1498Szrj {
366*38fd1498Szrj if (uu.s.high == (Wtype) -1 && vv.s.high == 0)
367*38fd1498Szrj {
368*38fd1498Szrj DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low
369*38fd1498Szrj * (UDWtype) (UWtype) vv.s.low};
370*38fd1498Szrj
371*38fd1498Szrj ww.s.high -= vv.s.low;
372*38fd1498Szrj if (__builtin_expect (ww.s.high < 0, 1))
373*38fd1498Szrj return ww.ll;
374*38fd1498Szrj }
375*38fd1498Szrj }
376*38fd1498Szrj else
377*38fd1498Szrj {
378*38fd1498Szrj if ((uu.s.high & vv.s.high) == (Wtype) -1
379*38fd1498Szrj && (uu.s.low | vv.s.low) != 0)
380*38fd1498Szrj {
381*38fd1498Szrj DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low
382*38fd1498Szrj * (UDWtype) (UWtype) vv.s.low};
383*38fd1498Szrj
384*38fd1498Szrj ww.s.high -= uu.s.low;
385*38fd1498Szrj ww.s.high -= vv.s.low;
386*38fd1498Szrj if (__builtin_expect (ww.s.high >= 0, 1))
387*38fd1498Szrj return ww.ll;
388*38fd1498Szrj }
389*38fd1498Szrj }
390*38fd1498Szrj }
391*38fd1498Szrj }
392*38fd1498Szrj }
393*38fd1498Szrj
394*38fd1498Szrj /* Overflow. */
395*38fd1498Szrj abort ();
396*38fd1498Szrj }
397*38fd1498Szrj #endif
398*38fd1498Szrj
399*38fd1498Szrj
400*38fd1498Szrj /* Unless shift functions are defined with full ANSI prototypes,
401*38fd1498Szrj parameter b will be promoted to int if shift_count_type is smaller than an int. */
402*38fd1498Szrj #ifdef L_lshrdi3
403*38fd1498Szrj DWtype
__lshrdi3(DWtype u,shift_count_type b)404*38fd1498Szrj __lshrdi3 (DWtype u, shift_count_type b)
405*38fd1498Szrj {
406*38fd1498Szrj if (b == 0)
407*38fd1498Szrj return u;
408*38fd1498Szrj
409*38fd1498Szrj const DWunion uu = {.ll = u};
410*38fd1498Szrj const shift_count_type bm = W_TYPE_SIZE - b;
411*38fd1498Szrj DWunion w;
412*38fd1498Szrj
413*38fd1498Szrj if (bm <= 0)
414*38fd1498Szrj {
415*38fd1498Szrj w.s.high = 0;
416*38fd1498Szrj w.s.low = (UWtype) uu.s.high >> -bm;
417*38fd1498Szrj }
418*38fd1498Szrj else
419*38fd1498Szrj {
420*38fd1498Szrj const UWtype carries = (UWtype) uu.s.high << bm;
421*38fd1498Szrj
422*38fd1498Szrj w.s.high = (UWtype) uu.s.high >> b;
423*38fd1498Szrj w.s.low = ((UWtype) uu.s.low >> b) | carries;
424*38fd1498Szrj }
425*38fd1498Szrj
426*38fd1498Szrj return w.ll;
427*38fd1498Szrj }
428*38fd1498Szrj #endif
429*38fd1498Szrj
430*38fd1498Szrj #ifdef L_ashldi3
431*38fd1498Szrj DWtype
__ashldi3(DWtype u,shift_count_type b)432*38fd1498Szrj __ashldi3 (DWtype u, shift_count_type b)
433*38fd1498Szrj {
434*38fd1498Szrj if (b == 0)
435*38fd1498Szrj return u;
436*38fd1498Szrj
437*38fd1498Szrj const DWunion uu = {.ll = u};
438*38fd1498Szrj const shift_count_type bm = W_TYPE_SIZE - b;
439*38fd1498Szrj DWunion w;
440*38fd1498Szrj
441*38fd1498Szrj if (bm <= 0)
442*38fd1498Szrj {
443*38fd1498Szrj w.s.low = 0;
444*38fd1498Szrj w.s.high = (UWtype) uu.s.low << -bm;
445*38fd1498Szrj }
446*38fd1498Szrj else
447*38fd1498Szrj {
448*38fd1498Szrj const UWtype carries = (UWtype) uu.s.low >> bm;
449*38fd1498Szrj
450*38fd1498Szrj w.s.low = (UWtype) uu.s.low << b;
451*38fd1498Szrj w.s.high = ((UWtype) uu.s.high << b) | carries;
452*38fd1498Szrj }
453*38fd1498Szrj
454*38fd1498Szrj return w.ll;
455*38fd1498Szrj }
456*38fd1498Szrj #endif
457*38fd1498Szrj
458*38fd1498Szrj #ifdef L_ashrdi3
459*38fd1498Szrj DWtype
__ashrdi3(DWtype u,shift_count_type b)460*38fd1498Szrj __ashrdi3 (DWtype u, shift_count_type b)
461*38fd1498Szrj {
462*38fd1498Szrj if (b == 0)
463*38fd1498Szrj return u;
464*38fd1498Szrj
465*38fd1498Szrj const DWunion uu = {.ll = u};
466*38fd1498Szrj const shift_count_type bm = W_TYPE_SIZE - b;
467*38fd1498Szrj DWunion w;
468*38fd1498Szrj
469*38fd1498Szrj if (bm <= 0)
470*38fd1498Szrj {
471*38fd1498Szrj /* w.s.high = 1..1 or 0..0 */
472*38fd1498Szrj w.s.high = uu.s.high >> (W_TYPE_SIZE - 1);
473*38fd1498Szrj w.s.low = uu.s.high >> -bm;
474*38fd1498Szrj }
475*38fd1498Szrj else
476*38fd1498Szrj {
477*38fd1498Szrj const UWtype carries = (UWtype) uu.s.high << bm;
478*38fd1498Szrj
479*38fd1498Szrj w.s.high = uu.s.high >> b;
480*38fd1498Szrj w.s.low = ((UWtype) uu.s.low >> b) | carries;
481*38fd1498Szrj }
482*38fd1498Szrj
483*38fd1498Szrj return w.ll;
484*38fd1498Szrj }
485*38fd1498Szrj #endif
486*38fd1498Szrj
487*38fd1498Szrj #ifdef L_bswapsi2
488*38fd1498Szrj SItype
__bswapsi2(SItype u)489*38fd1498Szrj __bswapsi2 (SItype u)
490*38fd1498Szrj {
491*38fd1498Szrj return ((((u) & 0xff000000) >> 24)
492*38fd1498Szrj | (((u) & 0x00ff0000) >> 8)
493*38fd1498Szrj | (((u) & 0x0000ff00) << 8)
494*38fd1498Szrj | (((u) & 0x000000ff) << 24));
495*38fd1498Szrj }
496*38fd1498Szrj #endif
497*38fd1498Szrj #ifdef L_bswapdi2
498*38fd1498Szrj DItype
__bswapdi2(DItype u)499*38fd1498Szrj __bswapdi2 (DItype u)
500*38fd1498Szrj {
501*38fd1498Szrj return ((((u) & 0xff00000000000000ull) >> 56)
502*38fd1498Szrj | (((u) & 0x00ff000000000000ull) >> 40)
503*38fd1498Szrj | (((u) & 0x0000ff0000000000ull) >> 24)
504*38fd1498Szrj | (((u) & 0x000000ff00000000ull) >> 8)
505*38fd1498Szrj | (((u) & 0x00000000ff000000ull) << 8)
506*38fd1498Szrj | (((u) & 0x0000000000ff0000ull) << 24)
507*38fd1498Szrj | (((u) & 0x000000000000ff00ull) << 40)
508*38fd1498Szrj | (((u) & 0x00000000000000ffull) << 56));
509*38fd1498Szrj }
510*38fd1498Szrj #endif
511*38fd1498Szrj #ifdef L_ffssi2
512*38fd1498Szrj #undef int
513*38fd1498Szrj int
__ffsSI2(UWtype u)514*38fd1498Szrj __ffsSI2 (UWtype u)
515*38fd1498Szrj {
516*38fd1498Szrj UWtype count;
517*38fd1498Szrj
518*38fd1498Szrj if (u == 0)
519*38fd1498Szrj return 0;
520*38fd1498Szrj
521*38fd1498Szrj count_trailing_zeros (count, u);
522*38fd1498Szrj return count + 1;
523*38fd1498Szrj }
524*38fd1498Szrj #endif
525*38fd1498Szrj
526*38fd1498Szrj #ifdef L_ffsdi2
527*38fd1498Szrj #undef int
528*38fd1498Szrj int
__ffsDI2(DWtype u)529*38fd1498Szrj __ffsDI2 (DWtype u)
530*38fd1498Szrj {
531*38fd1498Szrj const DWunion uu = {.ll = u};
532*38fd1498Szrj UWtype word, count, add;
533*38fd1498Szrj
534*38fd1498Szrj if (uu.s.low != 0)
535*38fd1498Szrj word = uu.s.low, add = 0;
536*38fd1498Szrj else if (uu.s.high != 0)
537*38fd1498Szrj word = uu.s.high, add = W_TYPE_SIZE;
538*38fd1498Szrj else
539*38fd1498Szrj return 0;
540*38fd1498Szrj
541*38fd1498Szrj count_trailing_zeros (count, word);
542*38fd1498Szrj return count + add + 1;
543*38fd1498Szrj }
544*38fd1498Szrj #endif
545*38fd1498Szrj
546*38fd1498Szrj #ifdef L_muldi3
547*38fd1498Szrj DWtype
__muldi3(DWtype u,DWtype v)548*38fd1498Szrj __muldi3 (DWtype u, DWtype v)
549*38fd1498Szrj {
550*38fd1498Szrj const DWunion uu = {.ll = u};
551*38fd1498Szrj const DWunion vv = {.ll = v};
552*38fd1498Szrj DWunion w = {.ll = __umulsidi3 (uu.s.low, vv.s.low)};
553*38fd1498Szrj
554*38fd1498Szrj w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
555*38fd1498Szrj + (UWtype) uu.s.high * (UWtype) vv.s.low);
556*38fd1498Szrj
557*38fd1498Szrj return w.ll;
558*38fd1498Szrj }
559*38fd1498Szrj #endif
560*38fd1498Szrj
561*38fd1498Szrj #if (defined (L_udivdi3) || defined (L_divdi3) || \
562*38fd1498Szrj defined (L_umoddi3) || defined (L_moddi3))
563*38fd1498Szrj #if defined (sdiv_qrnnd)
564*38fd1498Szrj #define L_udiv_w_sdiv
565*38fd1498Szrj #endif
566*38fd1498Szrj #endif
567*38fd1498Szrj
568*38fd1498Szrj #ifdef L_udiv_w_sdiv
569*38fd1498Szrj #if defined (sdiv_qrnnd)
570*38fd1498Szrj #if (defined (L_udivdi3) || defined (L_divdi3) || \
571*38fd1498Szrj defined (L_umoddi3) || defined (L_moddi3))
572*38fd1498Szrj static inline __attribute__ ((__always_inline__))
573*38fd1498Szrj #endif
574*38fd1498Szrj UWtype
__udiv_w_sdiv(UWtype * rp,UWtype a1,UWtype a0,UWtype d)575*38fd1498Szrj __udiv_w_sdiv (UWtype *rp, UWtype a1, UWtype a0, UWtype d)
576*38fd1498Szrj {
577*38fd1498Szrj UWtype q, r;
578*38fd1498Szrj UWtype c0, c1, b1;
579*38fd1498Szrj
580*38fd1498Szrj if ((Wtype) d >= 0)
581*38fd1498Szrj {
582*38fd1498Szrj if (a1 < d - a1 - (a0 >> (W_TYPE_SIZE - 1)))
583*38fd1498Szrj {
584*38fd1498Szrj /* Dividend, divisor, and quotient are nonnegative. */
585*38fd1498Szrj sdiv_qrnnd (q, r, a1, a0, d);
586*38fd1498Szrj }
587*38fd1498Szrj else
588*38fd1498Szrj {
589*38fd1498Szrj /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d. */
590*38fd1498Szrj sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (W_TYPE_SIZE - 1));
591*38fd1498Szrj /* Divide (c1*2^32 + c0) by d. */
592*38fd1498Szrj sdiv_qrnnd (q, r, c1, c0, d);
593*38fd1498Szrj /* Add 2^31 to quotient. */
594*38fd1498Szrj q += (UWtype) 1 << (W_TYPE_SIZE - 1);
595*38fd1498Szrj }
596*38fd1498Szrj }
597*38fd1498Szrj else
598*38fd1498Szrj {
599*38fd1498Szrj b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
600*38fd1498Szrj c1 = a1 >> 1; /* A/2 */
601*38fd1498Szrj c0 = (a1 << (W_TYPE_SIZE - 1)) + (a0 >> 1);
602*38fd1498Szrj
603*38fd1498Szrj if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
604*38fd1498Szrj {
605*38fd1498Szrj sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
606*38fd1498Szrj
607*38fd1498Szrj r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
608*38fd1498Szrj if ((d & 1) != 0)
609*38fd1498Szrj {
610*38fd1498Szrj if (r >= q)
611*38fd1498Szrj r = r - q;
612*38fd1498Szrj else if (q - r <= d)
613*38fd1498Szrj {
614*38fd1498Szrj r = r - q + d;
615*38fd1498Szrj q--;
616*38fd1498Szrj }
617*38fd1498Szrj else
618*38fd1498Szrj {
619*38fd1498Szrj r = r - q + 2*d;
620*38fd1498Szrj q -= 2;
621*38fd1498Szrj }
622*38fd1498Szrj }
623*38fd1498Szrj }
624*38fd1498Szrj else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
625*38fd1498Szrj {
626*38fd1498Szrj c1 = (b1 - 1) - c1;
627*38fd1498Szrj c0 = ~c0; /* logical NOT */
628*38fd1498Szrj
629*38fd1498Szrj sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
630*38fd1498Szrj
631*38fd1498Szrj q = ~q; /* (A/2)/b1 */
632*38fd1498Szrj r = (b1 - 1) - r;
633*38fd1498Szrj
634*38fd1498Szrj r = 2*r + (a0 & 1); /* A/(2*b1) */
635*38fd1498Szrj
636*38fd1498Szrj if ((d & 1) != 0)
637*38fd1498Szrj {
638*38fd1498Szrj if (r >= q)
639*38fd1498Szrj r = r - q;
640*38fd1498Szrj else if (q - r <= d)
641*38fd1498Szrj {
642*38fd1498Szrj r = r - q + d;
643*38fd1498Szrj q--;
644*38fd1498Szrj }
645*38fd1498Szrj else
646*38fd1498Szrj {
647*38fd1498Szrj r = r - q + 2*d;
648*38fd1498Szrj q -= 2;
649*38fd1498Szrj }
650*38fd1498Szrj }
651*38fd1498Szrj }
652*38fd1498Szrj else /* Implies c1 = b1 */
653*38fd1498Szrj { /* Hence a1 = d - 1 = 2*b1 - 1 */
654*38fd1498Szrj if (a0 >= -d)
655*38fd1498Szrj {
656*38fd1498Szrj q = -1;
657*38fd1498Szrj r = a0 + d;
658*38fd1498Szrj }
659*38fd1498Szrj else
660*38fd1498Szrj {
661*38fd1498Szrj q = -2;
662*38fd1498Szrj r = a0 + 2*d;
663*38fd1498Szrj }
664*38fd1498Szrj }
665*38fd1498Szrj }
666*38fd1498Szrj
667*38fd1498Szrj *rp = r;
668*38fd1498Szrj return q;
669*38fd1498Szrj }
670*38fd1498Szrj #else
671*38fd1498Szrj /* If sdiv_qrnnd doesn't exist, define dummy __udiv_w_sdiv. */
672*38fd1498Szrj UWtype
__udiv_w_sdiv(UWtype * rp,UWtype a1,UWtype a0,UWtype d)673*38fd1498Szrj __udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)),
674*38fd1498Szrj UWtype a1 __attribute__ ((__unused__)),
675*38fd1498Szrj UWtype a0 __attribute__ ((__unused__)),
676*38fd1498Szrj UWtype d __attribute__ ((__unused__)))
677*38fd1498Szrj {
678*38fd1498Szrj return 0;
679*38fd1498Szrj }
680*38fd1498Szrj #endif
681*38fd1498Szrj #endif
682*38fd1498Szrj
683*38fd1498Szrj #if (defined (L_udivdi3) || defined (L_divdi3) || \
684*38fd1498Szrj defined (L_umoddi3) || defined (L_moddi3) || \
685*38fd1498Szrj defined (L_divmoddi4))
686*38fd1498Szrj #define L_udivmoddi4
687*38fd1498Szrj #endif
688*38fd1498Szrj
689*38fd1498Szrj #ifdef L_clz
690*38fd1498Szrj const UQItype __clz_tab[256] =
691*38fd1498Szrj {
692*38fd1498Szrj 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,
693*38fd1498Szrj 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,
694*38fd1498Szrj 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,
695*38fd1498Szrj 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,
696*38fd1498Szrj 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,
697*38fd1498Szrj 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,
698*38fd1498Szrj 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,
699*38fd1498Szrj 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
700*38fd1498Szrj };
701*38fd1498Szrj #endif
702*38fd1498Szrj
703*38fd1498Szrj #ifdef L_clzsi2
704*38fd1498Szrj #undef int
705*38fd1498Szrj int
__clzSI2(UWtype x)706*38fd1498Szrj __clzSI2 (UWtype x)
707*38fd1498Szrj {
708*38fd1498Szrj Wtype ret;
709*38fd1498Szrj
710*38fd1498Szrj count_leading_zeros (ret, x);
711*38fd1498Szrj
712*38fd1498Szrj return ret;
713*38fd1498Szrj }
714*38fd1498Szrj #endif
715*38fd1498Szrj
716*38fd1498Szrj #ifdef L_clzdi2
717*38fd1498Szrj #undef int
718*38fd1498Szrj int
__clzDI2(UDWtype x)719*38fd1498Szrj __clzDI2 (UDWtype x)
720*38fd1498Szrj {
721*38fd1498Szrj const DWunion uu = {.ll = x};
722*38fd1498Szrj UWtype word;
723*38fd1498Szrj Wtype ret, add;
724*38fd1498Szrj
725*38fd1498Szrj if (uu.s.high)
726*38fd1498Szrj word = uu.s.high, add = 0;
727*38fd1498Szrj else
728*38fd1498Szrj word = uu.s.low, add = W_TYPE_SIZE;
729*38fd1498Szrj
730*38fd1498Szrj count_leading_zeros (ret, word);
731*38fd1498Szrj return ret + add;
732*38fd1498Szrj }
733*38fd1498Szrj #endif
734*38fd1498Szrj
735*38fd1498Szrj #ifdef L_ctzsi2
736*38fd1498Szrj #undef int
737*38fd1498Szrj int
__ctzSI2(UWtype x)738*38fd1498Szrj __ctzSI2 (UWtype x)
739*38fd1498Szrj {
740*38fd1498Szrj Wtype ret;
741*38fd1498Szrj
742*38fd1498Szrj count_trailing_zeros (ret, x);
743*38fd1498Szrj
744*38fd1498Szrj return ret;
745*38fd1498Szrj }
746*38fd1498Szrj #endif
747*38fd1498Szrj
748*38fd1498Szrj #ifdef L_ctzdi2
749*38fd1498Szrj #undef int
750*38fd1498Szrj int
__ctzDI2(UDWtype x)751*38fd1498Szrj __ctzDI2 (UDWtype x)
752*38fd1498Szrj {
753*38fd1498Szrj const DWunion uu = {.ll = x};
754*38fd1498Szrj UWtype word;
755*38fd1498Szrj Wtype ret, add;
756*38fd1498Szrj
757*38fd1498Szrj if (uu.s.low)
758*38fd1498Szrj word = uu.s.low, add = 0;
759*38fd1498Szrj else
760*38fd1498Szrj word = uu.s.high, add = W_TYPE_SIZE;
761*38fd1498Szrj
762*38fd1498Szrj count_trailing_zeros (ret, word);
763*38fd1498Szrj return ret + add;
764*38fd1498Szrj }
765*38fd1498Szrj #endif
766*38fd1498Szrj
767*38fd1498Szrj #ifdef L_clrsbsi2
768*38fd1498Szrj #undef int
769*38fd1498Szrj int
__clrsbSI2(Wtype x)770*38fd1498Szrj __clrsbSI2 (Wtype x)
771*38fd1498Szrj {
772*38fd1498Szrj Wtype ret;
773*38fd1498Szrj
774*38fd1498Szrj if (x < 0)
775*38fd1498Szrj x = ~x;
776*38fd1498Szrj if (x == 0)
777*38fd1498Szrj return W_TYPE_SIZE - 1;
778*38fd1498Szrj count_leading_zeros (ret, x);
779*38fd1498Szrj return ret - 1;
780*38fd1498Szrj }
781*38fd1498Szrj #endif
782*38fd1498Szrj
783*38fd1498Szrj #ifdef L_clrsbdi2
784*38fd1498Szrj #undef int
785*38fd1498Szrj int
__clrsbDI2(DWtype x)786*38fd1498Szrj __clrsbDI2 (DWtype x)
787*38fd1498Szrj {
788*38fd1498Szrj const DWunion uu = {.ll = x};
789*38fd1498Szrj UWtype word;
790*38fd1498Szrj Wtype ret, add;
791*38fd1498Szrj
792*38fd1498Szrj if (uu.s.high == 0)
793*38fd1498Szrj word = uu.s.low, add = W_TYPE_SIZE;
794*38fd1498Szrj else if (uu.s.high == -1)
795*38fd1498Szrj word = ~uu.s.low, add = W_TYPE_SIZE;
796*38fd1498Szrj else if (uu.s.high >= 0)
797*38fd1498Szrj word = uu.s.high, add = 0;
798*38fd1498Szrj else
799*38fd1498Szrj word = ~uu.s.high, add = 0;
800*38fd1498Szrj
801*38fd1498Szrj if (word == 0)
802*38fd1498Szrj ret = W_TYPE_SIZE;
803*38fd1498Szrj else
804*38fd1498Szrj count_leading_zeros (ret, word);
805*38fd1498Szrj
806*38fd1498Szrj return ret + add - 1;
807*38fd1498Szrj }
808*38fd1498Szrj #endif
809*38fd1498Szrj
810*38fd1498Szrj #ifdef L_popcount_tab
811*38fd1498Szrj const UQItype __popcount_tab[256] =
812*38fd1498Szrj {
813*38fd1498Szrj 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
814*38fd1498Szrj 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
815*38fd1498Szrj 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
816*38fd1498Szrj 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
817*38fd1498Szrj 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
818*38fd1498Szrj 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
819*38fd1498Szrj 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
820*38fd1498Szrj 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
821*38fd1498Szrj };
822*38fd1498Szrj #endif
823*38fd1498Szrj
824*38fd1498Szrj #if defined(L_popcountsi2) || defined(L_popcountdi2)
825*38fd1498Szrj #define POPCOUNTCST2(x) (((UWtype) x << __CHAR_BIT__) | x)
826*38fd1498Szrj #define POPCOUNTCST4(x) (((UWtype) x << (2 * __CHAR_BIT__)) | x)
827*38fd1498Szrj #define POPCOUNTCST8(x) (((UWtype) x << (4 * __CHAR_BIT__)) | x)
828*38fd1498Szrj #if W_TYPE_SIZE == __CHAR_BIT__
829*38fd1498Szrj #define POPCOUNTCST(x) x
830*38fd1498Szrj #elif W_TYPE_SIZE == 2 * __CHAR_BIT__
831*38fd1498Szrj #define POPCOUNTCST(x) POPCOUNTCST2 (x)
832*38fd1498Szrj #elif W_TYPE_SIZE == 4 * __CHAR_BIT__
833*38fd1498Szrj #define POPCOUNTCST(x) POPCOUNTCST4 (POPCOUNTCST2 (x))
834*38fd1498Szrj #elif W_TYPE_SIZE == 8 * __CHAR_BIT__
835*38fd1498Szrj #define POPCOUNTCST(x) POPCOUNTCST8 (POPCOUNTCST4 (POPCOUNTCST2 (x)))
836*38fd1498Szrj #endif
837*38fd1498Szrj #endif
838*38fd1498Szrj
839*38fd1498Szrj #ifdef L_popcountsi2
840*38fd1498Szrj #undef int
841*38fd1498Szrj int
__popcountSI2(UWtype x)842*38fd1498Szrj __popcountSI2 (UWtype x)
843*38fd1498Szrj {
844*38fd1498Szrj /* Force table lookup on targets like AVR and RL78 which only
845*38fd1498Szrj pretend they have LIBGCC2_UNITS_PER_WORD 4, but actually
846*38fd1498Szrj have 1, and other small word targets. */
847*38fd1498Szrj #if __SIZEOF_INT__ > 2 && defined (POPCOUNTCST) && __CHAR_BIT__ == 8
848*38fd1498Szrj x = x - ((x >> 1) & POPCOUNTCST (0x55));
849*38fd1498Szrj x = (x & POPCOUNTCST (0x33)) + ((x >> 2) & POPCOUNTCST (0x33));
850*38fd1498Szrj x = (x + (x >> 4)) & POPCOUNTCST (0x0F);
851*38fd1498Szrj return (x * POPCOUNTCST (0x01)) >> (W_TYPE_SIZE - __CHAR_BIT__);
852*38fd1498Szrj #else
853*38fd1498Szrj int i, ret = 0;
854*38fd1498Szrj
855*38fd1498Szrj for (i = 0; i < W_TYPE_SIZE; i += 8)
856*38fd1498Szrj ret += __popcount_tab[(x >> i) & 0xff];
857*38fd1498Szrj
858*38fd1498Szrj return ret;
859*38fd1498Szrj #endif
860*38fd1498Szrj }
861*38fd1498Szrj #endif
862*38fd1498Szrj
863*38fd1498Szrj #ifdef L_popcountdi2
864*38fd1498Szrj #undef int
865*38fd1498Szrj int
__popcountDI2(UDWtype x)866*38fd1498Szrj __popcountDI2 (UDWtype x)
867*38fd1498Szrj {
868*38fd1498Szrj /* Force table lookup on targets like AVR and RL78 which only
869*38fd1498Szrj pretend they have LIBGCC2_UNITS_PER_WORD 4, but actually
870*38fd1498Szrj have 1, and other small word targets. */
871*38fd1498Szrj #if __SIZEOF_INT__ > 2 && defined (POPCOUNTCST) && __CHAR_BIT__ == 8
872*38fd1498Szrj const DWunion uu = {.ll = x};
873*38fd1498Szrj UWtype x1 = uu.s.low, x2 = uu.s.high;
874*38fd1498Szrj x1 = x1 - ((x1 >> 1) & POPCOUNTCST (0x55));
875*38fd1498Szrj x2 = x2 - ((x2 >> 1) & POPCOUNTCST (0x55));
876*38fd1498Szrj x1 = (x1 & POPCOUNTCST (0x33)) + ((x1 >> 2) & POPCOUNTCST (0x33));
877*38fd1498Szrj x2 = (x2 & POPCOUNTCST (0x33)) + ((x2 >> 2) & POPCOUNTCST (0x33));
878*38fd1498Szrj x1 = (x1 + (x1 >> 4)) & POPCOUNTCST (0x0F);
879*38fd1498Szrj x2 = (x2 + (x2 >> 4)) & POPCOUNTCST (0x0F);
880*38fd1498Szrj x1 += x2;
881*38fd1498Szrj return (x1 * POPCOUNTCST (0x01)) >> (W_TYPE_SIZE - __CHAR_BIT__);
882*38fd1498Szrj #else
883*38fd1498Szrj int i, ret = 0;
884*38fd1498Szrj
885*38fd1498Szrj for (i = 0; i < 2*W_TYPE_SIZE; i += 8)
886*38fd1498Szrj ret += __popcount_tab[(x >> i) & 0xff];
887*38fd1498Szrj
888*38fd1498Szrj return ret;
889*38fd1498Szrj #endif
890*38fd1498Szrj }
891*38fd1498Szrj #endif
892*38fd1498Szrj
893*38fd1498Szrj #ifdef L_paritysi2
894*38fd1498Szrj #undef int
895*38fd1498Szrj int
__paritySI2(UWtype x)896*38fd1498Szrj __paritySI2 (UWtype x)
897*38fd1498Szrj {
898*38fd1498Szrj #if W_TYPE_SIZE > 64
899*38fd1498Szrj # error "fill out the table"
900*38fd1498Szrj #endif
901*38fd1498Szrj #if W_TYPE_SIZE > 32
902*38fd1498Szrj x ^= x >> 32;
903*38fd1498Szrj #endif
904*38fd1498Szrj #if W_TYPE_SIZE > 16
905*38fd1498Szrj x ^= x >> 16;
906*38fd1498Szrj #endif
907*38fd1498Szrj x ^= x >> 8;
908*38fd1498Szrj x ^= x >> 4;
909*38fd1498Szrj x &= 0xf;
910*38fd1498Szrj return (0x6996 >> x) & 1;
911*38fd1498Szrj }
912*38fd1498Szrj #endif
913*38fd1498Szrj
914*38fd1498Szrj #ifdef L_paritydi2
915*38fd1498Szrj #undef int
916*38fd1498Szrj int
__parityDI2(UDWtype x)917*38fd1498Szrj __parityDI2 (UDWtype x)
918*38fd1498Szrj {
919*38fd1498Szrj const DWunion uu = {.ll = x};
920*38fd1498Szrj UWtype nx = uu.s.low ^ uu.s.high;
921*38fd1498Szrj
922*38fd1498Szrj #if W_TYPE_SIZE > 64
923*38fd1498Szrj # error "fill out the table"
924*38fd1498Szrj #endif
925*38fd1498Szrj #if W_TYPE_SIZE > 32
926*38fd1498Szrj nx ^= nx >> 32;
927*38fd1498Szrj #endif
928*38fd1498Szrj #if W_TYPE_SIZE > 16
929*38fd1498Szrj nx ^= nx >> 16;
930*38fd1498Szrj #endif
931*38fd1498Szrj nx ^= nx >> 8;
932*38fd1498Szrj nx ^= nx >> 4;
933*38fd1498Szrj nx &= 0xf;
934*38fd1498Szrj return (0x6996 >> nx) & 1;
935*38fd1498Szrj }
936*38fd1498Szrj #endif
937*38fd1498Szrj
938*38fd1498Szrj #ifdef L_udivmoddi4
939*38fd1498Szrj #ifdef TARGET_HAS_NO_HW_DIVIDE
940*38fd1498Szrj
941*38fd1498Szrj #if (defined (L_udivdi3) || defined (L_divdi3) || \
942*38fd1498Szrj defined (L_umoddi3) || defined (L_moddi3) || \
943*38fd1498Szrj defined (L_divmoddi4))
944*38fd1498Szrj static inline __attribute__ ((__always_inline__))
945*38fd1498Szrj #endif
946*38fd1498Szrj UDWtype
__udivmoddi4(UDWtype n,UDWtype d,UDWtype * rp)947*38fd1498Szrj __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
948*38fd1498Szrj {
949*38fd1498Szrj UDWtype q = 0, r = n, y = d;
950*38fd1498Szrj UWtype lz1, lz2, i, k;
951*38fd1498Szrj
952*38fd1498Szrj /* Implements align divisor shift dividend method. This algorithm
953*38fd1498Szrj aligns the divisor under the dividend and then perform number of
954*38fd1498Szrj test-subtract iterations which shift the dividend left. Number of
955*38fd1498Szrj iterations is k + 1 where k is the number of bit positions the
956*38fd1498Szrj divisor must be shifted left to align it under the dividend.
957*38fd1498Szrj quotient bits can be saved in the rightmost positions of the dividend
958*38fd1498Szrj as it shifts left on each test-subtract iteration. */
959*38fd1498Szrj
960*38fd1498Szrj if (y <= r)
961*38fd1498Szrj {
962*38fd1498Szrj lz1 = __builtin_clzll (d);
963*38fd1498Szrj lz2 = __builtin_clzll (n);
964*38fd1498Szrj
965*38fd1498Szrj k = lz1 - lz2;
966*38fd1498Szrj y = (y << k);
967*38fd1498Szrj
968*38fd1498Szrj /* Dividend can exceed 2 ^ (width − 1) − 1 but still be less than the
969*38fd1498Szrj aligned divisor. Normal iteration can drops the high order bit
970*38fd1498Szrj of the dividend. Therefore, first test-subtract iteration is a
971*38fd1498Szrj special case, saving its quotient bit in a separate location and
972*38fd1498Szrj not shifting the dividend. */
973*38fd1498Szrj if (r >= y)
974*38fd1498Szrj {
975*38fd1498Szrj r = r - y;
976*38fd1498Szrj q = (1ULL << k);
977*38fd1498Szrj }
978*38fd1498Szrj
979*38fd1498Szrj if (k > 0)
980*38fd1498Szrj {
981*38fd1498Szrj y = y >> 1;
982*38fd1498Szrj
983*38fd1498Szrj /* k additional iterations where k regular test subtract shift
984*38fd1498Szrj dividend iterations are done. */
985*38fd1498Szrj i = k;
986*38fd1498Szrj do
987*38fd1498Szrj {
988*38fd1498Szrj if (r >= y)
989*38fd1498Szrj r = ((r - y) << 1) + 1;
990*38fd1498Szrj else
991*38fd1498Szrj r = (r << 1);
992*38fd1498Szrj i = i - 1;
993*38fd1498Szrj } while (i != 0);
994*38fd1498Szrj
995*38fd1498Szrj /* First quotient bit is combined with the quotient bits resulting
996*38fd1498Szrj from the k regular iterations. */
997*38fd1498Szrj q = q + r;
998*38fd1498Szrj r = r >> k;
999*38fd1498Szrj q = q - (r << k);
1000*38fd1498Szrj }
1001*38fd1498Szrj }
1002*38fd1498Szrj
1003*38fd1498Szrj if (rp)
1004*38fd1498Szrj *rp = r;
1005*38fd1498Szrj return q;
1006*38fd1498Szrj }
1007*38fd1498Szrj #else
1008*38fd1498Szrj
1009*38fd1498Szrj #if (defined (L_udivdi3) || defined (L_divdi3) || \
1010*38fd1498Szrj defined (L_umoddi3) || defined (L_moddi3) || \
1011*38fd1498Szrj defined (L_divmoddi4))
1012*38fd1498Szrj static inline __attribute__ ((__always_inline__))
1013*38fd1498Szrj #endif
1014*38fd1498Szrj UDWtype
__udivmoddi4(UDWtype n,UDWtype d,UDWtype * rp)1015*38fd1498Szrj __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
1016*38fd1498Szrj {
1017*38fd1498Szrj const DWunion nn = {.ll = n};
1018*38fd1498Szrj const DWunion dd = {.ll = d};
1019*38fd1498Szrj DWunion rr;
1020*38fd1498Szrj UWtype d0, d1, n0, n1, n2;
1021*38fd1498Szrj UWtype q0, q1;
1022*38fd1498Szrj UWtype b, bm;
1023*38fd1498Szrj
1024*38fd1498Szrj d0 = dd.s.low;
1025*38fd1498Szrj d1 = dd.s.high;
1026*38fd1498Szrj n0 = nn.s.low;
1027*38fd1498Szrj n1 = nn.s.high;
1028*38fd1498Szrj
1029*38fd1498Szrj #if !UDIV_NEEDS_NORMALIZATION
1030*38fd1498Szrj if (d1 == 0)
1031*38fd1498Szrj {
1032*38fd1498Szrj if (d0 > n1)
1033*38fd1498Szrj {
1034*38fd1498Szrj /* 0q = nn / 0D */
1035*38fd1498Szrj
1036*38fd1498Szrj udiv_qrnnd (q0, n0, n1, n0, d0);
1037*38fd1498Szrj q1 = 0;
1038*38fd1498Szrj
1039*38fd1498Szrj /* Remainder in n0. */
1040*38fd1498Szrj }
1041*38fd1498Szrj else
1042*38fd1498Szrj {
1043*38fd1498Szrj /* qq = NN / 0d */
1044*38fd1498Szrj
1045*38fd1498Szrj if (d0 == 0)
1046*38fd1498Szrj d0 = 1 / d0; /* Divide intentionally by zero. */
1047*38fd1498Szrj
1048*38fd1498Szrj udiv_qrnnd (q1, n1, 0, n1, d0);
1049*38fd1498Szrj udiv_qrnnd (q0, n0, n1, n0, d0);
1050*38fd1498Szrj
1051*38fd1498Szrj /* Remainder in n0. */
1052*38fd1498Szrj }
1053*38fd1498Szrj
1054*38fd1498Szrj if (rp != 0)
1055*38fd1498Szrj {
1056*38fd1498Szrj rr.s.low = n0;
1057*38fd1498Szrj rr.s.high = 0;
1058*38fd1498Szrj *rp = rr.ll;
1059*38fd1498Szrj }
1060*38fd1498Szrj }
1061*38fd1498Szrj
1062*38fd1498Szrj #else /* UDIV_NEEDS_NORMALIZATION */
1063*38fd1498Szrj
1064*38fd1498Szrj if (d1 == 0)
1065*38fd1498Szrj {
1066*38fd1498Szrj if (d0 > n1)
1067*38fd1498Szrj {
1068*38fd1498Szrj /* 0q = nn / 0D */
1069*38fd1498Szrj
1070*38fd1498Szrj count_leading_zeros (bm, d0);
1071*38fd1498Szrj
1072*38fd1498Szrj if (bm != 0)
1073*38fd1498Szrj {
1074*38fd1498Szrj /* Normalize, i.e. make the most significant bit of the
1075*38fd1498Szrj denominator set. */
1076*38fd1498Szrj
1077*38fd1498Szrj d0 = d0 << bm;
1078*38fd1498Szrj n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
1079*38fd1498Szrj n0 = n0 << bm;
1080*38fd1498Szrj }
1081*38fd1498Szrj
1082*38fd1498Szrj udiv_qrnnd (q0, n0, n1, n0, d0);
1083*38fd1498Szrj q1 = 0;
1084*38fd1498Szrj
1085*38fd1498Szrj /* Remainder in n0 >> bm. */
1086*38fd1498Szrj }
1087*38fd1498Szrj else
1088*38fd1498Szrj {
1089*38fd1498Szrj /* qq = NN / 0d */
1090*38fd1498Szrj
1091*38fd1498Szrj if (d0 == 0)
1092*38fd1498Szrj d0 = 1 / d0; /* Divide intentionally by zero. */
1093*38fd1498Szrj
1094*38fd1498Szrj count_leading_zeros (bm, d0);
1095*38fd1498Szrj
1096*38fd1498Szrj if (bm == 0)
1097*38fd1498Szrj {
1098*38fd1498Szrj /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
1099*38fd1498Szrj conclude (the most significant bit of n1 is set) /\ (the
1100*38fd1498Szrj leading quotient digit q1 = 1).
1101*38fd1498Szrj
1102*38fd1498Szrj This special case is necessary, not an optimization.
1103*38fd1498Szrj (Shifts counts of W_TYPE_SIZE are undefined.) */
1104*38fd1498Szrj
1105*38fd1498Szrj n1 -= d0;
1106*38fd1498Szrj q1 = 1;
1107*38fd1498Szrj }
1108*38fd1498Szrj else
1109*38fd1498Szrj {
1110*38fd1498Szrj /* Normalize. */
1111*38fd1498Szrj
1112*38fd1498Szrj b = W_TYPE_SIZE - bm;
1113*38fd1498Szrj
1114*38fd1498Szrj d0 = d0 << bm;
1115*38fd1498Szrj n2 = n1 >> b;
1116*38fd1498Szrj n1 = (n1 << bm) | (n0 >> b);
1117*38fd1498Szrj n0 = n0 << bm;
1118*38fd1498Szrj
1119*38fd1498Szrj udiv_qrnnd (q1, n1, n2, n1, d0);
1120*38fd1498Szrj }
1121*38fd1498Szrj
1122*38fd1498Szrj /* n1 != d0... */
1123*38fd1498Szrj
1124*38fd1498Szrj udiv_qrnnd (q0, n0, n1, n0, d0);
1125*38fd1498Szrj
1126*38fd1498Szrj /* Remainder in n0 >> bm. */
1127*38fd1498Szrj }
1128*38fd1498Szrj
1129*38fd1498Szrj if (rp != 0)
1130*38fd1498Szrj {
1131*38fd1498Szrj rr.s.low = n0 >> bm;
1132*38fd1498Szrj rr.s.high = 0;
1133*38fd1498Szrj *rp = rr.ll;
1134*38fd1498Szrj }
1135*38fd1498Szrj }
1136*38fd1498Szrj #endif /* UDIV_NEEDS_NORMALIZATION */
1137*38fd1498Szrj
1138*38fd1498Szrj else
1139*38fd1498Szrj {
1140*38fd1498Szrj if (d1 > n1)
1141*38fd1498Szrj {
1142*38fd1498Szrj /* 00 = nn / DD */
1143*38fd1498Szrj
1144*38fd1498Szrj q0 = 0;
1145*38fd1498Szrj q1 = 0;
1146*38fd1498Szrj
1147*38fd1498Szrj /* Remainder in n1n0. */
1148*38fd1498Szrj if (rp != 0)
1149*38fd1498Szrj {
1150*38fd1498Szrj rr.s.low = n0;
1151*38fd1498Szrj rr.s.high = n1;
1152*38fd1498Szrj *rp = rr.ll;
1153*38fd1498Szrj }
1154*38fd1498Szrj }
1155*38fd1498Szrj else
1156*38fd1498Szrj {
1157*38fd1498Szrj /* 0q = NN / dd */
1158*38fd1498Szrj
1159*38fd1498Szrj count_leading_zeros (bm, d1);
1160*38fd1498Szrj if (bm == 0)
1161*38fd1498Szrj {
1162*38fd1498Szrj /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
1163*38fd1498Szrj conclude (the most significant bit of n1 is set) /\ (the
1164*38fd1498Szrj quotient digit q0 = 0 or 1).
1165*38fd1498Szrj
1166*38fd1498Szrj This special case is necessary, not an optimization. */
1167*38fd1498Szrj
1168*38fd1498Szrj /* The condition on the next line takes advantage of that
1169*38fd1498Szrj n1 >= d1 (true due to program flow). */
1170*38fd1498Szrj if (n1 > d1 || n0 >= d0)
1171*38fd1498Szrj {
1172*38fd1498Szrj q0 = 1;
1173*38fd1498Szrj sub_ddmmss (n1, n0, n1, n0, d1, d0);
1174*38fd1498Szrj }
1175*38fd1498Szrj else
1176*38fd1498Szrj q0 = 0;
1177*38fd1498Szrj
1178*38fd1498Szrj q1 = 0;
1179*38fd1498Szrj
1180*38fd1498Szrj if (rp != 0)
1181*38fd1498Szrj {
1182*38fd1498Szrj rr.s.low = n0;
1183*38fd1498Szrj rr.s.high = n1;
1184*38fd1498Szrj *rp = rr.ll;
1185*38fd1498Szrj }
1186*38fd1498Szrj }
1187*38fd1498Szrj else
1188*38fd1498Szrj {
1189*38fd1498Szrj UWtype m1, m0;
1190*38fd1498Szrj /* Normalize. */
1191*38fd1498Szrj
1192*38fd1498Szrj b = W_TYPE_SIZE - bm;
1193*38fd1498Szrj
1194*38fd1498Szrj d1 = (d1 << bm) | (d0 >> b);
1195*38fd1498Szrj d0 = d0 << bm;
1196*38fd1498Szrj n2 = n1 >> b;
1197*38fd1498Szrj n1 = (n1 << bm) | (n0 >> b);
1198*38fd1498Szrj n0 = n0 << bm;
1199*38fd1498Szrj
1200*38fd1498Szrj udiv_qrnnd (q0, n1, n2, n1, d1);
1201*38fd1498Szrj umul_ppmm (m1, m0, q0, d0);
1202*38fd1498Szrj
1203*38fd1498Szrj if (m1 > n1 || (m1 == n1 && m0 > n0))
1204*38fd1498Szrj {
1205*38fd1498Szrj q0--;
1206*38fd1498Szrj sub_ddmmss (m1, m0, m1, m0, d1, d0);
1207*38fd1498Szrj }
1208*38fd1498Szrj
1209*38fd1498Szrj q1 = 0;
1210*38fd1498Szrj
1211*38fd1498Szrj /* Remainder in (n1n0 - m1m0) >> bm. */
1212*38fd1498Szrj if (rp != 0)
1213*38fd1498Szrj {
1214*38fd1498Szrj sub_ddmmss (n1, n0, n1, n0, m1, m0);
1215*38fd1498Szrj rr.s.low = (n1 << b) | (n0 >> bm);
1216*38fd1498Szrj rr.s.high = n1 >> bm;
1217*38fd1498Szrj *rp = rr.ll;
1218*38fd1498Szrj }
1219*38fd1498Szrj }
1220*38fd1498Szrj }
1221*38fd1498Szrj }
1222*38fd1498Szrj
1223*38fd1498Szrj const DWunion ww = {{.low = q0, .high = q1}};
1224*38fd1498Szrj return ww.ll;
1225*38fd1498Szrj }
1226*38fd1498Szrj #endif
1227*38fd1498Szrj #endif
1228*38fd1498Szrj
1229*38fd1498Szrj #ifdef L_divdi3
1230*38fd1498Szrj DWtype
__divdi3(DWtype u,DWtype v)1231*38fd1498Szrj __divdi3 (DWtype u, DWtype v)
1232*38fd1498Szrj {
1233*38fd1498Szrj Wtype c = 0;
1234*38fd1498Szrj DWunion uu = {.ll = u};
1235*38fd1498Szrj DWunion vv = {.ll = v};
1236*38fd1498Szrj DWtype w;
1237*38fd1498Szrj
1238*38fd1498Szrj if (uu.s.high < 0)
1239*38fd1498Szrj c = ~c,
1240*38fd1498Szrj uu.ll = -uu.ll;
1241*38fd1498Szrj if (vv.s.high < 0)
1242*38fd1498Szrj c = ~c,
1243*38fd1498Szrj vv.ll = -vv.ll;
1244*38fd1498Szrj
1245*38fd1498Szrj w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) 0);
1246*38fd1498Szrj if (c)
1247*38fd1498Szrj w = -w;
1248*38fd1498Szrj
1249*38fd1498Szrj return w;
1250*38fd1498Szrj }
1251*38fd1498Szrj #endif
1252*38fd1498Szrj
1253*38fd1498Szrj #ifdef L_moddi3
1254*38fd1498Szrj DWtype
__moddi3(DWtype u,DWtype v)1255*38fd1498Szrj __moddi3 (DWtype u, DWtype v)
1256*38fd1498Szrj {
1257*38fd1498Szrj Wtype c = 0;
1258*38fd1498Szrj DWunion uu = {.ll = u};
1259*38fd1498Szrj DWunion vv = {.ll = v};
1260*38fd1498Szrj DWtype w;
1261*38fd1498Szrj
1262*38fd1498Szrj if (uu.s.high < 0)
1263*38fd1498Szrj c = ~c,
1264*38fd1498Szrj uu.ll = -uu.ll;
1265*38fd1498Szrj if (vv.s.high < 0)
1266*38fd1498Szrj vv.ll = -vv.ll;
1267*38fd1498Szrj
1268*38fd1498Szrj (void) __udivmoddi4 (uu.ll, vv.ll, (UDWtype*)&w);
1269*38fd1498Szrj if (c)
1270*38fd1498Szrj w = -w;
1271*38fd1498Szrj
1272*38fd1498Szrj return w;
1273*38fd1498Szrj }
1274*38fd1498Szrj #endif
1275*38fd1498Szrj
1276*38fd1498Szrj #ifdef L_divmoddi4
1277*38fd1498Szrj DWtype
__divmoddi4(DWtype u,DWtype v,DWtype * rp)1278*38fd1498Szrj __divmoddi4 (DWtype u, DWtype v, DWtype *rp)
1279*38fd1498Szrj {
1280*38fd1498Szrj Wtype c1 = 0, c2 = 0;
1281*38fd1498Szrj DWunion uu = {.ll = u};
1282*38fd1498Szrj DWunion vv = {.ll = v};
1283*38fd1498Szrj DWtype w;
1284*38fd1498Szrj DWtype r;
1285*38fd1498Szrj
1286*38fd1498Szrj if (uu.s.high < 0)
1287*38fd1498Szrj c1 = ~c1, c2 = ~c2,
1288*38fd1498Szrj uu.ll = -uu.ll;
1289*38fd1498Szrj if (vv.s.high < 0)
1290*38fd1498Szrj c1 = ~c1,
1291*38fd1498Szrj vv.ll = -vv.ll;
1292*38fd1498Szrj
1293*38fd1498Szrj w = __udivmoddi4 (uu.ll, vv.ll, (UDWtype*)&r);
1294*38fd1498Szrj if (c1)
1295*38fd1498Szrj w = -w;
1296*38fd1498Szrj if (c2)
1297*38fd1498Szrj r = -r;
1298*38fd1498Szrj
1299*38fd1498Szrj *rp = r;
1300*38fd1498Szrj return w;
1301*38fd1498Szrj }
1302*38fd1498Szrj #endif
1303*38fd1498Szrj
1304*38fd1498Szrj #ifdef L_umoddi3
1305*38fd1498Szrj UDWtype
__umoddi3(UDWtype u,UDWtype v)1306*38fd1498Szrj __umoddi3 (UDWtype u, UDWtype v)
1307*38fd1498Szrj {
1308*38fd1498Szrj UDWtype w;
1309*38fd1498Szrj
1310*38fd1498Szrj (void) __udivmoddi4 (u, v, &w);
1311*38fd1498Szrj
1312*38fd1498Szrj return w;
1313*38fd1498Szrj }
1314*38fd1498Szrj #endif
1315*38fd1498Szrj
1316*38fd1498Szrj #ifdef L_udivdi3
1317*38fd1498Szrj UDWtype
__udivdi3(UDWtype n,UDWtype d)1318*38fd1498Szrj __udivdi3 (UDWtype n, UDWtype d)
1319*38fd1498Szrj {
1320*38fd1498Szrj return __udivmoddi4 (n, d, (UDWtype *) 0);
1321*38fd1498Szrj }
1322*38fd1498Szrj #endif
1323*38fd1498Szrj
1324*38fd1498Szrj #ifdef L_cmpdi2
1325*38fd1498Szrj cmp_return_type
__cmpdi2(DWtype a,DWtype b)1326*38fd1498Szrj __cmpdi2 (DWtype a, DWtype b)
1327*38fd1498Szrj {
1328*38fd1498Szrj const DWunion au = {.ll = a};
1329*38fd1498Szrj const DWunion bu = {.ll = b};
1330*38fd1498Szrj
1331*38fd1498Szrj if (au.s.high < bu.s.high)
1332*38fd1498Szrj return 0;
1333*38fd1498Szrj else if (au.s.high > bu.s.high)
1334*38fd1498Szrj return 2;
1335*38fd1498Szrj if ((UWtype) au.s.low < (UWtype) bu.s.low)
1336*38fd1498Szrj return 0;
1337*38fd1498Szrj else if ((UWtype) au.s.low > (UWtype) bu.s.low)
1338*38fd1498Szrj return 2;
1339*38fd1498Szrj return 1;
1340*38fd1498Szrj }
1341*38fd1498Szrj #endif
1342*38fd1498Szrj
1343*38fd1498Szrj #ifdef L_ucmpdi2
1344*38fd1498Szrj cmp_return_type
__ucmpdi2(DWtype a,DWtype b)1345*38fd1498Szrj __ucmpdi2 (DWtype a, DWtype b)
1346*38fd1498Szrj {
1347*38fd1498Szrj const DWunion au = {.ll = a};
1348*38fd1498Szrj const DWunion bu = {.ll = b};
1349*38fd1498Szrj
1350*38fd1498Szrj if ((UWtype) au.s.high < (UWtype) bu.s.high)
1351*38fd1498Szrj return 0;
1352*38fd1498Szrj else if ((UWtype) au.s.high > (UWtype) bu.s.high)
1353*38fd1498Szrj return 2;
1354*38fd1498Szrj if ((UWtype) au.s.low < (UWtype) bu.s.low)
1355*38fd1498Szrj return 0;
1356*38fd1498Szrj else if ((UWtype) au.s.low > (UWtype) bu.s.low)
1357*38fd1498Szrj return 2;
1358*38fd1498Szrj return 1;
1359*38fd1498Szrj }
1360*38fd1498Szrj #endif
1361*38fd1498Szrj
1362*38fd1498Szrj #if defined(L_fixunstfdi) && LIBGCC2_HAS_TF_MODE
1363*38fd1498Szrj UDWtype
__fixunstfDI(TFtype a)1364*38fd1498Szrj __fixunstfDI (TFtype a)
1365*38fd1498Szrj {
1366*38fd1498Szrj if (a < 0)
1367*38fd1498Szrj return 0;
1368*38fd1498Szrj
1369*38fd1498Szrj /* Compute high word of result, as a flonum. */
1370*38fd1498Szrj const TFtype b = (a / Wtype_MAXp1_F);
1371*38fd1498Szrj /* Convert that to fixed (but not to DWtype!),
1372*38fd1498Szrj and shift it into the high word. */
1373*38fd1498Szrj UDWtype v = (UWtype) b;
1374*38fd1498Szrj v <<= W_TYPE_SIZE;
1375*38fd1498Szrj /* Remove high part from the TFtype, leaving the low part as flonum. */
1376*38fd1498Szrj a -= (TFtype)v;
1377*38fd1498Szrj /* Convert that to fixed (but not to DWtype!) and add it in.
1378*38fd1498Szrj Sometimes A comes out negative. This is significant, since
1379*38fd1498Szrj A has more bits than a long int does. */
1380*38fd1498Szrj if (a < 0)
1381*38fd1498Szrj v -= (UWtype) (- a);
1382*38fd1498Szrj else
1383*38fd1498Szrj v += (UWtype) a;
1384*38fd1498Szrj return v;
1385*38fd1498Szrj }
1386*38fd1498Szrj #endif
1387*38fd1498Szrj
1388*38fd1498Szrj #if defined(L_fixtfdi) && LIBGCC2_HAS_TF_MODE
1389*38fd1498Szrj DWtype
__fixtfdi(TFtype a)1390*38fd1498Szrj __fixtfdi (TFtype a)
1391*38fd1498Szrj {
1392*38fd1498Szrj if (a < 0)
1393*38fd1498Szrj return - __fixunstfDI (-a);
1394*38fd1498Szrj return __fixunstfDI (a);
1395*38fd1498Szrj }
1396*38fd1498Szrj #endif
1397*38fd1498Szrj
1398*38fd1498Szrj #if defined(L_fixunsxfdi) && LIBGCC2_HAS_XF_MODE
1399*38fd1498Szrj UDWtype
__fixunsxfDI(XFtype a)1400*38fd1498Szrj __fixunsxfDI (XFtype a)
1401*38fd1498Szrj {
1402*38fd1498Szrj if (a < 0)
1403*38fd1498Szrj return 0;
1404*38fd1498Szrj
1405*38fd1498Szrj /* Compute high word of result, as a flonum. */
1406*38fd1498Szrj const XFtype b = (a / Wtype_MAXp1_F);
1407*38fd1498Szrj /* Convert that to fixed (but not to DWtype!),
1408*38fd1498Szrj and shift it into the high word. */
1409*38fd1498Szrj UDWtype v = (UWtype) b;
1410*38fd1498Szrj v <<= W_TYPE_SIZE;
1411*38fd1498Szrj /* Remove high part from the XFtype, leaving the low part as flonum. */
1412*38fd1498Szrj a -= (XFtype)v;
1413*38fd1498Szrj /* Convert that to fixed (but not to DWtype!) and add it in.
1414*38fd1498Szrj Sometimes A comes out negative. This is significant, since
1415*38fd1498Szrj A has more bits than a long int does. */
1416*38fd1498Szrj if (a < 0)
1417*38fd1498Szrj v -= (UWtype) (- a);
1418*38fd1498Szrj else
1419*38fd1498Szrj v += (UWtype) a;
1420*38fd1498Szrj return v;
1421*38fd1498Szrj }
1422*38fd1498Szrj #endif
1423*38fd1498Szrj
1424*38fd1498Szrj #if defined(L_fixxfdi) && LIBGCC2_HAS_XF_MODE
1425*38fd1498Szrj DWtype
__fixxfdi(XFtype a)1426*38fd1498Szrj __fixxfdi (XFtype a)
1427*38fd1498Szrj {
1428*38fd1498Szrj if (a < 0)
1429*38fd1498Szrj return - __fixunsxfDI (-a);
1430*38fd1498Szrj return __fixunsxfDI (a);
1431*38fd1498Szrj }
1432*38fd1498Szrj #endif
1433*38fd1498Szrj
1434*38fd1498Szrj #if defined(L_fixunsdfdi) && LIBGCC2_HAS_DF_MODE
1435*38fd1498Szrj UDWtype
__fixunsdfDI(DFtype a)1436*38fd1498Szrj __fixunsdfDI (DFtype a)
1437*38fd1498Szrj {
1438*38fd1498Szrj /* Get high part of result. The division here will just moves the radix
1439*38fd1498Szrj point and will not cause any rounding. Then the conversion to integral
1440*38fd1498Szrj type chops result as desired. */
1441*38fd1498Szrj const UWtype hi = a / Wtype_MAXp1_F;
1442*38fd1498Szrj
1443*38fd1498Szrj /* Get low part of result. Convert `hi' to floating type and scale it back,
1444*38fd1498Szrj then subtract this from the number being converted. This leaves the low
1445*38fd1498Szrj part. Convert that to integral type. */
1446*38fd1498Szrj const UWtype lo = a - (DFtype) hi * Wtype_MAXp1_F;
1447*38fd1498Szrj
1448*38fd1498Szrj /* Assemble result from the two parts. */
1449*38fd1498Szrj return ((UDWtype) hi << W_TYPE_SIZE) | lo;
1450*38fd1498Szrj }
1451*38fd1498Szrj #endif
1452*38fd1498Szrj
1453*38fd1498Szrj #if defined(L_fixdfdi) && LIBGCC2_HAS_DF_MODE
1454*38fd1498Szrj DWtype
__fixdfdi(DFtype a)1455*38fd1498Szrj __fixdfdi (DFtype a)
1456*38fd1498Szrj {
1457*38fd1498Szrj if (a < 0)
1458*38fd1498Szrj return - __fixunsdfDI (-a);
1459*38fd1498Szrj return __fixunsdfDI (a);
1460*38fd1498Szrj }
1461*38fd1498Szrj #endif
1462*38fd1498Szrj
1463*38fd1498Szrj #if defined(L_fixunssfdi) && LIBGCC2_HAS_SF_MODE
1464*38fd1498Szrj UDWtype
__fixunssfDI(SFtype a)1465*38fd1498Szrj __fixunssfDI (SFtype a)
1466*38fd1498Szrj {
1467*38fd1498Szrj #if LIBGCC2_HAS_DF_MODE
1468*38fd1498Szrj /* Convert the SFtype to a DFtype, because that is surely not going
1469*38fd1498Szrj to lose any bits. Some day someone else can write a faster version
1470*38fd1498Szrj that avoids converting to DFtype, and verify it really works right. */
1471*38fd1498Szrj const DFtype dfa = a;
1472*38fd1498Szrj
1473*38fd1498Szrj /* Get high part of result. The division here will just moves the radix
1474*38fd1498Szrj point and will not cause any rounding. Then the conversion to integral
1475*38fd1498Szrj type chops result as desired. */
1476*38fd1498Szrj const UWtype hi = dfa / Wtype_MAXp1_F;
1477*38fd1498Szrj
1478*38fd1498Szrj /* Get low part of result. Convert `hi' to floating type and scale it back,
1479*38fd1498Szrj then subtract this from the number being converted. This leaves the low
1480*38fd1498Szrj part. Convert that to integral type. */
1481*38fd1498Szrj const UWtype lo = dfa - (DFtype) hi * Wtype_MAXp1_F;
1482*38fd1498Szrj
1483*38fd1498Szrj /* Assemble result from the two parts. */
1484*38fd1498Szrj return ((UDWtype) hi << W_TYPE_SIZE) | lo;
1485*38fd1498Szrj #elif FLT_MANT_DIG < W_TYPE_SIZE
1486*38fd1498Szrj if (a < 1)
1487*38fd1498Szrj return 0;
1488*38fd1498Szrj if (a < Wtype_MAXp1_F)
1489*38fd1498Szrj return (UWtype)a;
1490*38fd1498Szrj if (a < Wtype_MAXp1_F * Wtype_MAXp1_F)
1491*38fd1498Szrj {
1492*38fd1498Szrj /* Since we know that there are fewer significant bits in the SFmode
1493*38fd1498Szrj quantity than in a word, we know that we can convert out all the
1494*38fd1498Szrj significant bits in one step, and thus avoid losing bits. */
1495*38fd1498Szrj
1496*38fd1498Szrj /* ??? This following loop essentially performs frexpf. If we could
1497*38fd1498Szrj use the real libm function, or poke at the actual bits of the fp
1498*38fd1498Szrj format, it would be significantly faster. */
1499*38fd1498Szrj
1500*38fd1498Szrj UWtype shift = 0, counter;
1501*38fd1498Szrj SFtype msb;
1502*38fd1498Szrj
1503*38fd1498Szrj a /= Wtype_MAXp1_F;
1504*38fd1498Szrj for (counter = W_TYPE_SIZE / 2; counter != 0; counter >>= 1)
1505*38fd1498Szrj {
1506*38fd1498Szrj SFtype counterf = (UWtype)1 << counter;
1507*38fd1498Szrj if (a >= counterf)
1508*38fd1498Szrj {
1509*38fd1498Szrj shift |= counter;
1510*38fd1498Szrj a /= counterf;
1511*38fd1498Szrj }
1512*38fd1498Szrj }
1513*38fd1498Szrj
1514*38fd1498Szrj /* Rescale into the range of one word, extract the bits of that
1515*38fd1498Szrj one word, and shift the result into position. */
1516*38fd1498Szrj a *= Wtype_MAXp1_F;
1517*38fd1498Szrj counter = a;
1518*38fd1498Szrj return (DWtype)counter << shift;
1519*38fd1498Szrj }
1520*38fd1498Szrj return -1;
1521*38fd1498Szrj #else
1522*38fd1498Szrj # error
1523*38fd1498Szrj #endif
1524*38fd1498Szrj }
1525*38fd1498Szrj #endif
1526*38fd1498Szrj
1527*38fd1498Szrj #if defined(L_fixsfdi) && LIBGCC2_HAS_SF_MODE
1528*38fd1498Szrj DWtype
__fixsfdi(SFtype a)1529*38fd1498Szrj __fixsfdi (SFtype a)
1530*38fd1498Szrj {
1531*38fd1498Szrj if (a < 0)
1532*38fd1498Szrj return - __fixunssfDI (-a);
1533*38fd1498Szrj return __fixunssfDI (a);
1534*38fd1498Szrj }
1535*38fd1498Szrj #endif
1536*38fd1498Szrj
1537*38fd1498Szrj #if defined(L_floatdixf) && LIBGCC2_HAS_XF_MODE
1538*38fd1498Szrj XFtype
__floatdixf(DWtype u)1539*38fd1498Szrj __floatdixf (DWtype u)
1540*38fd1498Szrj {
1541*38fd1498Szrj #if W_TYPE_SIZE > __LIBGCC_XF_MANT_DIG__
1542*38fd1498Szrj # error
1543*38fd1498Szrj #endif
1544*38fd1498Szrj XFtype d = (Wtype) (u >> W_TYPE_SIZE);
1545*38fd1498Szrj d *= Wtype_MAXp1_F;
1546*38fd1498Szrj d += (UWtype)u;
1547*38fd1498Szrj return d;
1548*38fd1498Szrj }
1549*38fd1498Szrj #endif
1550*38fd1498Szrj
1551*38fd1498Szrj #if defined(L_floatundixf) && LIBGCC2_HAS_XF_MODE
1552*38fd1498Szrj XFtype
__floatundixf(UDWtype u)1553*38fd1498Szrj __floatundixf (UDWtype u)
1554*38fd1498Szrj {
1555*38fd1498Szrj #if W_TYPE_SIZE > __LIBGCC_XF_MANT_DIG__
1556*38fd1498Szrj # error
1557*38fd1498Szrj #endif
1558*38fd1498Szrj XFtype d = (UWtype) (u >> W_TYPE_SIZE);
1559*38fd1498Szrj d *= Wtype_MAXp1_F;
1560*38fd1498Szrj d += (UWtype)u;
1561*38fd1498Szrj return d;
1562*38fd1498Szrj }
1563*38fd1498Szrj #endif
1564*38fd1498Szrj
1565*38fd1498Szrj #if defined(L_floatditf) && LIBGCC2_HAS_TF_MODE
1566*38fd1498Szrj TFtype
__floatditf(DWtype u)1567*38fd1498Szrj __floatditf (DWtype u)
1568*38fd1498Szrj {
1569*38fd1498Szrj #if W_TYPE_SIZE > __LIBGCC_TF_MANT_DIG__
1570*38fd1498Szrj # error
1571*38fd1498Szrj #endif
1572*38fd1498Szrj TFtype d = (Wtype) (u >> W_TYPE_SIZE);
1573*38fd1498Szrj d *= Wtype_MAXp1_F;
1574*38fd1498Szrj d += (UWtype)u;
1575*38fd1498Szrj return d;
1576*38fd1498Szrj }
1577*38fd1498Szrj #endif
1578*38fd1498Szrj
1579*38fd1498Szrj #if defined(L_floatunditf) && LIBGCC2_HAS_TF_MODE
1580*38fd1498Szrj TFtype
__floatunditf(UDWtype u)1581*38fd1498Szrj __floatunditf (UDWtype u)
1582*38fd1498Szrj {
1583*38fd1498Szrj #if W_TYPE_SIZE > __LIBGCC_TF_MANT_DIG__
1584*38fd1498Szrj # error
1585*38fd1498Szrj #endif
1586*38fd1498Szrj TFtype d = (UWtype) (u >> W_TYPE_SIZE);
1587*38fd1498Szrj d *= Wtype_MAXp1_F;
1588*38fd1498Szrj d += (UWtype)u;
1589*38fd1498Szrj return d;
1590*38fd1498Szrj }
1591*38fd1498Szrj #endif
1592*38fd1498Szrj
1593*38fd1498Szrj #if (defined(L_floatdisf) && LIBGCC2_HAS_SF_MODE) \
1594*38fd1498Szrj || (defined(L_floatdidf) && LIBGCC2_HAS_DF_MODE)
1595*38fd1498Szrj #define DI_SIZE (W_TYPE_SIZE * 2)
1596*38fd1498Szrj #define F_MODE_OK(SIZE) \
1597*38fd1498Szrj (SIZE < DI_SIZE \
1598*38fd1498Szrj && SIZE > (DI_SIZE - SIZE + FSSIZE) \
1599*38fd1498Szrj && !AVOID_FP_TYPE_CONVERSION(SIZE))
1600*38fd1498Szrj #if defined(L_floatdisf)
1601*38fd1498Szrj #define FUNC __floatdisf
1602*38fd1498Szrj #define FSTYPE SFtype
1603*38fd1498Szrj #define FSSIZE __LIBGCC_SF_MANT_DIG__
1604*38fd1498Szrj #else
1605*38fd1498Szrj #define FUNC __floatdidf
1606*38fd1498Szrj #define FSTYPE DFtype
1607*38fd1498Szrj #define FSSIZE __LIBGCC_DF_MANT_DIG__
1608*38fd1498Szrj #endif
1609*38fd1498Szrj
1610*38fd1498Szrj FSTYPE
FUNC(DWtype u)1611*38fd1498Szrj FUNC (DWtype u)
1612*38fd1498Szrj {
1613*38fd1498Szrj #if FSSIZE >= W_TYPE_SIZE
1614*38fd1498Szrj /* When the word size is small, we never get any rounding error. */
1615*38fd1498Szrj FSTYPE f = (Wtype) (u >> W_TYPE_SIZE);
1616*38fd1498Szrj f *= Wtype_MAXp1_F;
1617*38fd1498Szrj f += (UWtype)u;
1618*38fd1498Szrj return f;
1619*38fd1498Szrj #elif (LIBGCC2_HAS_DF_MODE && F_MODE_OK (__LIBGCC_DF_MANT_DIG__)) \
1620*38fd1498Szrj || (LIBGCC2_HAS_XF_MODE && F_MODE_OK (__LIBGCC_XF_MANT_DIG__)) \
1621*38fd1498Szrj || (LIBGCC2_HAS_TF_MODE && F_MODE_OK (__LIBGCC_TF_MANT_DIG__))
1622*38fd1498Szrj
1623*38fd1498Szrj #if (LIBGCC2_HAS_DF_MODE && F_MODE_OK (__LIBGCC_DF_MANT_DIG__))
1624*38fd1498Szrj # define FSIZE __LIBGCC_DF_MANT_DIG__
1625*38fd1498Szrj # define FTYPE DFtype
1626*38fd1498Szrj #elif (LIBGCC2_HAS_XF_MODE && F_MODE_OK (__LIBGCC_XF_MANT_DIG__))
1627*38fd1498Szrj # define FSIZE __LIBGCC_XF_MANT_DIG__
1628*38fd1498Szrj # define FTYPE XFtype
1629*38fd1498Szrj #elif (LIBGCC2_HAS_TF_MODE && F_MODE_OK (__LIBGCC_TF_MANT_DIG__))
1630*38fd1498Szrj # define FSIZE __LIBGCC_TF_MANT_DIG__
1631*38fd1498Szrj # define FTYPE TFtype
1632*38fd1498Szrj #else
1633*38fd1498Szrj # error
1634*38fd1498Szrj #endif
1635*38fd1498Szrj
1636*38fd1498Szrj #define REP_BIT ((UDWtype) 1 << (DI_SIZE - FSIZE))
1637*38fd1498Szrj
1638*38fd1498Szrj /* Protect against double-rounding error.
1639*38fd1498Szrj Represent any low-order bits, that might be truncated by a bit that
1640*38fd1498Szrj won't be lost. The bit can go in anywhere below the rounding position
1641*38fd1498Szrj of the FSTYPE. A fixed mask and bit position handles all usual
1642*38fd1498Szrj configurations. */
1643*38fd1498Szrj if (! (- ((DWtype) 1 << FSIZE) < u
1644*38fd1498Szrj && u < ((DWtype) 1 << FSIZE)))
1645*38fd1498Szrj {
1646*38fd1498Szrj if ((UDWtype) u & (REP_BIT - 1))
1647*38fd1498Szrj {
1648*38fd1498Szrj u &= ~ (REP_BIT - 1);
1649*38fd1498Szrj u |= REP_BIT;
1650*38fd1498Szrj }
1651*38fd1498Szrj }
1652*38fd1498Szrj
1653*38fd1498Szrj /* Do the calculation in a wider type so that we don't lose any of
1654*38fd1498Szrj the precision of the high word while multiplying it. */
1655*38fd1498Szrj FTYPE f = (Wtype) (u >> W_TYPE_SIZE);
1656*38fd1498Szrj f *= Wtype_MAXp1_F;
1657*38fd1498Szrj f += (UWtype)u;
1658*38fd1498Szrj return (FSTYPE) f;
1659*38fd1498Szrj #else
1660*38fd1498Szrj #if FSSIZE >= W_TYPE_SIZE - 2
1661*38fd1498Szrj # error
1662*38fd1498Szrj #endif
1663*38fd1498Szrj /* Finally, the word size is larger than the number of bits in the
1664*38fd1498Szrj required FSTYPE, and we've got no suitable wider type. The only
1665*38fd1498Szrj way to avoid double rounding is to special case the
1666*38fd1498Szrj extraction. */
1667*38fd1498Szrj
1668*38fd1498Szrj /* If there are no high bits set, fall back to one conversion. */
1669*38fd1498Szrj if ((Wtype)u == u)
1670*38fd1498Szrj return (FSTYPE)(Wtype)u;
1671*38fd1498Szrj
1672*38fd1498Szrj /* Otherwise, find the power of two. */
1673*38fd1498Szrj Wtype hi = u >> W_TYPE_SIZE;
1674*38fd1498Szrj if (hi < 0)
1675*38fd1498Szrj hi = -(UWtype) hi;
1676*38fd1498Szrj
1677*38fd1498Szrj UWtype count, shift;
1678*38fd1498Szrj #if !defined (COUNT_LEADING_ZEROS_0) || COUNT_LEADING_ZEROS_0 != W_TYPE_SIZE
1679*38fd1498Szrj if (hi == 0)
1680*38fd1498Szrj count = W_TYPE_SIZE;
1681*38fd1498Szrj else
1682*38fd1498Szrj #endif
1683*38fd1498Szrj count_leading_zeros (count, hi);
1684*38fd1498Szrj
1685*38fd1498Szrj /* No leading bits means u == minimum. */
1686*38fd1498Szrj if (count == 0)
1687*38fd1498Szrj return -(Wtype_MAXp1_F * (Wtype_MAXp1_F / 2));
1688*38fd1498Szrj
1689*38fd1498Szrj shift = 1 + W_TYPE_SIZE - count;
1690*38fd1498Szrj
1691*38fd1498Szrj /* Shift down the most significant bits. */
1692*38fd1498Szrj hi = u >> shift;
1693*38fd1498Szrj
1694*38fd1498Szrj /* If we lost any nonzero bits, set the lsb to ensure correct rounding. */
1695*38fd1498Szrj if ((UWtype)u << (W_TYPE_SIZE - shift))
1696*38fd1498Szrj hi |= 1;
1697*38fd1498Szrj
1698*38fd1498Szrj /* Convert the one word of data, and rescale. */
1699*38fd1498Szrj FSTYPE f = hi, e;
1700*38fd1498Szrj if (shift == W_TYPE_SIZE)
1701*38fd1498Szrj e = Wtype_MAXp1_F;
1702*38fd1498Szrj /* The following two cases could be merged if we knew that the target
1703*38fd1498Szrj supported a native unsigned->float conversion. More often, we only
1704*38fd1498Szrj have a signed conversion, and have to add extra fixup code. */
1705*38fd1498Szrj else if (shift == W_TYPE_SIZE - 1)
1706*38fd1498Szrj e = Wtype_MAXp1_F / 2;
1707*38fd1498Szrj else
1708*38fd1498Szrj e = (Wtype)1 << shift;
1709*38fd1498Szrj return f * e;
1710*38fd1498Szrj #endif
1711*38fd1498Szrj }
1712*38fd1498Szrj #endif
1713*38fd1498Szrj
1714*38fd1498Szrj #if (defined(L_floatundisf) && LIBGCC2_HAS_SF_MODE) \
1715*38fd1498Szrj || (defined(L_floatundidf) && LIBGCC2_HAS_DF_MODE)
1716*38fd1498Szrj #define DI_SIZE (W_TYPE_SIZE * 2)
1717*38fd1498Szrj #define F_MODE_OK(SIZE) \
1718*38fd1498Szrj (SIZE < DI_SIZE \
1719*38fd1498Szrj && SIZE > (DI_SIZE - SIZE + FSSIZE) \
1720*38fd1498Szrj && !AVOID_FP_TYPE_CONVERSION(SIZE))
1721*38fd1498Szrj #if defined(L_floatundisf)
1722*38fd1498Szrj #define FUNC __floatundisf
1723*38fd1498Szrj #define FSTYPE SFtype
1724*38fd1498Szrj #define FSSIZE __LIBGCC_SF_MANT_DIG__
1725*38fd1498Szrj #else
1726*38fd1498Szrj #define FUNC __floatundidf
1727*38fd1498Szrj #define FSTYPE DFtype
1728*38fd1498Szrj #define FSSIZE __LIBGCC_DF_MANT_DIG__
1729*38fd1498Szrj #endif
1730*38fd1498Szrj
1731*38fd1498Szrj FSTYPE
FUNC(UDWtype u)1732*38fd1498Szrj FUNC (UDWtype u)
1733*38fd1498Szrj {
1734*38fd1498Szrj #if FSSIZE >= W_TYPE_SIZE
1735*38fd1498Szrj /* When the word size is small, we never get any rounding error. */
1736*38fd1498Szrj FSTYPE f = (UWtype) (u >> W_TYPE_SIZE);
1737*38fd1498Szrj f *= Wtype_MAXp1_F;
1738*38fd1498Szrj f += (UWtype)u;
1739*38fd1498Szrj return f;
1740*38fd1498Szrj #elif (LIBGCC2_HAS_DF_MODE && F_MODE_OK (__LIBGCC_DF_MANT_DIG__)) \
1741*38fd1498Szrj || (LIBGCC2_HAS_XF_MODE && F_MODE_OK (__LIBGCC_XF_MANT_DIG__)) \
1742*38fd1498Szrj || (LIBGCC2_HAS_TF_MODE && F_MODE_OK (__LIBGCC_TF_MANT_DIG__))
1743*38fd1498Szrj
1744*38fd1498Szrj #if (LIBGCC2_HAS_DF_MODE && F_MODE_OK (__LIBGCC_DF_MANT_DIG__))
1745*38fd1498Szrj # define FSIZE __LIBGCC_DF_MANT_DIG__
1746*38fd1498Szrj # define FTYPE DFtype
1747*38fd1498Szrj #elif (LIBGCC2_HAS_XF_MODE && F_MODE_OK (__LIBGCC_XF_MANT_DIG__))
1748*38fd1498Szrj # define FSIZE __LIBGCC_XF_MANT_DIG__
1749*38fd1498Szrj # define FTYPE XFtype
1750*38fd1498Szrj #elif (LIBGCC2_HAS_TF_MODE && F_MODE_OK (__LIBGCC_TF_MANT_DIG__))
1751*38fd1498Szrj # define FSIZE __LIBGCC_TF_MANT_DIG__
1752*38fd1498Szrj # define FTYPE TFtype
1753*38fd1498Szrj #else
1754*38fd1498Szrj # error
1755*38fd1498Szrj #endif
1756*38fd1498Szrj
1757*38fd1498Szrj #define REP_BIT ((UDWtype) 1 << (DI_SIZE - FSIZE))
1758*38fd1498Szrj
1759*38fd1498Szrj /* Protect against double-rounding error.
1760*38fd1498Szrj Represent any low-order bits, that might be truncated by a bit that
1761*38fd1498Szrj won't be lost. The bit can go in anywhere below the rounding position
1762*38fd1498Szrj of the FSTYPE. A fixed mask and bit position handles all usual
1763*38fd1498Szrj configurations. */
1764*38fd1498Szrj if (u >= ((UDWtype) 1 << FSIZE))
1765*38fd1498Szrj {
1766*38fd1498Szrj if ((UDWtype) u & (REP_BIT - 1))
1767*38fd1498Szrj {
1768*38fd1498Szrj u &= ~ (REP_BIT - 1);
1769*38fd1498Szrj u |= REP_BIT;
1770*38fd1498Szrj }
1771*38fd1498Szrj }
1772*38fd1498Szrj
1773*38fd1498Szrj /* Do the calculation in a wider type so that we don't lose any of
1774*38fd1498Szrj the precision of the high word while multiplying it. */
1775*38fd1498Szrj FTYPE f = (UWtype) (u >> W_TYPE_SIZE);
1776*38fd1498Szrj f *= Wtype_MAXp1_F;
1777*38fd1498Szrj f += (UWtype)u;
1778*38fd1498Szrj return (FSTYPE) f;
1779*38fd1498Szrj #else
1780*38fd1498Szrj #if FSSIZE == W_TYPE_SIZE - 1
1781*38fd1498Szrj # error
1782*38fd1498Szrj #endif
1783*38fd1498Szrj /* Finally, the word size is larger than the number of bits in the
1784*38fd1498Szrj required FSTYPE, and we've got no suitable wider type. The only
1785*38fd1498Szrj way to avoid double rounding is to special case the
1786*38fd1498Szrj extraction. */
1787*38fd1498Szrj
1788*38fd1498Szrj /* If there are no high bits set, fall back to one conversion. */
1789*38fd1498Szrj if ((UWtype)u == u)
1790*38fd1498Szrj return (FSTYPE)(UWtype)u;
1791*38fd1498Szrj
1792*38fd1498Szrj /* Otherwise, find the power of two. */
1793*38fd1498Szrj UWtype hi = u >> W_TYPE_SIZE;
1794*38fd1498Szrj
1795*38fd1498Szrj UWtype count, shift;
1796*38fd1498Szrj count_leading_zeros (count, hi);
1797*38fd1498Szrj
1798*38fd1498Szrj shift = W_TYPE_SIZE - count;
1799*38fd1498Szrj
1800*38fd1498Szrj /* Shift down the most significant bits. */
1801*38fd1498Szrj hi = u >> shift;
1802*38fd1498Szrj
1803*38fd1498Szrj /* If we lost any nonzero bits, set the lsb to ensure correct rounding. */
1804*38fd1498Szrj if ((UWtype)u << (W_TYPE_SIZE - shift))
1805*38fd1498Szrj hi |= 1;
1806*38fd1498Szrj
1807*38fd1498Szrj /* Convert the one word of data, and rescale. */
1808*38fd1498Szrj FSTYPE f = hi, e;
1809*38fd1498Szrj if (shift == W_TYPE_SIZE)
1810*38fd1498Szrj e = Wtype_MAXp1_F;
1811*38fd1498Szrj /* The following two cases could be merged if we knew that the target
1812*38fd1498Szrj supported a native unsigned->float conversion. More often, we only
1813*38fd1498Szrj have a signed conversion, and have to add extra fixup code. */
1814*38fd1498Szrj else if (shift == W_TYPE_SIZE - 1)
1815*38fd1498Szrj e = Wtype_MAXp1_F / 2;
1816*38fd1498Szrj else
1817*38fd1498Szrj e = (Wtype)1 << shift;
1818*38fd1498Szrj return f * e;
1819*38fd1498Szrj #endif
1820*38fd1498Szrj }
1821*38fd1498Szrj #endif
1822*38fd1498Szrj
1823*38fd1498Szrj #if defined(L_fixunsxfsi) && LIBGCC2_HAS_XF_MODE
1824*38fd1498Szrj UWtype
__fixunsxfSI(XFtype a)1825*38fd1498Szrj __fixunsxfSI (XFtype a)
1826*38fd1498Szrj {
1827*38fd1498Szrj if (a >= - (DFtype) Wtype_MIN)
1828*38fd1498Szrj return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1829*38fd1498Szrj return (Wtype) a;
1830*38fd1498Szrj }
1831*38fd1498Szrj #endif
1832*38fd1498Szrj
1833*38fd1498Szrj #if defined(L_fixunsdfsi) && LIBGCC2_HAS_DF_MODE
1834*38fd1498Szrj UWtype
__fixunsdfSI(DFtype a)1835*38fd1498Szrj __fixunsdfSI (DFtype a)
1836*38fd1498Szrj {
1837*38fd1498Szrj if (a >= - (DFtype) Wtype_MIN)
1838*38fd1498Szrj return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1839*38fd1498Szrj return (Wtype) a;
1840*38fd1498Szrj }
1841*38fd1498Szrj #endif
1842*38fd1498Szrj
1843*38fd1498Szrj #if defined(L_fixunssfsi) && LIBGCC2_HAS_SF_MODE
1844*38fd1498Szrj UWtype
__fixunssfSI(SFtype a)1845*38fd1498Szrj __fixunssfSI (SFtype a)
1846*38fd1498Szrj {
1847*38fd1498Szrj if (a >= - (SFtype) Wtype_MIN)
1848*38fd1498Szrj return (Wtype) (a + Wtype_MIN) - Wtype_MIN;
1849*38fd1498Szrj return (Wtype) a;
1850*38fd1498Szrj }
1851*38fd1498Szrj #endif
1852*38fd1498Szrj
1853*38fd1498Szrj /* Integer power helper used from __builtin_powi for non-constant
1854*38fd1498Szrj exponents. */
1855*38fd1498Szrj
1856*38fd1498Szrj #if (defined(L_powisf2) && LIBGCC2_HAS_SF_MODE) \
1857*38fd1498Szrj || (defined(L_powidf2) && LIBGCC2_HAS_DF_MODE) \
1858*38fd1498Szrj || (defined(L_powixf2) && LIBGCC2_HAS_XF_MODE) \
1859*38fd1498Szrj || (defined(L_powitf2) && LIBGCC2_HAS_TF_MODE)
1860*38fd1498Szrj # if defined(L_powisf2)
1861*38fd1498Szrj # define TYPE SFtype
1862*38fd1498Szrj # define NAME __powisf2
1863*38fd1498Szrj # elif defined(L_powidf2)
1864*38fd1498Szrj # define TYPE DFtype
1865*38fd1498Szrj # define NAME __powidf2
1866*38fd1498Szrj # elif defined(L_powixf2)
1867*38fd1498Szrj # define TYPE XFtype
1868*38fd1498Szrj # define NAME __powixf2
1869*38fd1498Szrj # elif defined(L_powitf2)
1870*38fd1498Szrj # define TYPE TFtype
1871*38fd1498Szrj # define NAME __powitf2
1872*38fd1498Szrj # endif
1873*38fd1498Szrj
1874*38fd1498Szrj #undef int
1875*38fd1498Szrj #undef unsigned
1876*38fd1498Szrj TYPE
NAME(TYPE x,int m)1877*38fd1498Szrj NAME (TYPE x, int m)
1878*38fd1498Szrj {
1879*38fd1498Szrj unsigned int n = m < 0 ? -m : m;
1880*38fd1498Szrj TYPE y = n % 2 ? x : 1;
1881*38fd1498Szrj while (n >>= 1)
1882*38fd1498Szrj {
1883*38fd1498Szrj x = x * x;
1884*38fd1498Szrj if (n % 2)
1885*38fd1498Szrj y = y * x;
1886*38fd1498Szrj }
1887*38fd1498Szrj return m < 0 ? 1/y : y;
1888*38fd1498Szrj }
1889*38fd1498Szrj
1890*38fd1498Szrj #endif
1891*38fd1498Szrj
1892*38fd1498Szrj #if((defined(L_mulhc3) || defined(L_divhc3)) && LIBGCC2_HAS_HF_MODE) \
1893*38fd1498Szrj || ((defined(L_mulsc3) || defined(L_divsc3)) && LIBGCC2_HAS_SF_MODE) \
1894*38fd1498Szrj || ((defined(L_muldc3) || defined(L_divdc3)) && LIBGCC2_HAS_DF_MODE) \
1895*38fd1498Szrj || ((defined(L_mulxc3) || defined(L_divxc3)) && LIBGCC2_HAS_XF_MODE) \
1896*38fd1498Szrj || ((defined(L_multc3) || defined(L_divtc3)) && LIBGCC2_HAS_TF_MODE)
1897*38fd1498Szrj
1898*38fd1498Szrj #undef float
1899*38fd1498Szrj #undef double
1900*38fd1498Szrj #undef long
1901*38fd1498Szrj
1902*38fd1498Szrj #if defined(L_mulhc3) || defined(L_divhc3)
1903*38fd1498Szrj # define MTYPE HFtype
1904*38fd1498Szrj # define CTYPE HCtype
1905*38fd1498Szrj # define MODE hc
1906*38fd1498Szrj # define CEXT __LIBGCC_HF_FUNC_EXT__
1907*38fd1498Szrj # define NOTRUNC (!__LIBGCC_HF_EXCESS_PRECISION__)
1908*38fd1498Szrj #elif defined(L_mulsc3) || defined(L_divsc3)
1909*38fd1498Szrj # define MTYPE SFtype
1910*38fd1498Szrj # define CTYPE SCtype
1911*38fd1498Szrj # define MODE sc
1912*38fd1498Szrj # define CEXT __LIBGCC_SF_FUNC_EXT__
1913*38fd1498Szrj # define NOTRUNC (!__LIBGCC_SF_EXCESS_PRECISION__)
1914*38fd1498Szrj #elif defined(L_muldc3) || defined(L_divdc3)
1915*38fd1498Szrj # define MTYPE DFtype
1916*38fd1498Szrj # define CTYPE DCtype
1917*38fd1498Szrj # define MODE dc
1918*38fd1498Szrj # define CEXT __LIBGCC_DF_FUNC_EXT__
1919*38fd1498Szrj # define NOTRUNC (!__LIBGCC_DF_EXCESS_PRECISION__)
1920*38fd1498Szrj #elif defined(L_mulxc3) || defined(L_divxc3)
1921*38fd1498Szrj # define MTYPE XFtype
1922*38fd1498Szrj # define CTYPE XCtype
1923*38fd1498Szrj # define MODE xc
1924*38fd1498Szrj # define CEXT __LIBGCC_XF_FUNC_EXT__
1925*38fd1498Szrj # define NOTRUNC (!__LIBGCC_XF_EXCESS_PRECISION__)
1926*38fd1498Szrj #elif defined(L_multc3) || defined(L_divtc3)
1927*38fd1498Szrj # define MTYPE TFtype
1928*38fd1498Szrj # define CTYPE TCtype
1929*38fd1498Szrj # define MODE tc
1930*38fd1498Szrj # define CEXT __LIBGCC_TF_FUNC_EXT__
1931*38fd1498Szrj # define NOTRUNC (!__LIBGCC_TF_EXCESS_PRECISION__)
1932*38fd1498Szrj #else
1933*38fd1498Szrj # error
1934*38fd1498Szrj #endif
1935*38fd1498Szrj
1936*38fd1498Szrj #define CONCAT3(A,B,C) _CONCAT3(A,B,C)
1937*38fd1498Szrj #define _CONCAT3(A,B,C) A##B##C
1938*38fd1498Szrj
1939*38fd1498Szrj #define CONCAT2(A,B) _CONCAT2(A,B)
1940*38fd1498Szrj #define _CONCAT2(A,B) A##B
1941*38fd1498Szrj
1942*38fd1498Szrj /* All of these would be present in a full C99 implementation of <math.h>
1943*38fd1498Szrj and <complex.h>. Our problem is that only a few systems have such full
1944*38fd1498Szrj implementations. Further, libgcc_s.so isn't currently linked against
1945*38fd1498Szrj libm.so, and even for systems that do provide full C99, the extra overhead
1946*38fd1498Szrj of all programs using libgcc having to link against libm. So avoid it. */
1947*38fd1498Szrj
1948*38fd1498Szrj #define isnan(x) __builtin_expect ((x) != (x), 0)
1949*38fd1498Szrj #define isfinite(x) __builtin_expect (!isnan((x) - (x)), 1)
1950*38fd1498Szrj #define isinf(x) __builtin_expect (!isnan(x) & !isfinite(x), 0)
1951*38fd1498Szrj
1952*38fd1498Szrj #define INFINITY CONCAT2(__builtin_huge_val, CEXT) ()
1953*38fd1498Szrj #define I 1i
1954*38fd1498Szrj
1955*38fd1498Szrj /* Helpers to make the following code slightly less gross. */
1956*38fd1498Szrj #define COPYSIGN CONCAT2(__builtin_copysign, CEXT)
1957*38fd1498Szrj #define FABS CONCAT2(__builtin_fabs, CEXT)
1958*38fd1498Szrj
1959*38fd1498Szrj /* Verify that MTYPE matches up with CEXT. */
1960*38fd1498Szrj extern void *compile_type_assert[sizeof(INFINITY) == sizeof(MTYPE) ? 1 : -1];
1961*38fd1498Szrj
1962*38fd1498Szrj /* Ensure that we've lost any extra precision. */
1963*38fd1498Szrj #if NOTRUNC
1964*38fd1498Szrj # define TRUNC(x)
1965*38fd1498Szrj #else
1966*38fd1498Szrj # define TRUNC(x) __asm__ ("" : "=m"(x) : "m"(x))
1967*38fd1498Szrj #endif
1968*38fd1498Szrj
1969*38fd1498Szrj #if defined(L_mulhc3) || defined(L_mulsc3) || defined(L_muldc3) \
1970*38fd1498Szrj || defined(L_mulxc3) || defined(L_multc3)
1971*38fd1498Szrj
1972*38fd1498Szrj CTYPE
1973*38fd1498Szrj CONCAT3(__mul,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d)
1974*38fd1498Szrj {
1975*38fd1498Szrj MTYPE ac, bd, ad, bc, x, y;
1976*38fd1498Szrj CTYPE res;
1977*38fd1498Szrj
1978*38fd1498Szrj ac = a * c;
1979*38fd1498Szrj bd = b * d;
1980*38fd1498Szrj ad = a * d;
1981*38fd1498Szrj bc = b * c;
1982*38fd1498Szrj
1983*38fd1498Szrj TRUNC (ac);
1984*38fd1498Szrj TRUNC (bd);
1985*38fd1498Szrj TRUNC (ad);
1986*38fd1498Szrj TRUNC (bc);
1987*38fd1498Szrj
1988*38fd1498Szrj x = ac - bd;
1989*38fd1498Szrj y = ad + bc;
1990*38fd1498Szrj
1991*38fd1498Szrj if (isnan (x) && isnan (y))
1992*38fd1498Szrj {
1993*38fd1498Szrj /* Recover infinities that computed as NaN + iNaN. */
1994*38fd1498Szrj _Bool recalc = 0;
1995*38fd1498Szrj if (isinf (a) || isinf (b))
1996*38fd1498Szrj {
1997*38fd1498Szrj /* z is infinite. "Box" the infinity and change NaNs in
1998*38fd1498Szrj the other factor to 0. */
1999*38fd1498Szrj a = COPYSIGN (isinf (a) ? 1 : 0, a);
2000*38fd1498Szrj b = COPYSIGN (isinf (b) ? 1 : 0, b);
2001*38fd1498Szrj if (isnan (c)) c = COPYSIGN (0, c);
2002*38fd1498Szrj if (isnan (d)) d = COPYSIGN (0, d);
2003*38fd1498Szrj recalc = 1;
2004*38fd1498Szrj }
2005*38fd1498Szrj if (isinf (c) || isinf (d))
2006*38fd1498Szrj {
2007*38fd1498Szrj /* w is infinite. "Box" the infinity and change NaNs in
2008*38fd1498Szrj the other factor to 0. */
2009*38fd1498Szrj c = COPYSIGN (isinf (c) ? 1 : 0, c);
2010*38fd1498Szrj d = COPYSIGN (isinf (d) ? 1 : 0, d);
2011*38fd1498Szrj if (isnan (a)) a = COPYSIGN (0, a);
2012*38fd1498Szrj if (isnan (b)) b = COPYSIGN (0, b);
2013*38fd1498Szrj recalc = 1;
2014*38fd1498Szrj }
2015*38fd1498Szrj if (!recalc
2016*38fd1498Szrj && (isinf (ac) || isinf (bd)
2017*38fd1498Szrj || isinf (ad) || isinf (bc)))
2018*38fd1498Szrj {
2019*38fd1498Szrj /* Recover infinities from overflow by changing NaNs to 0. */
2020*38fd1498Szrj if (isnan (a)) a = COPYSIGN (0, a);
2021*38fd1498Szrj if (isnan (b)) b = COPYSIGN (0, b);
2022*38fd1498Szrj if (isnan (c)) c = COPYSIGN (0, c);
2023*38fd1498Szrj if (isnan (d)) d = COPYSIGN (0, d);
2024*38fd1498Szrj recalc = 1;
2025*38fd1498Szrj }
2026*38fd1498Szrj if (recalc)
2027*38fd1498Szrj {
2028*38fd1498Szrj x = INFINITY * (a * c - b * d);
2029*38fd1498Szrj y = INFINITY * (a * d + b * c);
2030*38fd1498Szrj }
2031*38fd1498Szrj }
2032*38fd1498Szrj
2033*38fd1498Szrj __real__ res = x;
2034*38fd1498Szrj __imag__ res = y;
2035*38fd1498Szrj return res;
2036*38fd1498Szrj }
2037*38fd1498Szrj #endif /* complex multiply */
2038*38fd1498Szrj
2039*38fd1498Szrj #if defined(L_divhc3) || defined(L_divsc3) || defined(L_divdc3) \
2040*38fd1498Szrj || defined(L_divxc3) || defined(L_divtc3)
2041*38fd1498Szrj
2042*38fd1498Szrj CTYPE
2043*38fd1498Szrj CONCAT3(__div,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d)
2044*38fd1498Szrj {
2045*38fd1498Szrj MTYPE denom, ratio, x, y;
2046*38fd1498Szrj CTYPE res;
2047*38fd1498Szrj
2048*38fd1498Szrj /* ??? We can get better behavior from logarithmic scaling instead of
2049*38fd1498Szrj the division. But that would mean starting to link libgcc against
2050*38fd1498Szrj libm. We could implement something akin to ldexp/frexp as gcc builtins
2051*38fd1498Szrj fairly easily... */
2052*38fd1498Szrj if (FABS (c) < FABS (d))
2053*38fd1498Szrj {
2054*38fd1498Szrj ratio = c / d;
2055*38fd1498Szrj denom = (c * ratio) + d;
2056*38fd1498Szrj x = ((a * ratio) + b) / denom;
2057*38fd1498Szrj y = ((b * ratio) - a) / denom;
2058*38fd1498Szrj }
2059*38fd1498Szrj else
2060*38fd1498Szrj {
2061*38fd1498Szrj ratio = d / c;
2062*38fd1498Szrj denom = (d * ratio) + c;
2063*38fd1498Szrj x = ((b * ratio) + a) / denom;
2064*38fd1498Szrj y = (b - (a * ratio)) / denom;
2065*38fd1498Szrj }
2066*38fd1498Szrj
2067*38fd1498Szrj /* Recover infinities and zeros that computed as NaN+iNaN; the only cases
2068*38fd1498Szrj are nonzero/zero, infinite/finite, and finite/infinite. */
2069*38fd1498Szrj if (isnan (x) && isnan (y))
2070*38fd1498Szrj {
2071*38fd1498Szrj if (c == 0.0 && d == 0.0 && (!isnan (a) || !isnan (b)))
2072*38fd1498Szrj {
2073*38fd1498Szrj x = COPYSIGN (INFINITY, c) * a;
2074*38fd1498Szrj y = COPYSIGN (INFINITY, c) * b;
2075*38fd1498Szrj }
2076*38fd1498Szrj else if ((isinf (a) || isinf (b)) && isfinite (c) && isfinite (d))
2077*38fd1498Szrj {
2078*38fd1498Szrj a = COPYSIGN (isinf (a) ? 1 : 0, a);
2079*38fd1498Szrj b = COPYSIGN (isinf (b) ? 1 : 0, b);
2080*38fd1498Szrj x = INFINITY * (a * c + b * d);
2081*38fd1498Szrj y = INFINITY * (b * c - a * d);
2082*38fd1498Szrj }
2083*38fd1498Szrj else if ((isinf (c) || isinf (d)) && isfinite (a) && isfinite (b))
2084*38fd1498Szrj {
2085*38fd1498Szrj c = COPYSIGN (isinf (c) ? 1 : 0, c);
2086*38fd1498Szrj d = COPYSIGN (isinf (d) ? 1 : 0, d);
2087*38fd1498Szrj x = 0.0 * (a * c + b * d);
2088*38fd1498Szrj y = 0.0 * (b * c - a * d);
2089*38fd1498Szrj }
2090*38fd1498Szrj }
2091*38fd1498Szrj
2092*38fd1498Szrj __real__ res = x;
2093*38fd1498Szrj __imag__ res = y;
2094*38fd1498Szrj return res;
2095*38fd1498Szrj }
2096*38fd1498Szrj #endif /* complex divide */
2097*38fd1498Szrj
2098*38fd1498Szrj #endif /* all complex float routines */
2099*38fd1498Szrj
2100*38fd1498Szrj /* From here on down, the routines use normal data types. */
2101*38fd1498Szrj
2102*38fd1498Szrj #define SItype bogus_type
2103*38fd1498Szrj #define USItype bogus_type
2104*38fd1498Szrj #define DItype bogus_type
2105*38fd1498Szrj #define UDItype bogus_type
2106*38fd1498Szrj #define SFtype bogus_type
2107*38fd1498Szrj #define DFtype bogus_type
2108*38fd1498Szrj #undef Wtype
2109*38fd1498Szrj #undef UWtype
2110*38fd1498Szrj #undef HWtype
2111*38fd1498Szrj #undef UHWtype
2112*38fd1498Szrj #undef DWtype
2113*38fd1498Szrj #undef UDWtype
2114*38fd1498Szrj
2115*38fd1498Szrj #undef char
2116*38fd1498Szrj #undef short
2117*38fd1498Szrj #undef int
2118*38fd1498Szrj #undef long
2119*38fd1498Szrj #undef unsigned
2120*38fd1498Szrj #undef float
2121*38fd1498Szrj #undef double
2122*38fd1498Szrj
2123*38fd1498Szrj #ifdef L__gcc_bcmp
2124*38fd1498Szrj
2125*38fd1498Szrj /* Like bcmp except the sign is meaningful.
2126*38fd1498Szrj Result is negative if S1 is less than S2,
2127*38fd1498Szrj positive if S1 is greater, 0 if S1 and S2 are equal. */
2128*38fd1498Szrj
2129*38fd1498Szrj int
2130*38fd1498Szrj __gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
2131*38fd1498Szrj {
2132*38fd1498Szrj while (size > 0)
2133*38fd1498Szrj {
2134*38fd1498Szrj const unsigned char c1 = *s1++, c2 = *s2++;
2135*38fd1498Szrj if (c1 != c2)
2136*38fd1498Szrj return c1 - c2;
2137*38fd1498Szrj size--;
2138*38fd1498Szrj }
2139*38fd1498Szrj return 0;
2140*38fd1498Szrj }
2141*38fd1498Szrj
2142*38fd1498Szrj #endif
2143*38fd1498Szrj
2144*38fd1498Szrj /* __eprintf used to be used by GCC's private version of <assert.h>.
2145*38fd1498Szrj We no longer provide that header, but this routine remains in libgcc.a
2146*38fd1498Szrj for binary backward compatibility. Note that it is not included in
2147*38fd1498Szrj the shared version of libgcc. */
2148*38fd1498Szrj #ifdef L_eprintf
2149*38fd1498Szrj #ifndef inhibit_libc
2150*38fd1498Szrj
2151*38fd1498Szrj #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
2152*38fd1498Szrj #include <stdio.h>
2153*38fd1498Szrj
2154*38fd1498Szrj void
2155*38fd1498Szrj __eprintf (const char *string, const char *expression,
2156*38fd1498Szrj unsigned int line, const char *filename)
2157*38fd1498Szrj {
2158*38fd1498Szrj fprintf (stderr, string, expression, line, filename);
2159*38fd1498Szrj fflush (stderr);
2160*38fd1498Szrj abort ();
2161*38fd1498Szrj }
2162*38fd1498Szrj
2163*38fd1498Szrj #endif
2164*38fd1498Szrj #endif
2165*38fd1498Szrj
2166*38fd1498Szrj
2167*38fd1498Szrj #ifdef L_clear_cache
2168*38fd1498Szrj /* Clear part of an instruction cache. */
2169*38fd1498Szrj
2170*38fd1498Szrj void
2171*38fd1498Szrj __clear_cache (char *beg __attribute__((__unused__)),
2172*38fd1498Szrj char *end __attribute__((__unused__)))
2173*38fd1498Szrj {
2174*38fd1498Szrj #ifdef CLEAR_INSN_CACHE
2175*38fd1498Szrj CLEAR_INSN_CACHE (beg, end);
2176*38fd1498Szrj #endif /* CLEAR_INSN_CACHE */
2177*38fd1498Szrj }
2178*38fd1498Szrj
2179*38fd1498Szrj #endif /* L_clear_cache */
2180*38fd1498Szrj
2181*38fd1498Szrj #ifdef L_trampoline
2182*38fd1498Szrj
2183*38fd1498Szrj /* Jump to a trampoline, loading the static chain address. */
2184*38fd1498Szrj
2185*38fd1498Szrj #if defined(WINNT) && ! defined(__CYGWIN__)
2186*38fd1498Szrj #include <windows.h>
2187*38fd1498Szrj int getpagesize (void);
2188*38fd1498Szrj int mprotect (char *,int, int);
2189*38fd1498Szrj
2190*38fd1498Szrj int
2191*38fd1498Szrj getpagesize (void)
2192*38fd1498Szrj {
2193*38fd1498Szrj #ifdef _ALPHA_
2194*38fd1498Szrj return 8192;
2195*38fd1498Szrj #else
2196*38fd1498Szrj return 4096;
2197*38fd1498Szrj #endif
2198*38fd1498Szrj }
2199*38fd1498Szrj
2200*38fd1498Szrj int
2201*38fd1498Szrj mprotect (char *addr, int len, int prot)
2202*38fd1498Szrj {
2203*38fd1498Szrj DWORD np, op;
2204*38fd1498Szrj
2205*38fd1498Szrj if (prot == 7)
2206*38fd1498Szrj np = 0x40;
2207*38fd1498Szrj else if (prot == 5)
2208*38fd1498Szrj np = 0x20;
2209*38fd1498Szrj else if (prot == 4)
2210*38fd1498Szrj np = 0x10;
2211*38fd1498Szrj else if (prot == 3)
2212*38fd1498Szrj np = 0x04;
2213*38fd1498Szrj else if (prot == 1)
2214*38fd1498Szrj np = 0x02;
2215*38fd1498Szrj else if (prot == 0)
2216*38fd1498Szrj np = 0x01;
2217*38fd1498Szrj else
2218*38fd1498Szrj return -1;
2219*38fd1498Szrj
2220*38fd1498Szrj if (VirtualProtect (addr, len, np, &op))
2221*38fd1498Szrj return 0;
2222*38fd1498Szrj else
2223*38fd1498Szrj return -1;
2224*38fd1498Szrj }
2225*38fd1498Szrj
2226*38fd1498Szrj #endif /* WINNT && ! __CYGWIN__ */
2227*38fd1498Szrj
2228*38fd1498Szrj #ifdef TRANSFER_FROM_TRAMPOLINE
2229*38fd1498Szrj TRANSFER_FROM_TRAMPOLINE
2230*38fd1498Szrj #endif
2231*38fd1498Szrj #endif /* L_trampoline */
2232*38fd1498Szrj
2233*38fd1498Szrj #ifndef __CYGWIN__
2234*38fd1498Szrj #ifdef L__main
2235*38fd1498Szrj
2236*38fd1498Szrj #include "gbl-ctors.h"
2237*38fd1498Szrj
2238*38fd1498Szrj /* Some systems use __main in a way incompatible with its use in gcc, in these
2239*38fd1498Szrj cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
2240*38fd1498Szrj give the same symbol without quotes for an alternative entry point. You
2241*38fd1498Szrj must define both, or neither. */
2242*38fd1498Szrj #ifndef NAME__MAIN
2243*38fd1498Szrj #define NAME__MAIN "__main"
2244*38fd1498Szrj #define SYMBOL__MAIN __main
2245*38fd1498Szrj #endif
2246*38fd1498Szrj
2247*38fd1498Szrj #if defined (__LIBGCC_INIT_SECTION_ASM_OP__) \
2248*38fd1498Szrj || defined (__LIBGCC_INIT_ARRAY_SECTION_ASM_OP__)
2249*38fd1498Szrj #undef HAS_INIT_SECTION
2250*38fd1498Szrj #define HAS_INIT_SECTION
2251*38fd1498Szrj #endif
2252*38fd1498Szrj
2253*38fd1498Szrj #if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF)
2254*38fd1498Szrj
2255*38fd1498Szrj /* Some ELF crosses use crtstuff.c to provide __CTOR_LIST__, but use this
2256*38fd1498Szrj code to run constructors. In that case, we need to handle EH here, too.
2257*38fd1498Szrj But MINGW32 is special because it handles CRTSTUFF and EH on its own. */
2258*38fd1498Szrj
2259*38fd1498Szrj #ifdef __MINGW32__
2260*38fd1498Szrj #undef __LIBGCC_EH_FRAME_SECTION_NAME__
2261*38fd1498Szrj #endif
2262*38fd1498Szrj
2263*38fd1498Szrj #ifdef __LIBGCC_EH_FRAME_SECTION_NAME__
2264*38fd1498Szrj #include "unwind-dw2-fde.h"
2265*38fd1498Szrj extern unsigned char __EH_FRAME_BEGIN__[];
2266*38fd1498Szrj #endif
2267*38fd1498Szrj
2268*38fd1498Szrj /* Run all the global destructors on exit from the program. */
2269*38fd1498Szrj
2270*38fd1498Szrj void
2271*38fd1498Szrj __do_global_dtors (void)
2272*38fd1498Szrj {
2273*38fd1498Szrj #ifdef DO_GLOBAL_DTORS_BODY
2274*38fd1498Szrj DO_GLOBAL_DTORS_BODY;
2275*38fd1498Szrj #else
2276*38fd1498Szrj static func_ptr *p = __DTOR_LIST__ + 1;
2277*38fd1498Szrj while (*p)
2278*38fd1498Szrj {
2279*38fd1498Szrj p++;
2280*38fd1498Szrj (*(p-1)) ();
2281*38fd1498Szrj }
2282*38fd1498Szrj #endif
2283*38fd1498Szrj #if defined (__LIBGCC_EH_FRAME_SECTION_NAME__) && !defined (HAS_INIT_SECTION)
2284*38fd1498Szrj {
2285*38fd1498Szrj static int completed = 0;
2286*38fd1498Szrj if (! completed)
2287*38fd1498Szrj {
2288*38fd1498Szrj completed = 1;
2289*38fd1498Szrj __deregister_frame_info (__EH_FRAME_BEGIN__);
2290*38fd1498Szrj }
2291*38fd1498Szrj }
2292*38fd1498Szrj #endif
2293*38fd1498Szrj }
2294*38fd1498Szrj #endif
2295*38fd1498Szrj
2296*38fd1498Szrj #ifndef HAS_INIT_SECTION
2297*38fd1498Szrj /* Run all the global constructors on entry to the program. */
2298*38fd1498Szrj
2299*38fd1498Szrj void
2300*38fd1498Szrj __do_global_ctors (void)
2301*38fd1498Szrj {
2302*38fd1498Szrj #ifdef __LIBGCC_EH_FRAME_SECTION_NAME__
2303*38fd1498Szrj {
2304*38fd1498Szrj static struct object object;
2305*38fd1498Szrj __register_frame_info (__EH_FRAME_BEGIN__, &object);
2306*38fd1498Szrj }
2307*38fd1498Szrj #endif
2308*38fd1498Szrj DO_GLOBAL_CTORS_BODY;
2309*38fd1498Szrj atexit (__do_global_dtors);
2310*38fd1498Szrj }
2311*38fd1498Szrj #endif /* no HAS_INIT_SECTION */
2312*38fd1498Szrj
2313*38fd1498Szrj #if !defined (HAS_INIT_SECTION) || defined (INVOKE__main)
2314*38fd1498Szrj /* Subroutine called automatically by `main'.
2315*38fd1498Szrj Compiling a global function named `main'
2316*38fd1498Szrj produces an automatic call to this function at the beginning.
2317*38fd1498Szrj
2318*38fd1498Szrj For many systems, this routine calls __do_global_ctors.
2319*38fd1498Szrj For systems which support a .init section we use the .init section
2320*38fd1498Szrj to run __do_global_ctors, so we need not do anything here. */
2321*38fd1498Szrj
2322*38fd1498Szrj extern void SYMBOL__MAIN (void);
2323*38fd1498Szrj void
2324*38fd1498Szrj SYMBOL__MAIN (void)
2325*38fd1498Szrj {
2326*38fd1498Szrj /* Support recursive calls to `main': run initializers just once. */
2327*38fd1498Szrj static int initialized;
2328*38fd1498Szrj if (! initialized)
2329*38fd1498Szrj {
2330*38fd1498Szrj initialized = 1;
2331*38fd1498Szrj __do_global_ctors ();
2332*38fd1498Szrj }
2333*38fd1498Szrj }
2334*38fd1498Szrj #endif /* no HAS_INIT_SECTION or INVOKE__main */
2335*38fd1498Szrj
2336*38fd1498Szrj #endif /* L__main */
2337*38fd1498Szrj #endif /* __CYGWIN__ */
2338*38fd1498Szrj
2339*38fd1498Szrj #ifdef L_ctors
2340*38fd1498Szrj
2341*38fd1498Szrj #include "gbl-ctors.h"
2342*38fd1498Szrj
2343*38fd1498Szrj /* Provide default definitions for the lists of constructors and
2344*38fd1498Szrj destructors, so that we don't get linker errors. These symbols are
2345*38fd1498Szrj intentionally bss symbols, so that gld and/or collect will provide
2346*38fd1498Szrj the right values. */
2347*38fd1498Szrj
2348*38fd1498Szrj /* We declare the lists here with two elements each,
2349*38fd1498Szrj so that they are valid empty lists if no other definition is loaded.
2350*38fd1498Szrj
2351*38fd1498Szrj If we are using the old "set" extensions to have the gnu linker
2352*38fd1498Szrj collect ctors and dtors, then we __CTOR_LIST__ and __DTOR_LIST__
2353*38fd1498Szrj must be in the bss/common section.
2354*38fd1498Szrj
2355*38fd1498Szrj Long term no port should use those extensions. But many still do. */
2356*38fd1498Szrj #if !defined(__LIBGCC_INIT_SECTION_ASM_OP__)
2357*38fd1498Szrj #if defined (TARGET_ASM_CONSTRUCTOR) || defined (USE_COLLECT2)
2358*38fd1498Szrj func_ptr __CTOR_LIST__[2] = {0, 0};
2359*38fd1498Szrj func_ptr __DTOR_LIST__[2] = {0, 0};
2360*38fd1498Szrj #else
2361*38fd1498Szrj func_ptr __CTOR_LIST__[2];
2362*38fd1498Szrj func_ptr __DTOR_LIST__[2];
2363*38fd1498Szrj #endif
2364*38fd1498Szrj #endif /* no __LIBGCC_INIT_SECTION_ASM_OP__ */
2365*38fd1498Szrj #endif /* L_ctors */
2366*38fd1498Szrj #endif /* LIBGCC2_UNITS_PER_WORD <= MIN_UNITS_PER_WORD */
2367