1*e4b17023SJohn Marino /* This is a software floating point library which can be used
2*e4b17023SJohn Marino for targets without hardware floating point.
3*e4b17023SJohn Marino Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003,
4*e4b17023SJohn Marino 2004, 2005, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
5*e4b17023SJohn Marino
6*e4b17023SJohn Marino This file is part of GCC.
7*e4b17023SJohn Marino
8*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
9*e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
10*e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
11*e4b17023SJohn Marino version.
12*e4b17023SJohn Marino
13*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14*e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
15*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16*e4b17023SJohn Marino for more details.
17*e4b17023SJohn Marino
18*e4b17023SJohn Marino Under Section 7 of GPL version 3, you are granted additional
19*e4b17023SJohn Marino permissions described in the GCC Runtime Library Exception, version
20*e4b17023SJohn Marino 3.1, as published by the Free Software Foundation.
21*e4b17023SJohn Marino
22*e4b17023SJohn Marino You should have received a copy of the GNU General Public License and
23*e4b17023SJohn Marino a copy of the GCC Runtime Library Exception along with this program;
24*e4b17023SJohn Marino see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25*e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */
26*e4b17023SJohn Marino
27*e4b17023SJohn Marino /* This implements IEEE 754 format arithmetic, but does not provide a
28*e4b17023SJohn Marino mechanism for setting the rounding mode, or for generating or handling
29*e4b17023SJohn Marino exceptions.
30*e4b17023SJohn Marino
31*e4b17023SJohn Marino The original code by Steve Chamberlain, hacked by Mark Eichin and Jim
32*e4b17023SJohn Marino Wilson, all of Cygnus Support. */
33*e4b17023SJohn Marino
34*e4b17023SJohn Marino /* The intended way to use this file is to make two copies, add `#define FLOAT'
35*e4b17023SJohn Marino to one copy, then compile both copies and add them to libgcc.a. */
36*e4b17023SJohn Marino
37*e4b17023SJohn Marino #include "tconfig.h"
38*e4b17023SJohn Marino #include "coretypes.h"
39*e4b17023SJohn Marino #include "tm.h"
40*e4b17023SJohn Marino #include "libgcc_tm.h"
41*e4b17023SJohn Marino #include "fp-bit.h"
42*e4b17023SJohn Marino
43*e4b17023SJohn Marino /* The following macros can be defined to change the behavior of this file:
44*e4b17023SJohn Marino FLOAT: Implement a `float', aka SFmode, fp library. If this is not
45*e4b17023SJohn Marino defined, then this file implements a `double', aka DFmode, fp library.
46*e4b17023SJohn Marino FLOAT_ONLY: Used with FLOAT, to implement a `float' only library, i.e.
47*e4b17023SJohn Marino don't include float->double conversion which requires the double library.
48*e4b17023SJohn Marino This is useful only for machines which can't support doubles, e.g. some
49*e4b17023SJohn Marino 8-bit processors.
50*e4b17023SJohn Marino CMPtype: Specify the type that floating point compares should return.
51*e4b17023SJohn Marino This defaults to SItype, aka int.
52*e4b17023SJohn Marino _DEBUG_BITFLOAT: This makes debugging the code a little easier, by adding
53*e4b17023SJohn Marino two integers to the FLO_union_type.
54*e4b17023SJohn Marino NO_DENORMALS: Disable handling of denormals.
55*e4b17023SJohn Marino NO_NANS: Disable nan and infinity handling
56*e4b17023SJohn Marino SMALL_MACHINE: Useful when operations on QIs and HIs are faster
57*e4b17023SJohn Marino than on an SI */
58*e4b17023SJohn Marino
59*e4b17023SJohn Marino /* We don't currently support extended floats (long doubles) on machines
60*e4b17023SJohn Marino without hardware to deal with them.
61*e4b17023SJohn Marino
62*e4b17023SJohn Marino These stubs are just to keep the linker from complaining about unresolved
63*e4b17023SJohn Marino references which can be pulled in from libio & libstdc++, even if the
64*e4b17023SJohn Marino user isn't using long doubles. However, they may generate an unresolved
65*e4b17023SJohn Marino external to abort if abort is not used by the function, and the stubs
66*e4b17023SJohn Marino are referenced from within libc, since libgcc goes before and after the
67*e4b17023SJohn Marino system library. */
68*e4b17023SJohn Marino
69*e4b17023SJohn Marino #ifdef DECLARE_LIBRARY_RENAMES
70*e4b17023SJohn Marino DECLARE_LIBRARY_RENAMES
71*e4b17023SJohn Marino #endif
72*e4b17023SJohn Marino
73*e4b17023SJohn Marino #ifdef EXTENDED_FLOAT_STUBS
74*e4b17023SJohn Marino extern void abort (void);
__extendsfxf2(void)75*e4b17023SJohn Marino void __extendsfxf2 (void) { abort(); }
__extenddfxf2(void)76*e4b17023SJohn Marino void __extenddfxf2 (void) { abort(); }
__truncxfdf2(void)77*e4b17023SJohn Marino void __truncxfdf2 (void) { abort(); }
__truncxfsf2(void)78*e4b17023SJohn Marino void __truncxfsf2 (void) { abort(); }
__fixxfsi(void)79*e4b17023SJohn Marino void __fixxfsi (void) { abort(); }
__floatsixf(void)80*e4b17023SJohn Marino void __floatsixf (void) { abort(); }
__addxf3(void)81*e4b17023SJohn Marino void __addxf3 (void) { abort(); }
__subxf3(void)82*e4b17023SJohn Marino void __subxf3 (void) { abort(); }
__mulxf3(void)83*e4b17023SJohn Marino void __mulxf3 (void) { abort(); }
__divxf3(void)84*e4b17023SJohn Marino void __divxf3 (void) { abort(); }
__negxf2(void)85*e4b17023SJohn Marino void __negxf2 (void) { abort(); }
__eqxf2(void)86*e4b17023SJohn Marino void __eqxf2 (void) { abort(); }
__nexf2(void)87*e4b17023SJohn Marino void __nexf2 (void) { abort(); }
__gtxf2(void)88*e4b17023SJohn Marino void __gtxf2 (void) { abort(); }
__gexf2(void)89*e4b17023SJohn Marino void __gexf2 (void) { abort(); }
__lexf2(void)90*e4b17023SJohn Marino void __lexf2 (void) { abort(); }
__ltxf2(void)91*e4b17023SJohn Marino void __ltxf2 (void) { abort(); }
92*e4b17023SJohn Marino
__extendsftf2(void)93*e4b17023SJohn Marino void __extendsftf2 (void) { abort(); }
__extenddftf2(void)94*e4b17023SJohn Marino void __extenddftf2 (void) { abort(); }
__trunctfdf2(void)95*e4b17023SJohn Marino void __trunctfdf2 (void) { abort(); }
__trunctfsf2(void)96*e4b17023SJohn Marino void __trunctfsf2 (void) { abort(); }
__fixtfsi(void)97*e4b17023SJohn Marino void __fixtfsi (void) { abort(); }
__floatsitf(void)98*e4b17023SJohn Marino void __floatsitf (void) { abort(); }
__addtf3(void)99*e4b17023SJohn Marino void __addtf3 (void) { abort(); }
__subtf3(void)100*e4b17023SJohn Marino void __subtf3 (void) { abort(); }
__multf3(void)101*e4b17023SJohn Marino void __multf3 (void) { abort(); }
__divtf3(void)102*e4b17023SJohn Marino void __divtf3 (void) { abort(); }
__negtf2(void)103*e4b17023SJohn Marino void __negtf2 (void) { abort(); }
__eqtf2(void)104*e4b17023SJohn Marino void __eqtf2 (void) { abort(); }
__netf2(void)105*e4b17023SJohn Marino void __netf2 (void) { abort(); }
__gttf2(void)106*e4b17023SJohn Marino void __gttf2 (void) { abort(); }
__getf2(void)107*e4b17023SJohn Marino void __getf2 (void) { abort(); }
__letf2(void)108*e4b17023SJohn Marino void __letf2 (void) { abort(); }
__lttf2(void)109*e4b17023SJohn Marino void __lttf2 (void) { abort(); }
110*e4b17023SJohn Marino #else /* !EXTENDED_FLOAT_STUBS, rest of file */
111*e4b17023SJohn Marino
112*e4b17023SJohn Marino /* IEEE "special" number predicates */
113*e4b17023SJohn Marino
114*e4b17023SJohn Marino #ifdef NO_NANS
115*e4b17023SJohn Marino
116*e4b17023SJohn Marino #define nan() 0
117*e4b17023SJohn Marino #define isnan(x) 0
118*e4b17023SJohn Marino #define isinf(x) 0
119*e4b17023SJohn Marino #else
120*e4b17023SJohn Marino
121*e4b17023SJohn Marino #if defined L_thenan_sf
122*e4b17023SJohn Marino const fp_number_type __thenan_sf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
123*e4b17023SJohn Marino #elif defined L_thenan_df
124*e4b17023SJohn Marino const fp_number_type __thenan_df = { CLASS_SNAN, 0, 0, {(fractype) 0} };
125*e4b17023SJohn Marino #elif defined L_thenan_tf
126*e4b17023SJohn Marino const fp_number_type __thenan_tf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
127*e4b17023SJohn Marino #elif defined TFLOAT
128*e4b17023SJohn Marino extern const fp_number_type __thenan_tf;
129*e4b17023SJohn Marino #elif defined FLOAT
130*e4b17023SJohn Marino extern const fp_number_type __thenan_sf;
131*e4b17023SJohn Marino #else
132*e4b17023SJohn Marino extern const fp_number_type __thenan_df;
133*e4b17023SJohn Marino #endif
134*e4b17023SJohn Marino
135*e4b17023SJohn Marino INLINE
136*e4b17023SJohn Marino static const fp_number_type *
137*e4b17023SJohn Marino makenan (void)
138*e4b17023SJohn Marino {
139*e4b17023SJohn Marino #ifdef TFLOAT
140*e4b17023SJohn Marino return & __thenan_tf;
141*e4b17023SJohn Marino #elif defined FLOAT
142*e4b17023SJohn Marino return & __thenan_sf;
143*e4b17023SJohn Marino #else
144*e4b17023SJohn Marino return & __thenan_df;
145*e4b17023SJohn Marino #endif
146*e4b17023SJohn Marino }
147*e4b17023SJohn Marino
148*e4b17023SJohn Marino INLINE
149*e4b17023SJohn Marino static int
150*e4b17023SJohn Marino isnan (const fp_number_type *x)
151*e4b17023SJohn Marino {
152*e4b17023SJohn Marino return __builtin_expect (x->class == CLASS_SNAN || x->class == CLASS_QNAN,
153*e4b17023SJohn Marino 0);
154*e4b17023SJohn Marino }
155*e4b17023SJohn Marino
156*e4b17023SJohn Marino INLINE
157*e4b17023SJohn Marino static int
158*e4b17023SJohn Marino isinf (const fp_number_type * x)
159*e4b17023SJohn Marino {
160*e4b17023SJohn Marino return __builtin_expect (x->class == CLASS_INFINITY, 0);
161*e4b17023SJohn Marino }
162*e4b17023SJohn Marino
163*e4b17023SJohn Marino #endif /* NO_NANS */
164*e4b17023SJohn Marino
165*e4b17023SJohn Marino INLINE
166*e4b17023SJohn Marino static int
167*e4b17023SJohn Marino iszero (const fp_number_type * x)
168*e4b17023SJohn Marino {
169*e4b17023SJohn Marino return x->class == CLASS_ZERO;
170*e4b17023SJohn Marino }
171*e4b17023SJohn Marino
172*e4b17023SJohn Marino INLINE
173*e4b17023SJohn Marino static void
174*e4b17023SJohn Marino flip_sign ( fp_number_type * x)
175*e4b17023SJohn Marino {
176*e4b17023SJohn Marino x->sign = !x->sign;
177*e4b17023SJohn Marino }
178*e4b17023SJohn Marino
179*e4b17023SJohn Marino /* Count leading zeroes in N. */
180*e4b17023SJohn Marino INLINE
181*e4b17023SJohn Marino static int
182*e4b17023SJohn Marino clzusi (USItype n)
183*e4b17023SJohn Marino {
184*e4b17023SJohn Marino extern int __clzsi2 (USItype);
185*e4b17023SJohn Marino if (sizeof (USItype) == sizeof (unsigned int))
186*e4b17023SJohn Marino return __builtin_clz (n);
187*e4b17023SJohn Marino else if (sizeof (USItype) == sizeof (unsigned long))
188*e4b17023SJohn Marino return __builtin_clzl (n);
189*e4b17023SJohn Marino else if (sizeof (USItype) == sizeof (unsigned long long))
190*e4b17023SJohn Marino return __builtin_clzll (n);
191*e4b17023SJohn Marino else
192*e4b17023SJohn Marino return __clzsi2 (n);
193*e4b17023SJohn Marino }
194*e4b17023SJohn Marino
195*e4b17023SJohn Marino extern FLO_type pack_d (const fp_number_type * );
196*e4b17023SJohn Marino
197*e4b17023SJohn Marino #if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf)
198*e4b17023SJohn Marino FLO_type
199*e4b17023SJohn Marino pack_d (const fp_number_type *src)
200*e4b17023SJohn Marino {
201*e4b17023SJohn Marino FLO_union_type dst;
202*e4b17023SJohn Marino fractype fraction = src->fraction.ll; /* wasn't unsigned before? */
203*e4b17023SJohn Marino int sign = src->sign;
204*e4b17023SJohn Marino int exp = 0;
205*e4b17023SJohn Marino
206*e4b17023SJohn Marino if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && (isnan (src) || isinf (src)))
207*e4b17023SJohn Marino {
208*e4b17023SJohn Marino /* We can't represent these values accurately. By using the
209*e4b17023SJohn Marino largest possible magnitude, we guarantee that the conversion
210*e4b17023SJohn Marino of infinity is at least as big as any finite number. */
211*e4b17023SJohn Marino exp = EXPMAX;
212*e4b17023SJohn Marino fraction = ((fractype) 1 << FRACBITS) - 1;
213*e4b17023SJohn Marino }
214*e4b17023SJohn Marino else if (isnan (src))
215*e4b17023SJohn Marino {
216*e4b17023SJohn Marino exp = EXPMAX;
217*e4b17023SJohn Marino if (src->class == CLASS_QNAN || 1)
218*e4b17023SJohn Marino {
219*e4b17023SJohn Marino #ifdef QUIET_NAN_NEGATED
220*e4b17023SJohn Marino fraction |= QUIET_NAN - 1;
221*e4b17023SJohn Marino #else
222*e4b17023SJohn Marino fraction |= QUIET_NAN;
223*e4b17023SJohn Marino #endif
224*e4b17023SJohn Marino }
225*e4b17023SJohn Marino }
226*e4b17023SJohn Marino else if (isinf (src))
227*e4b17023SJohn Marino {
228*e4b17023SJohn Marino exp = EXPMAX;
229*e4b17023SJohn Marino fraction = 0;
230*e4b17023SJohn Marino }
231*e4b17023SJohn Marino else if (iszero (src))
232*e4b17023SJohn Marino {
233*e4b17023SJohn Marino exp = 0;
234*e4b17023SJohn Marino fraction = 0;
235*e4b17023SJohn Marino }
236*e4b17023SJohn Marino else if (fraction == 0)
237*e4b17023SJohn Marino {
238*e4b17023SJohn Marino exp = 0;
239*e4b17023SJohn Marino }
240*e4b17023SJohn Marino else
241*e4b17023SJohn Marino {
242*e4b17023SJohn Marino if (__builtin_expect (src->normal_exp < NORMAL_EXPMIN, 0))
243*e4b17023SJohn Marino {
244*e4b17023SJohn Marino #ifdef NO_DENORMALS
245*e4b17023SJohn Marino /* Go straight to a zero representation if denormals are not
246*e4b17023SJohn Marino supported. The denormal handling would be harmless but
247*e4b17023SJohn Marino isn't unnecessary. */
248*e4b17023SJohn Marino exp = 0;
249*e4b17023SJohn Marino fraction = 0;
250*e4b17023SJohn Marino #else /* NO_DENORMALS */
251*e4b17023SJohn Marino /* This number's exponent is too low to fit into the bits
252*e4b17023SJohn Marino available in the number, so we'll store 0 in the exponent and
253*e4b17023SJohn Marino shift the fraction to the right to make up for it. */
254*e4b17023SJohn Marino
255*e4b17023SJohn Marino int shift = NORMAL_EXPMIN - src->normal_exp;
256*e4b17023SJohn Marino
257*e4b17023SJohn Marino exp = 0;
258*e4b17023SJohn Marino
259*e4b17023SJohn Marino if (shift > FRAC_NBITS - NGARDS)
260*e4b17023SJohn Marino {
261*e4b17023SJohn Marino /* No point shifting, since it's more that 64 out. */
262*e4b17023SJohn Marino fraction = 0;
263*e4b17023SJohn Marino }
264*e4b17023SJohn Marino else
265*e4b17023SJohn Marino {
266*e4b17023SJohn Marino int lowbit = (fraction & (((fractype)1 << shift) - 1)) ? 1 : 0;
267*e4b17023SJohn Marino fraction = (fraction >> shift) | lowbit;
268*e4b17023SJohn Marino }
269*e4b17023SJohn Marino if ((fraction & GARDMASK) == GARDMSB)
270*e4b17023SJohn Marino {
271*e4b17023SJohn Marino if ((fraction & (1 << NGARDS)))
272*e4b17023SJohn Marino fraction += GARDROUND + 1;
273*e4b17023SJohn Marino }
274*e4b17023SJohn Marino else
275*e4b17023SJohn Marino {
276*e4b17023SJohn Marino /* Add to the guards to round up. */
277*e4b17023SJohn Marino fraction += GARDROUND;
278*e4b17023SJohn Marino }
279*e4b17023SJohn Marino /* Perhaps the rounding means we now need to change the
280*e4b17023SJohn Marino exponent, because the fraction is no longer denormal. */
281*e4b17023SJohn Marino if (fraction >= IMPLICIT_1)
282*e4b17023SJohn Marino {
283*e4b17023SJohn Marino exp += 1;
284*e4b17023SJohn Marino }
285*e4b17023SJohn Marino fraction >>= NGARDS;
286*e4b17023SJohn Marino #endif /* NO_DENORMALS */
287*e4b17023SJohn Marino }
288*e4b17023SJohn Marino else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS)
289*e4b17023SJohn Marino && __builtin_expect (src->normal_exp > EXPBIAS, 0))
290*e4b17023SJohn Marino {
291*e4b17023SJohn Marino exp = EXPMAX;
292*e4b17023SJohn Marino fraction = 0;
293*e4b17023SJohn Marino }
294*e4b17023SJohn Marino else
295*e4b17023SJohn Marino {
296*e4b17023SJohn Marino exp = src->normal_exp + EXPBIAS;
297*e4b17023SJohn Marino if (!ROUND_TOWARDS_ZERO)
298*e4b17023SJohn Marino {
299*e4b17023SJohn Marino /* IF the gard bits are the all zero, but the first, then we're
300*e4b17023SJohn Marino half way between two numbers, choose the one which makes the
301*e4b17023SJohn Marino lsb of the answer 0. */
302*e4b17023SJohn Marino if ((fraction & GARDMASK) == GARDMSB)
303*e4b17023SJohn Marino {
304*e4b17023SJohn Marino if (fraction & (1 << NGARDS))
305*e4b17023SJohn Marino fraction += GARDROUND + 1;
306*e4b17023SJohn Marino }
307*e4b17023SJohn Marino else
308*e4b17023SJohn Marino {
309*e4b17023SJohn Marino /* Add a one to the guards to round up */
310*e4b17023SJohn Marino fraction += GARDROUND;
311*e4b17023SJohn Marino }
312*e4b17023SJohn Marino if (fraction >= IMPLICIT_2)
313*e4b17023SJohn Marino {
314*e4b17023SJohn Marino fraction >>= 1;
315*e4b17023SJohn Marino exp += 1;
316*e4b17023SJohn Marino }
317*e4b17023SJohn Marino }
318*e4b17023SJohn Marino fraction >>= NGARDS;
319*e4b17023SJohn Marino
320*e4b17023SJohn Marino if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp > EXPMAX)
321*e4b17023SJohn Marino {
322*e4b17023SJohn Marino /* Saturate on overflow. */
323*e4b17023SJohn Marino exp = EXPMAX;
324*e4b17023SJohn Marino fraction = ((fractype) 1 << FRACBITS) - 1;
325*e4b17023SJohn Marino }
326*e4b17023SJohn Marino }
327*e4b17023SJohn Marino }
328*e4b17023SJohn Marino
329*e4b17023SJohn Marino /* We previously used bitfields to store the number, but this doesn't
330*e4b17023SJohn Marino handle little/big endian systems conveniently, so use shifts and
331*e4b17023SJohn Marino masks */
332*e4b17023SJohn Marino #ifdef FLOAT_BIT_ORDER_MISMATCH
333*e4b17023SJohn Marino dst.bits.fraction = fraction;
334*e4b17023SJohn Marino dst.bits.exp = exp;
335*e4b17023SJohn Marino dst.bits.sign = sign;
336*e4b17023SJohn Marino #else
337*e4b17023SJohn Marino # if defined TFLOAT && defined HALFFRACBITS
338*e4b17023SJohn Marino {
339*e4b17023SJohn Marino halffractype high, low, unity;
340*e4b17023SJohn Marino int lowsign, lowexp;
341*e4b17023SJohn Marino
342*e4b17023SJohn Marino unity = (halffractype) 1 << HALFFRACBITS;
343*e4b17023SJohn Marino
344*e4b17023SJohn Marino /* Set HIGH to the high double's significand, masking out the implicit 1.
345*e4b17023SJohn Marino Set LOW to the low double's full significand. */
346*e4b17023SJohn Marino high = (fraction >> (FRACBITS - HALFFRACBITS)) & (unity - 1);
347*e4b17023SJohn Marino low = fraction & (unity * 2 - 1);
348*e4b17023SJohn Marino
349*e4b17023SJohn Marino /* Get the initial sign and exponent of the low double. */
350*e4b17023SJohn Marino lowexp = exp - HALFFRACBITS - 1;
351*e4b17023SJohn Marino lowsign = sign;
352*e4b17023SJohn Marino
353*e4b17023SJohn Marino /* HIGH should be rounded like a normal double, making |LOW| <=
354*e4b17023SJohn Marino 0.5 ULP of HIGH. Assume round-to-nearest. */
355*e4b17023SJohn Marino if (exp < EXPMAX)
356*e4b17023SJohn Marino if (low > unity || (low == unity && (high & 1) == 1))
357*e4b17023SJohn Marino {
358*e4b17023SJohn Marino /* Round HIGH up and adjust LOW to match. */
359*e4b17023SJohn Marino high++;
360*e4b17023SJohn Marino if (high == unity)
361*e4b17023SJohn Marino {
362*e4b17023SJohn Marino /* May make it infinite, but that's OK. */
363*e4b17023SJohn Marino high = 0;
364*e4b17023SJohn Marino exp++;
365*e4b17023SJohn Marino }
366*e4b17023SJohn Marino low = unity * 2 - low;
367*e4b17023SJohn Marino lowsign ^= 1;
368*e4b17023SJohn Marino }
369*e4b17023SJohn Marino
370*e4b17023SJohn Marino high |= (halffractype) exp << HALFFRACBITS;
371*e4b17023SJohn Marino high |= (halffractype) sign << (HALFFRACBITS + EXPBITS);
372*e4b17023SJohn Marino
373*e4b17023SJohn Marino if (exp == EXPMAX || exp == 0 || low == 0)
374*e4b17023SJohn Marino low = 0;
375*e4b17023SJohn Marino else
376*e4b17023SJohn Marino {
377*e4b17023SJohn Marino while (lowexp > 0 && low < unity)
378*e4b17023SJohn Marino {
379*e4b17023SJohn Marino low <<= 1;
380*e4b17023SJohn Marino lowexp--;
381*e4b17023SJohn Marino }
382*e4b17023SJohn Marino
383*e4b17023SJohn Marino if (lowexp <= 0)
384*e4b17023SJohn Marino {
385*e4b17023SJohn Marino halffractype roundmsb, round;
386*e4b17023SJohn Marino int shift;
387*e4b17023SJohn Marino
388*e4b17023SJohn Marino shift = 1 - lowexp;
389*e4b17023SJohn Marino roundmsb = (1 << (shift - 1));
390*e4b17023SJohn Marino round = low & ((roundmsb << 1) - 1);
391*e4b17023SJohn Marino
392*e4b17023SJohn Marino low >>= shift;
393*e4b17023SJohn Marino lowexp = 0;
394*e4b17023SJohn Marino
395*e4b17023SJohn Marino if (round > roundmsb || (round == roundmsb && (low & 1) == 1))
396*e4b17023SJohn Marino {
397*e4b17023SJohn Marino low++;
398*e4b17023SJohn Marino if (low == unity)
399*e4b17023SJohn Marino /* LOW rounds up to the smallest normal number. */
400*e4b17023SJohn Marino lowexp++;
401*e4b17023SJohn Marino }
402*e4b17023SJohn Marino }
403*e4b17023SJohn Marino
404*e4b17023SJohn Marino low &= unity - 1;
405*e4b17023SJohn Marino low |= (halffractype) lowexp << HALFFRACBITS;
406*e4b17023SJohn Marino low |= (halffractype) lowsign << (HALFFRACBITS + EXPBITS);
407*e4b17023SJohn Marino }
408*e4b17023SJohn Marino dst.value_raw = ((fractype) high << HALFSHIFT) | low;
409*e4b17023SJohn Marino }
410*e4b17023SJohn Marino # else
411*e4b17023SJohn Marino dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1);
412*e4b17023SJohn Marino dst.value_raw |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << FRACBITS;
413*e4b17023SJohn Marino dst.value_raw |= ((fractype) (sign & 1)) << (FRACBITS | EXPBITS);
414*e4b17023SJohn Marino # endif
415*e4b17023SJohn Marino #endif
416*e4b17023SJohn Marino
417*e4b17023SJohn Marino #if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
418*e4b17023SJohn Marino #ifdef TFLOAT
419*e4b17023SJohn Marino {
420*e4b17023SJohn Marino qrtrfractype tmp1 = dst.words[0];
421*e4b17023SJohn Marino qrtrfractype tmp2 = dst.words[1];
422*e4b17023SJohn Marino dst.words[0] = dst.words[3];
423*e4b17023SJohn Marino dst.words[1] = dst.words[2];
424*e4b17023SJohn Marino dst.words[2] = tmp2;
425*e4b17023SJohn Marino dst.words[3] = tmp1;
426*e4b17023SJohn Marino }
427*e4b17023SJohn Marino #else
428*e4b17023SJohn Marino {
429*e4b17023SJohn Marino halffractype tmp = dst.words[0];
430*e4b17023SJohn Marino dst.words[0] = dst.words[1];
431*e4b17023SJohn Marino dst.words[1] = tmp;
432*e4b17023SJohn Marino }
433*e4b17023SJohn Marino #endif
434*e4b17023SJohn Marino #endif
435*e4b17023SJohn Marino
436*e4b17023SJohn Marino return dst.value;
437*e4b17023SJohn Marino }
438*e4b17023SJohn Marino #endif
439*e4b17023SJohn Marino
440*e4b17023SJohn Marino #if defined(L_unpack_df) || defined(L_unpack_sf) || defined(L_unpack_tf)
441*e4b17023SJohn Marino void
442*e4b17023SJohn Marino unpack_d (FLO_union_type * src, fp_number_type * dst)
443*e4b17023SJohn Marino {
444*e4b17023SJohn Marino /* We previously used bitfields to store the number, but this doesn't
445*e4b17023SJohn Marino handle little/big endian systems conveniently, so use shifts and
446*e4b17023SJohn Marino masks */
447*e4b17023SJohn Marino fractype fraction;
448*e4b17023SJohn Marino int exp;
449*e4b17023SJohn Marino int sign;
450*e4b17023SJohn Marino
451*e4b17023SJohn Marino #if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
452*e4b17023SJohn Marino FLO_union_type swapped;
453*e4b17023SJohn Marino
454*e4b17023SJohn Marino #ifdef TFLOAT
455*e4b17023SJohn Marino swapped.words[0] = src->words[3];
456*e4b17023SJohn Marino swapped.words[1] = src->words[2];
457*e4b17023SJohn Marino swapped.words[2] = src->words[1];
458*e4b17023SJohn Marino swapped.words[3] = src->words[0];
459*e4b17023SJohn Marino #else
460*e4b17023SJohn Marino swapped.words[0] = src->words[1];
461*e4b17023SJohn Marino swapped.words[1] = src->words[0];
462*e4b17023SJohn Marino #endif
463*e4b17023SJohn Marino src = &swapped;
464*e4b17023SJohn Marino #endif
465*e4b17023SJohn Marino
466*e4b17023SJohn Marino #ifdef FLOAT_BIT_ORDER_MISMATCH
467*e4b17023SJohn Marino fraction = src->bits.fraction;
468*e4b17023SJohn Marino exp = src->bits.exp;
469*e4b17023SJohn Marino sign = src->bits.sign;
470*e4b17023SJohn Marino #else
471*e4b17023SJohn Marino # if defined TFLOAT && defined HALFFRACBITS
472*e4b17023SJohn Marino {
473*e4b17023SJohn Marino halffractype high, low;
474*e4b17023SJohn Marino
475*e4b17023SJohn Marino high = src->value_raw >> HALFSHIFT;
476*e4b17023SJohn Marino low = src->value_raw & (((fractype)1 << HALFSHIFT) - 1);
477*e4b17023SJohn Marino
478*e4b17023SJohn Marino fraction = high & ((((fractype)1) << HALFFRACBITS) - 1);
479*e4b17023SJohn Marino fraction <<= FRACBITS - HALFFRACBITS;
480*e4b17023SJohn Marino exp = ((int)(high >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
481*e4b17023SJohn Marino sign = ((int)(high >> (((HALFFRACBITS + EXPBITS))))) & 1;
482*e4b17023SJohn Marino
483*e4b17023SJohn Marino if (exp != EXPMAX && exp != 0 && low != 0)
484*e4b17023SJohn Marino {
485*e4b17023SJohn Marino int lowexp = ((int)(low >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
486*e4b17023SJohn Marino int lowsign = ((int)(low >> (((HALFFRACBITS + EXPBITS))))) & 1;
487*e4b17023SJohn Marino int shift;
488*e4b17023SJohn Marino fractype xlow;
489*e4b17023SJohn Marino
490*e4b17023SJohn Marino xlow = low & ((((fractype)1) << HALFFRACBITS) - 1);
491*e4b17023SJohn Marino if (lowexp)
492*e4b17023SJohn Marino xlow |= (((halffractype)1) << HALFFRACBITS);
493*e4b17023SJohn Marino else
494*e4b17023SJohn Marino lowexp = 1;
495*e4b17023SJohn Marino shift = (FRACBITS - HALFFRACBITS) - (exp - lowexp);
496*e4b17023SJohn Marino if (shift > 0)
497*e4b17023SJohn Marino xlow <<= shift;
498*e4b17023SJohn Marino else if (shift < 0)
499*e4b17023SJohn Marino xlow >>= -shift;
500*e4b17023SJohn Marino if (sign == lowsign)
501*e4b17023SJohn Marino fraction += xlow;
502*e4b17023SJohn Marino else if (fraction >= xlow)
503*e4b17023SJohn Marino fraction -= xlow;
504*e4b17023SJohn Marino else
505*e4b17023SJohn Marino {
506*e4b17023SJohn Marino /* The high part is a power of two but the full number is lower.
507*e4b17023SJohn Marino This code will leave the implicit 1 in FRACTION, but we'd
508*e4b17023SJohn Marino have added that below anyway. */
509*e4b17023SJohn Marino fraction = (((fractype) 1 << FRACBITS) - xlow) << 1;
510*e4b17023SJohn Marino exp--;
511*e4b17023SJohn Marino }
512*e4b17023SJohn Marino }
513*e4b17023SJohn Marino }
514*e4b17023SJohn Marino # else
515*e4b17023SJohn Marino fraction = src->value_raw & ((((fractype)1) << FRACBITS) - 1);
516*e4b17023SJohn Marino exp = ((int)(src->value_raw >> FRACBITS)) & ((1 << EXPBITS) - 1);
517*e4b17023SJohn Marino sign = ((int)(src->value_raw >> (FRACBITS + EXPBITS))) & 1;
518*e4b17023SJohn Marino # endif
519*e4b17023SJohn Marino #endif
520*e4b17023SJohn Marino
521*e4b17023SJohn Marino dst->sign = sign;
522*e4b17023SJohn Marino if (exp == 0)
523*e4b17023SJohn Marino {
524*e4b17023SJohn Marino /* Hmm. Looks like 0 */
525*e4b17023SJohn Marino if (fraction == 0
526*e4b17023SJohn Marino #ifdef NO_DENORMALS
527*e4b17023SJohn Marino || 1
528*e4b17023SJohn Marino #endif
529*e4b17023SJohn Marino )
530*e4b17023SJohn Marino {
531*e4b17023SJohn Marino /* tastes like zero */
532*e4b17023SJohn Marino dst->class = CLASS_ZERO;
533*e4b17023SJohn Marino }
534*e4b17023SJohn Marino else
535*e4b17023SJohn Marino {
536*e4b17023SJohn Marino /* Zero exponent with nonzero fraction - it's denormalized,
537*e4b17023SJohn Marino so there isn't a leading implicit one - we'll shift it so
538*e4b17023SJohn Marino it gets one. */
539*e4b17023SJohn Marino dst->normal_exp = exp - EXPBIAS + 1;
540*e4b17023SJohn Marino fraction <<= NGARDS;
541*e4b17023SJohn Marino
542*e4b17023SJohn Marino dst->class = CLASS_NUMBER;
543*e4b17023SJohn Marino #if 1
544*e4b17023SJohn Marino while (fraction < IMPLICIT_1)
545*e4b17023SJohn Marino {
546*e4b17023SJohn Marino fraction <<= 1;
547*e4b17023SJohn Marino dst->normal_exp--;
548*e4b17023SJohn Marino }
549*e4b17023SJohn Marino #endif
550*e4b17023SJohn Marino dst->fraction.ll = fraction;
551*e4b17023SJohn Marino }
552*e4b17023SJohn Marino }
553*e4b17023SJohn Marino else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS)
554*e4b17023SJohn Marino && __builtin_expect (exp == EXPMAX, 0))
555*e4b17023SJohn Marino {
556*e4b17023SJohn Marino /* Huge exponent*/
557*e4b17023SJohn Marino if (fraction == 0)
558*e4b17023SJohn Marino {
559*e4b17023SJohn Marino /* Attached to a zero fraction - means infinity */
560*e4b17023SJohn Marino dst->class = CLASS_INFINITY;
561*e4b17023SJohn Marino }
562*e4b17023SJohn Marino else
563*e4b17023SJohn Marino {
564*e4b17023SJohn Marino /* Nonzero fraction, means nan */
565*e4b17023SJohn Marino #ifdef QUIET_NAN_NEGATED
566*e4b17023SJohn Marino if ((fraction & QUIET_NAN) == 0)
567*e4b17023SJohn Marino #else
568*e4b17023SJohn Marino if (fraction & QUIET_NAN)
569*e4b17023SJohn Marino #endif
570*e4b17023SJohn Marino {
571*e4b17023SJohn Marino dst->class = CLASS_QNAN;
572*e4b17023SJohn Marino }
573*e4b17023SJohn Marino else
574*e4b17023SJohn Marino {
575*e4b17023SJohn Marino dst->class = CLASS_SNAN;
576*e4b17023SJohn Marino }
577*e4b17023SJohn Marino /* Keep the fraction part as the nan number */
578*e4b17023SJohn Marino dst->fraction.ll = fraction;
579*e4b17023SJohn Marino }
580*e4b17023SJohn Marino }
581*e4b17023SJohn Marino else
582*e4b17023SJohn Marino {
583*e4b17023SJohn Marino /* Nothing strange about this number */
584*e4b17023SJohn Marino dst->normal_exp = exp - EXPBIAS;
585*e4b17023SJohn Marino dst->class = CLASS_NUMBER;
586*e4b17023SJohn Marino dst->fraction.ll = (fraction << NGARDS) | IMPLICIT_1;
587*e4b17023SJohn Marino }
588*e4b17023SJohn Marino }
589*e4b17023SJohn Marino #endif /* L_unpack_df || L_unpack_sf */
590*e4b17023SJohn Marino
591*e4b17023SJohn Marino #if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf)
592*e4b17023SJohn Marino static const fp_number_type *
593*e4b17023SJohn Marino _fpadd_parts (fp_number_type * a,
594*e4b17023SJohn Marino fp_number_type * b,
595*e4b17023SJohn Marino fp_number_type * tmp)
596*e4b17023SJohn Marino {
597*e4b17023SJohn Marino intfrac tfraction;
598*e4b17023SJohn Marino
599*e4b17023SJohn Marino /* Put commonly used fields in local variables. */
600*e4b17023SJohn Marino int a_normal_exp;
601*e4b17023SJohn Marino int b_normal_exp;
602*e4b17023SJohn Marino fractype a_fraction;
603*e4b17023SJohn Marino fractype b_fraction;
604*e4b17023SJohn Marino
605*e4b17023SJohn Marino if (isnan (a))
606*e4b17023SJohn Marino {
607*e4b17023SJohn Marino return a;
608*e4b17023SJohn Marino }
609*e4b17023SJohn Marino if (isnan (b))
610*e4b17023SJohn Marino {
611*e4b17023SJohn Marino return b;
612*e4b17023SJohn Marino }
613*e4b17023SJohn Marino if (isinf (a))
614*e4b17023SJohn Marino {
615*e4b17023SJohn Marino /* Adding infinities with opposite signs yields a NaN. */
616*e4b17023SJohn Marino if (isinf (b) && a->sign != b->sign)
617*e4b17023SJohn Marino return makenan ();
618*e4b17023SJohn Marino return a;
619*e4b17023SJohn Marino }
620*e4b17023SJohn Marino if (isinf (b))
621*e4b17023SJohn Marino {
622*e4b17023SJohn Marino return b;
623*e4b17023SJohn Marino }
624*e4b17023SJohn Marino if (iszero (b))
625*e4b17023SJohn Marino {
626*e4b17023SJohn Marino if (iszero (a))
627*e4b17023SJohn Marino {
628*e4b17023SJohn Marino *tmp = *a;
629*e4b17023SJohn Marino tmp->sign = a->sign & b->sign;
630*e4b17023SJohn Marino return tmp;
631*e4b17023SJohn Marino }
632*e4b17023SJohn Marino return a;
633*e4b17023SJohn Marino }
634*e4b17023SJohn Marino if (iszero (a))
635*e4b17023SJohn Marino {
636*e4b17023SJohn Marino return b;
637*e4b17023SJohn Marino }
638*e4b17023SJohn Marino
639*e4b17023SJohn Marino /* Got two numbers. shift the smaller and increment the exponent till
640*e4b17023SJohn Marino they're the same */
641*e4b17023SJohn Marino {
642*e4b17023SJohn Marino int diff;
643*e4b17023SJohn Marino int sdiff;
644*e4b17023SJohn Marino
645*e4b17023SJohn Marino a_normal_exp = a->normal_exp;
646*e4b17023SJohn Marino b_normal_exp = b->normal_exp;
647*e4b17023SJohn Marino a_fraction = a->fraction.ll;
648*e4b17023SJohn Marino b_fraction = b->fraction.ll;
649*e4b17023SJohn Marino
650*e4b17023SJohn Marino diff = a_normal_exp - b_normal_exp;
651*e4b17023SJohn Marino sdiff = diff;
652*e4b17023SJohn Marino
653*e4b17023SJohn Marino if (diff < 0)
654*e4b17023SJohn Marino diff = -diff;
655*e4b17023SJohn Marino if (diff < FRAC_NBITS)
656*e4b17023SJohn Marino {
657*e4b17023SJohn Marino if (sdiff > 0)
658*e4b17023SJohn Marino {
659*e4b17023SJohn Marino b_normal_exp += diff;
660*e4b17023SJohn Marino LSHIFT (b_fraction, diff);
661*e4b17023SJohn Marino }
662*e4b17023SJohn Marino else if (sdiff < 0)
663*e4b17023SJohn Marino {
664*e4b17023SJohn Marino a_normal_exp += diff;
665*e4b17023SJohn Marino LSHIFT (a_fraction, diff);
666*e4b17023SJohn Marino }
667*e4b17023SJohn Marino }
668*e4b17023SJohn Marino else
669*e4b17023SJohn Marino {
670*e4b17023SJohn Marino /* Somethings's up.. choose the biggest */
671*e4b17023SJohn Marino if (a_normal_exp > b_normal_exp)
672*e4b17023SJohn Marino {
673*e4b17023SJohn Marino b_normal_exp = a_normal_exp;
674*e4b17023SJohn Marino b_fraction = 0;
675*e4b17023SJohn Marino }
676*e4b17023SJohn Marino else
677*e4b17023SJohn Marino {
678*e4b17023SJohn Marino a_normal_exp = b_normal_exp;
679*e4b17023SJohn Marino a_fraction = 0;
680*e4b17023SJohn Marino }
681*e4b17023SJohn Marino }
682*e4b17023SJohn Marino }
683*e4b17023SJohn Marino
684*e4b17023SJohn Marino if (a->sign != b->sign)
685*e4b17023SJohn Marino {
686*e4b17023SJohn Marino if (a->sign)
687*e4b17023SJohn Marino {
688*e4b17023SJohn Marino tfraction = -a_fraction + b_fraction;
689*e4b17023SJohn Marino }
690*e4b17023SJohn Marino else
691*e4b17023SJohn Marino {
692*e4b17023SJohn Marino tfraction = a_fraction - b_fraction;
693*e4b17023SJohn Marino }
694*e4b17023SJohn Marino if (tfraction >= 0)
695*e4b17023SJohn Marino {
696*e4b17023SJohn Marino tmp->sign = 0;
697*e4b17023SJohn Marino tmp->normal_exp = a_normal_exp;
698*e4b17023SJohn Marino tmp->fraction.ll = tfraction;
699*e4b17023SJohn Marino }
700*e4b17023SJohn Marino else
701*e4b17023SJohn Marino {
702*e4b17023SJohn Marino tmp->sign = 1;
703*e4b17023SJohn Marino tmp->normal_exp = a_normal_exp;
704*e4b17023SJohn Marino tmp->fraction.ll = -tfraction;
705*e4b17023SJohn Marino }
706*e4b17023SJohn Marino /* and renormalize it */
707*e4b17023SJohn Marino
708*e4b17023SJohn Marino while (tmp->fraction.ll < IMPLICIT_1 && tmp->fraction.ll)
709*e4b17023SJohn Marino {
710*e4b17023SJohn Marino tmp->fraction.ll <<= 1;
711*e4b17023SJohn Marino tmp->normal_exp--;
712*e4b17023SJohn Marino }
713*e4b17023SJohn Marino }
714*e4b17023SJohn Marino else
715*e4b17023SJohn Marino {
716*e4b17023SJohn Marino tmp->sign = a->sign;
717*e4b17023SJohn Marino tmp->normal_exp = a_normal_exp;
718*e4b17023SJohn Marino tmp->fraction.ll = a_fraction + b_fraction;
719*e4b17023SJohn Marino }
720*e4b17023SJohn Marino tmp->class = CLASS_NUMBER;
721*e4b17023SJohn Marino /* Now the fraction is added, we have to shift down to renormalize the
722*e4b17023SJohn Marino number */
723*e4b17023SJohn Marino
724*e4b17023SJohn Marino if (tmp->fraction.ll >= IMPLICIT_2)
725*e4b17023SJohn Marino {
726*e4b17023SJohn Marino LSHIFT (tmp->fraction.ll, 1);
727*e4b17023SJohn Marino tmp->normal_exp++;
728*e4b17023SJohn Marino }
729*e4b17023SJohn Marino return tmp;
730*e4b17023SJohn Marino }
731*e4b17023SJohn Marino
732*e4b17023SJohn Marino FLO_type
733*e4b17023SJohn Marino add (FLO_type arg_a, FLO_type arg_b)
734*e4b17023SJohn Marino {
735*e4b17023SJohn Marino fp_number_type a;
736*e4b17023SJohn Marino fp_number_type b;
737*e4b17023SJohn Marino fp_number_type tmp;
738*e4b17023SJohn Marino const fp_number_type *res;
739*e4b17023SJohn Marino FLO_union_type au, bu;
740*e4b17023SJohn Marino
741*e4b17023SJohn Marino au.value = arg_a;
742*e4b17023SJohn Marino bu.value = arg_b;
743*e4b17023SJohn Marino
744*e4b17023SJohn Marino unpack_d (&au, &a);
745*e4b17023SJohn Marino unpack_d (&bu, &b);
746*e4b17023SJohn Marino
747*e4b17023SJohn Marino res = _fpadd_parts (&a, &b, &tmp);
748*e4b17023SJohn Marino
749*e4b17023SJohn Marino return pack_d (res);
750*e4b17023SJohn Marino }
751*e4b17023SJohn Marino
752*e4b17023SJohn Marino FLO_type
753*e4b17023SJohn Marino sub (FLO_type arg_a, FLO_type arg_b)
754*e4b17023SJohn Marino {
755*e4b17023SJohn Marino fp_number_type a;
756*e4b17023SJohn Marino fp_number_type b;
757*e4b17023SJohn Marino fp_number_type tmp;
758*e4b17023SJohn Marino const fp_number_type *res;
759*e4b17023SJohn Marino FLO_union_type au, bu;
760*e4b17023SJohn Marino
761*e4b17023SJohn Marino au.value = arg_a;
762*e4b17023SJohn Marino bu.value = arg_b;
763*e4b17023SJohn Marino
764*e4b17023SJohn Marino unpack_d (&au, &a);
765*e4b17023SJohn Marino unpack_d (&bu, &b);
766*e4b17023SJohn Marino
767*e4b17023SJohn Marino b.sign ^= 1;
768*e4b17023SJohn Marino
769*e4b17023SJohn Marino res = _fpadd_parts (&a, &b, &tmp);
770*e4b17023SJohn Marino
771*e4b17023SJohn Marino return pack_d (res);
772*e4b17023SJohn Marino }
773*e4b17023SJohn Marino #endif /* L_addsub_sf || L_addsub_df */
774*e4b17023SJohn Marino
775*e4b17023SJohn Marino #if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf)
776*e4b17023SJohn Marino static inline __attribute__ ((__always_inline__)) const fp_number_type *
777*e4b17023SJohn Marino _fpmul_parts ( fp_number_type * a,
778*e4b17023SJohn Marino fp_number_type * b,
779*e4b17023SJohn Marino fp_number_type * tmp)
780*e4b17023SJohn Marino {
781*e4b17023SJohn Marino fractype low = 0;
782*e4b17023SJohn Marino fractype high = 0;
783*e4b17023SJohn Marino
784*e4b17023SJohn Marino if (isnan (a))
785*e4b17023SJohn Marino {
786*e4b17023SJohn Marino a->sign = a->sign != b->sign;
787*e4b17023SJohn Marino return a;
788*e4b17023SJohn Marino }
789*e4b17023SJohn Marino if (isnan (b))
790*e4b17023SJohn Marino {
791*e4b17023SJohn Marino b->sign = a->sign != b->sign;
792*e4b17023SJohn Marino return b;
793*e4b17023SJohn Marino }
794*e4b17023SJohn Marino if (isinf (a))
795*e4b17023SJohn Marino {
796*e4b17023SJohn Marino if (iszero (b))
797*e4b17023SJohn Marino return makenan ();
798*e4b17023SJohn Marino a->sign = a->sign != b->sign;
799*e4b17023SJohn Marino return a;
800*e4b17023SJohn Marino }
801*e4b17023SJohn Marino if (isinf (b))
802*e4b17023SJohn Marino {
803*e4b17023SJohn Marino if (iszero (a))
804*e4b17023SJohn Marino {
805*e4b17023SJohn Marino return makenan ();
806*e4b17023SJohn Marino }
807*e4b17023SJohn Marino b->sign = a->sign != b->sign;
808*e4b17023SJohn Marino return b;
809*e4b17023SJohn Marino }
810*e4b17023SJohn Marino if (iszero (a))
811*e4b17023SJohn Marino {
812*e4b17023SJohn Marino a->sign = a->sign != b->sign;
813*e4b17023SJohn Marino return a;
814*e4b17023SJohn Marino }
815*e4b17023SJohn Marino if (iszero (b))
816*e4b17023SJohn Marino {
817*e4b17023SJohn Marino b->sign = a->sign != b->sign;
818*e4b17023SJohn Marino return b;
819*e4b17023SJohn Marino }
820*e4b17023SJohn Marino
821*e4b17023SJohn Marino /* Calculate the mantissa by multiplying both numbers to get a
822*e4b17023SJohn Marino twice-as-wide number. */
823*e4b17023SJohn Marino {
824*e4b17023SJohn Marino #if defined(NO_DI_MODE) || defined(TFLOAT)
825*e4b17023SJohn Marino {
826*e4b17023SJohn Marino fractype x = a->fraction.ll;
827*e4b17023SJohn Marino fractype ylow = b->fraction.ll;
828*e4b17023SJohn Marino fractype yhigh = 0;
829*e4b17023SJohn Marino int bit;
830*e4b17023SJohn Marino
831*e4b17023SJohn Marino /* ??? This does multiplies one bit at a time. Optimize. */
832*e4b17023SJohn Marino for (bit = 0; bit < FRAC_NBITS; bit++)
833*e4b17023SJohn Marino {
834*e4b17023SJohn Marino int carry;
835*e4b17023SJohn Marino
836*e4b17023SJohn Marino if (x & 1)
837*e4b17023SJohn Marino {
838*e4b17023SJohn Marino carry = (low += ylow) < ylow;
839*e4b17023SJohn Marino high += yhigh + carry;
840*e4b17023SJohn Marino }
841*e4b17023SJohn Marino yhigh <<= 1;
842*e4b17023SJohn Marino if (ylow & FRACHIGH)
843*e4b17023SJohn Marino {
844*e4b17023SJohn Marino yhigh |= 1;
845*e4b17023SJohn Marino }
846*e4b17023SJohn Marino ylow <<= 1;
847*e4b17023SJohn Marino x >>= 1;
848*e4b17023SJohn Marino }
849*e4b17023SJohn Marino }
850*e4b17023SJohn Marino #elif defined(FLOAT)
851*e4b17023SJohn Marino /* Multiplying two USIs to get a UDI, we're safe. */
852*e4b17023SJohn Marino {
853*e4b17023SJohn Marino UDItype answer = (UDItype)a->fraction.ll * (UDItype)b->fraction.ll;
854*e4b17023SJohn Marino
855*e4b17023SJohn Marino high = answer >> BITS_PER_SI;
856*e4b17023SJohn Marino low = answer;
857*e4b17023SJohn Marino }
858*e4b17023SJohn Marino #else
859*e4b17023SJohn Marino /* fractype is DImode, but we need the result to be twice as wide.
860*e4b17023SJohn Marino Assuming a widening multiply from DImode to TImode is not
861*e4b17023SJohn Marino available, build one by hand. */
862*e4b17023SJohn Marino {
863*e4b17023SJohn Marino USItype nl = a->fraction.ll;
864*e4b17023SJohn Marino USItype nh = a->fraction.ll >> BITS_PER_SI;
865*e4b17023SJohn Marino USItype ml = b->fraction.ll;
866*e4b17023SJohn Marino USItype mh = b->fraction.ll >> BITS_PER_SI;
867*e4b17023SJohn Marino UDItype pp_ll = (UDItype) ml * nl;
868*e4b17023SJohn Marino UDItype pp_hl = (UDItype) mh * nl;
869*e4b17023SJohn Marino UDItype pp_lh = (UDItype) ml * nh;
870*e4b17023SJohn Marino UDItype pp_hh = (UDItype) mh * nh;
871*e4b17023SJohn Marino UDItype res2 = 0;
872*e4b17023SJohn Marino UDItype res0 = 0;
873*e4b17023SJohn Marino UDItype ps_hh__ = pp_hl + pp_lh;
874*e4b17023SJohn Marino if (ps_hh__ < pp_hl)
875*e4b17023SJohn Marino res2 += (UDItype)1 << BITS_PER_SI;
876*e4b17023SJohn Marino pp_hl = (UDItype)(USItype)ps_hh__ << BITS_PER_SI;
877*e4b17023SJohn Marino res0 = pp_ll + pp_hl;
878*e4b17023SJohn Marino if (res0 < pp_ll)
879*e4b17023SJohn Marino res2++;
880*e4b17023SJohn Marino res2 += (ps_hh__ >> BITS_PER_SI) + pp_hh;
881*e4b17023SJohn Marino high = res2;
882*e4b17023SJohn Marino low = res0;
883*e4b17023SJohn Marino }
884*e4b17023SJohn Marino #endif
885*e4b17023SJohn Marino }
886*e4b17023SJohn Marino
887*e4b17023SJohn Marino tmp->normal_exp = a->normal_exp + b->normal_exp
888*e4b17023SJohn Marino + FRAC_NBITS - (FRACBITS + NGARDS);
889*e4b17023SJohn Marino tmp->sign = a->sign != b->sign;
890*e4b17023SJohn Marino while (high >= IMPLICIT_2)
891*e4b17023SJohn Marino {
892*e4b17023SJohn Marino tmp->normal_exp++;
893*e4b17023SJohn Marino if (high & 1)
894*e4b17023SJohn Marino {
895*e4b17023SJohn Marino low >>= 1;
896*e4b17023SJohn Marino low |= FRACHIGH;
897*e4b17023SJohn Marino }
898*e4b17023SJohn Marino high >>= 1;
899*e4b17023SJohn Marino }
900*e4b17023SJohn Marino while (high < IMPLICIT_1)
901*e4b17023SJohn Marino {
902*e4b17023SJohn Marino tmp->normal_exp--;
903*e4b17023SJohn Marino
904*e4b17023SJohn Marino high <<= 1;
905*e4b17023SJohn Marino if (low & FRACHIGH)
906*e4b17023SJohn Marino high |= 1;
907*e4b17023SJohn Marino low <<= 1;
908*e4b17023SJohn Marino }
909*e4b17023SJohn Marino
910*e4b17023SJohn Marino if (!ROUND_TOWARDS_ZERO && (high & GARDMASK) == GARDMSB)
911*e4b17023SJohn Marino {
912*e4b17023SJohn Marino if (high & (1 << NGARDS))
913*e4b17023SJohn Marino {
914*e4b17023SJohn Marino /* Because we're half way, we would round to even by adding
915*e4b17023SJohn Marino GARDROUND + 1, except that's also done in the packing
916*e4b17023SJohn Marino function, and rounding twice will lose precision and cause
917*e4b17023SJohn Marino the result to be too far off. Example: 32-bit floats with
918*e4b17023SJohn Marino bit patterns 0xfff * 0x3f800400 ~= 0xfff (less than 0.5ulp
919*e4b17023SJohn Marino off), not 0x1000 (more than 0.5ulp off). */
920*e4b17023SJohn Marino }
921*e4b17023SJohn Marino else if (low)
922*e4b17023SJohn Marino {
923*e4b17023SJohn Marino /* We're a further than half way by a small amount corresponding
924*e4b17023SJohn Marino to the bits set in "low". Knowing that, we round here and
925*e4b17023SJohn Marino not in pack_d, because there we don't have "low" available
926*e4b17023SJohn Marino anymore. */
927*e4b17023SJohn Marino high += GARDROUND + 1;
928*e4b17023SJohn Marino
929*e4b17023SJohn Marino /* Avoid further rounding in pack_d. */
930*e4b17023SJohn Marino high &= ~(fractype) GARDMASK;
931*e4b17023SJohn Marino }
932*e4b17023SJohn Marino }
933*e4b17023SJohn Marino tmp->fraction.ll = high;
934*e4b17023SJohn Marino tmp->class = CLASS_NUMBER;
935*e4b17023SJohn Marino return tmp;
936*e4b17023SJohn Marino }
937*e4b17023SJohn Marino
938*e4b17023SJohn Marino FLO_type
939*e4b17023SJohn Marino multiply (FLO_type arg_a, FLO_type arg_b)
940*e4b17023SJohn Marino {
941*e4b17023SJohn Marino fp_number_type a;
942*e4b17023SJohn Marino fp_number_type b;
943*e4b17023SJohn Marino fp_number_type tmp;
944*e4b17023SJohn Marino const fp_number_type *res;
945*e4b17023SJohn Marino FLO_union_type au, bu;
946*e4b17023SJohn Marino
947*e4b17023SJohn Marino au.value = arg_a;
948*e4b17023SJohn Marino bu.value = arg_b;
949*e4b17023SJohn Marino
950*e4b17023SJohn Marino unpack_d (&au, &a);
951*e4b17023SJohn Marino unpack_d (&bu, &b);
952*e4b17023SJohn Marino
953*e4b17023SJohn Marino res = _fpmul_parts (&a, &b, &tmp);
954*e4b17023SJohn Marino
955*e4b17023SJohn Marino return pack_d (res);
956*e4b17023SJohn Marino }
957*e4b17023SJohn Marino #endif /* L_mul_sf || L_mul_df || L_mul_tf */
958*e4b17023SJohn Marino
959*e4b17023SJohn Marino #if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf)
960*e4b17023SJohn Marino static inline __attribute__ ((__always_inline__)) const fp_number_type *
961*e4b17023SJohn Marino _fpdiv_parts (fp_number_type * a,
962*e4b17023SJohn Marino fp_number_type * b)
963*e4b17023SJohn Marino {
964*e4b17023SJohn Marino fractype bit;
965*e4b17023SJohn Marino fractype numerator;
966*e4b17023SJohn Marino fractype denominator;
967*e4b17023SJohn Marino fractype quotient;
968*e4b17023SJohn Marino
969*e4b17023SJohn Marino if (isnan (a))
970*e4b17023SJohn Marino {
971*e4b17023SJohn Marino return a;
972*e4b17023SJohn Marino }
973*e4b17023SJohn Marino if (isnan (b))
974*e4b17023SJohn Marino {
975*e4b17023SJohn Marino return b;
976*e4b17023SJohn Marino }
977*e4b17023SJohn Marino
978*e4b17023SJohn Marino a->sign = a->sign ^ b->sign;
979*e4b17023SJohn Marino
980*e4b17023SJohn Marino if (isinf (a) || iszero (a))
981*e4b17023SJohn Marino {
982*e4b17023SJohn Marino if (a->class == b->class)
983*e4b17023SJohn Marino return makenan ();
984*e4b17023SJohn Marino return a;
985*e4b17023SJohn Marino }
986*e4b17023SJohn Marino
987*e4b17023SJohn Marino if (isinf (b))
988*e4b17023SJohn Marino {
989*e4b17023SJohn Marino a->fraction.ll = 0;
990*e4b17023SJohn Marino a->normal_exp = 0;
991*e4b17023SJohn Marino return a;
992*e4b17023SJohn Marino }
993*e4b17023SJohn Marino if (iszero (b))
994*e4b17023SJohn Marino {
995*e4b17023SJohn Marino a->class = CLASS_INFINITY;
996*e4b17023SJohn Marino return a;
997*e4b17023SJohn Marino }
998*e4b17023SJohn Marino
999*e4b17023SJohn Marino /* Calculate the mantissa by multiplying both 64bit numbers to get a
1000*e4b17023SJohn Marino 128 bit number */
1001*e4b17023SJohn Marino {
1002*e4b17023SJohn Marino /* quotient =
1003*e4b17023SJohn Marino ( numerator / denominator) * 2^(numerator exponent - denominator exponent)
1004*e4b17023SJohn Marino */
1005*e4b17023SJohn Marino
1006*e4b17023SJohn Marino a->normal_exp = a->normal_exp - b->normal_exp;
1007*e4b17023SJohn Marino numerator = a->fraction.ll;
1008*e4b17023SJohn Marino denominator = b->fraction.ll;
1009*e4b17023SJohn Marino
1010*e4b17023SJohn Marino if (numerator < denominator)
1011*e4b17023SJohn Marino {
1012*e4b17023SJohn Marino /* Fraction will be less than 1.0 */
1013*e4b17023SJohn Marino numerator *= 2;
1014*e4b17023SJohn Marino a->normal_exp--;
1015*e4b17023SJohn Marino }
1016*e4b17023SJohn Marino bit = IMPLICIT_1;
1017*e4b17023SJohn Marino quotient = 0;
1018*e4b17023SJohn Marino /* ??? Does divide one bit at a time. Optimize. */
1019*e4b17023SJohn Marino while (bit)
1020*e4b17023SJohn Marino {
1021*e4b17023SJohn Marino if (numerator >= denominator)
1022*e4b17023SJohn Marino {
1023*e4b17023SJohn Marino quotient |= bit;
1024*e4b17023SJohn Marino numerator -= denominator;
1025*e4b17023SJohn Marino }
1026*e4b17023SJohn Marino bit >>= 1;
1027*e4b17023SJohn Marino numerator *= 2;
1028*e4b17023SJohn Marino }
1029*e4b17023SJohn Marino
1030*e4b17023SJohn Marino if (!ROUND_TOWARDS_ZERO && (quotient & GARDMASK) == GARDMSB)
1031*e4b17023SJohn Marino {
1032*e4b17023SJohn Marino if (quotient & (1 << NGARDS))
1033*e4b17023SJohn Marino {
1034*e4b17023SJohn Marino /* Because we're half way, we would round to even by adding
1035*e4b17023SJohn Marino GARDROUND + 1, except that's also done in the packing
1036*e4b17023SJohn Marino function, and rounding twice will lose precision and cause
1037*e4b17023SJohn Marino the result to be too far off. */
1038*e4b17023SJohn Marino }
1039*e4b17023SJohn Marino else if (numerator)
1040*e4b17023SJohn Marino {
1041*e4b17023SJohn Marino /* We're a further than half way by the small amount
1042*e4b17023SJohn Marino corresponding to the bits set in "numerator". Knowing
1043*e4b17023SJohn Marino that, we round here and not in pack_d, because there we
1044*e4b17023SJohn Marino don't have "numerator" available anymore. */
1045*e4b17023SJohn Marino quotient += GARDROUND + 1;
1046*e4b17023SJohn Marino
1047*e4b17023SJohn Marino /* Avoid further rounding in pack_d. */
1048*e4b17023SJohn Marino quotient &= ~(fractype) GARDMASK;
1049*e4b17023SJohn Marino }
1050*e4b17023SJohn Marino }
1051*e4b17023SJohn Marino
1052*e4b17023SJohn Marino a->fraction.ll = quotient;
1053*e4b17023SJohn Marino return (a);
1054*e4b17023SJohn Marino }
1055*e4b17023SJohn Marino }
1056*e4b17023SJohn Marino
1057*e4b17023SJohn Marino FLO_type
1058*e4b17023SJohn Marino divide (FLO_type arg_a, FLO_type arg_b)
1059*e4b17023SJohn Marino {
1060*e4b17023SJohn Marino fp_number_type a;
1061*e4b17023SJohn Marino fp_number_type b;
1062*e4b17023SJohn Marino const fp_number_type *res;
1063*e4b17023SJohn Marino FLO_union_type au, bu;
1064*e4b17023SJohn Marino
1065*e4b17023SJohn Marino au.value = arg_a;
1066*e4b17023SJohn Marino bu.value = arg_b;
1067*e4b17023SJohn Marino
1068*e4b17023SJohn Marino unpack_d (&au, &a);
1069*e4b17023SJohn Marino unpack_d (&bu, &b);
1070*e4b17023SJohn Marino
1071*e4b17023SJohn Marino res = _fpdiv_parts (&a, &b);
1072*e4b17023SJohn Marino
1073*e4b17023SJohn Marino return pack_d (res);
1074*e4b17023SJohn Marino }
1075*e4b17023SJohn Marino #endif /* L_div_sf || L_div_df */
1076*e4b17023SJohn Marino
1077*e4b17023SJohn Marino #if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df) \
1078*e4b17023SJohn Marino || defined(L_fpcmp_parts_tf)
1079*e4b17023SJohn Marino /* according to the demo, fpcmp returns a comparison with 0... thus
1080*e4b17023SJohn Marino a<b -> -1
1081*e4b17023SJohn Marino a==b -> 0
1082*e4b17023SJohn Marino a>b -> +1
1083*e4b17023SJohn Marino */
1084*e4b17023SJohn Marino
1085*e4b17023SJohn Marino int
1086*e4b17023SJohn Marino __fpcmp_parts (fp_number_type * a, fp_number_type * b)
1087*e4b17023SJohn Marino {
1088*e4b17023SJohn Marino #if 0
1089*e4b17023SJohn Marino /* either nan -> unordered. Must be checked outside of this routine. */
1090*e4b17023SJohn Marino if (isnan (a) && isnan (b))
1091*e4b17023SJohn Marino {
1092*e4b17023SJohn Marino return 1; /* still unordered! */
1093*e4b17023SJohn Marino }
1094*e4b17023SJohn Marino #endif
1095*e4b17023SJohn Marino
1096*e4b17023SJohn Marino if (isnan (a) || isnan (b))
1097*e4b17023SJohn Marino {
1098*e4b17023SJohn Marino return 1; /* how to indicate unordered compare? */
1099*e4b17023SJohn Marino }
1100*e4b17023SJohn Marino if (isinf (a) && isinf (b))
1101*e4b17023SJohn Marino {
1102*e4b17023SJohn Marino /* +inf > -inf, but +inf != +inf */
1103*e4b17023SJohn Marino /* b \a| +inf(0)| -inf(1)
1104*e4b17023SJohn Marino ______\+--------+--------
1105*e4b17023SJohn Marino +inf(0)| a==b(0)| a<b(-1)
1106*e4b17023SJohn Marino -------+--------+--------
1107*e4b17023SJohn Marino -inf(1)| a>b(1) | a==b(0)
1108*e4b17023SJohn Marino -------+--------+--------
1109*e4b17023SJohn Marino So since unordered must be nonzero, just line up the columns...
1110*e4b17023SJohn Marino */
1111*e4b17023SJohn Marino return b->sign - a->sign;
1112*e4b17023SJohn Marino }
1113*e4b17023SJohn Marino /* but not both... */
1114*e4b17023SJohn Marino if (isinf (a))
1115*e4b17023SJohn Marino {
1116*e4b17023SJohn Marino return a->sign ? -1 : 1;
1117*e4b17023SJohn Marino }
1118*e4b17023SJohn Marino if (isinf (b))
1119*e4b17023SJohn Marino {
1120*e4b17023SJohn Marino return b->sign ? 1 : -1;
1121*e4b17023SJohn Marino }
1122*e4b17023SJohn Marino if (iszero (a) && iszero (b))
1123*e4b17023SJohn Marino {
1124*e4b17023SJohn Marino return 0;
1125*e4b17023SJohn Marino }
1126*e4b17023SJohn Marino if (iszero (a))
1127*e4b17023SJohn Marino {
1128*e4b17023SJohn Marino return b->sign ? 1 : -1;
1129*e4b17023SJohn Marino }
1130*e4b17023SJohn Marino if (iszero (b))
1131*e4b17023SJohn Marino {
1132*e4b17023SJohn Marino return a->sign ? -1 : 1;
1133*e4b17023SJohn Marino }
1134*e4b17023SJohn Marino /* now both are "normal". */
1135*e4b17023SJohn Marino if (a->sign != b->sign)
1136*e4b17023SJohn Marino {
1137*e4b17023SJohn Marino /* opposite signs */
1138*e4b17023SJohn Marino return a->sign ? -1 : 1;
1139*e4b17023SJohn Marino }
1140*e4b17023SJohn Marino /* same sign; exponents? */
1141*e4b17023SJohn Marino if (a->normal_exp > b->normal_exp)
1142*e4b17023SJohn Marino {
1143*e4b17023SJohn Marino return a->sign ? -1 : 1;
1144*e4b17023SJohn Marino }
1145*e4b17023SJohn Marino if (a->normal_exp < b->normal_exp)
1146*e4b17023SJohn Marino {
1147*e4b17023SJohn Marino return a->sign ? 1 : -1;
1148*e4b17023SJohn Marino }
1149*e4b17023SJohn Marino /* same exponents; check size. */
1150*e4b17023SJohn Marino if (a->fraction.ll > b->fraction.ll)
1151*e4b17023SJohn Marino {
1152*e4b17023SJohn Marino return a->sign ? -1 : 1;
1153*e4b17023SJohn Marino }
1154*e4b17023SJohn Marino if (a->fraction.ll < b->fraction.ll)
1155*e4b17023SJohn Marino {
1156*e4b17023SJohn Marino return a->sign ? 1 : -1;
1157*e4b17023SJohn Marino }
1158*e4b17023SJohn Marino /* after all that, they're equal. */
1159*e4b17023SJohn Marino return 0;
1160*e4b17023SJohn Marino }
1161*e4b17023SJohn Marino #endif
1162*e4b17023SJohn Marino
1163*e4b17023SJohn Marino #if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compoare_tf)
1164*e4b17023SJohn Marino CMPtype
1165*e4b17023SJohn Marino compare (FLO_type arg_a, FLO_type arg_b)
1166*e4b17023SJohn Marino {
1167*e4b17023SJohn Marino fp_number_type a;
1168*e4b17023SJohn Marino fp_number_type b;
1169*e4b17023SJohn Marino FLO_union_type au, bu;
1170*e4b17023SJohn Marino
1171*e4b17023SJohn Marino au.value = arg_a;
1172*e4b17023SJohn Marino bu.value = arg_b;
1173*e4b17023SJohn Marino
1174*e4b17023SJohn Marino unpack_d (&au, &a);
1175*e4b17023SJohn Marino unpack_d (&bu, &b);
1176*e4b17023SJohn Marino
1177*e4b17023SJohn Marino return __fpcmp_parts (&a, &b);
1178*e4b17023SJohn Marino }
1179*e4b17023SJohn Marino #endif /* L_compare_sf || L_compare_df */
1180*e4b17023SJohn Marino
1181*e4b17023SJohn Marino /* These should be optimized for their specific tasks someday. */
1182*e4b17023SJohn Marino
1183*e4b17023SJohn Marino #if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf)
1184*e4b17023SJohn Marino CMPtype
1185*e4b17023SJohn Marino _eq_f2 (FLO_type arg_a, FLO_type arg_b)
1186*e4b17023SJohn Marino {
1187*e4b17023SJohn Marino fp_number_type a;
1188*e4b17023SJohn Marino fp_number_type b;
1189*e4b17023SJohn Marino FLO_union_type au, bu;
1190*e4b17023SJohn Marino
1191*e4b17023SJohn Marino au.value = arg_a;
1192*e4b17023SJohn Marino bu.value = arg_b;
1193*e4b17023SJohn Marino
1194*e4b17023SJohn Marino unpack_d (&au, &a);
1195*e4b17023SJohn Marino unpack_d (&bu, &b);
1196*e4b17023SJohn Marino
1197*e4b17023SJohn Marino if (isnan (&a) || isnan (&b))
1198*e4b17023SJohn Marino return 1; /* false, truth == 0 */
1199*e4b17023SJohn Marino
1200*e4b17023SJohn Marino return __fpcmp_parts (&a, &b) ;
1201*e4b17023SJohn Marino }
1202*e4b17023SJohn Marino #endif /* L_eq_sf || L_eq_df */
1203*e4b17023SJohn Marino
1204*e4b17023SJohn Marino #if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf)
1205*e4b17023SJohn Marino CMPtype
1206*e4b17023SJohn Marino _ne_f2 (FLO_type arg_a, FLO_type arg_b)
1207*e4b17023SJohn Marino {
1208*e4b17023SJohn Marino fp_number_type a;
1209*e4b17023SJohn Marino fp_number_type b;
1210*e4b17023SJohn Marino FLO_union_type au, bu;
1211*e4b17023SJohn Marino
1212*e4b17023SJohn Marino au.value = arg_a;
1213*e4b17023SJohn Marino bu.value = arg_b;
1214*e4b17023SJohn Marino
1215*e4b17023SJohn Marino unpack_d (&au, &a);
1216*e4b17023SJohn Marino unpack_d (&bu, &b);
1217*e4b17023SJohn Marino
1218*e4b17023SJohn Marino if (isnan (&a) || isnan (&b))
1219*e4b17023SJohn Marino return 1; /* true, truth != 0 */
1220*e4b17023SJohn Marino
1221*e4b17023SJohn Marino return __fpcmp_parts (&a, &b) ;
1222*e4b17023SJohn Marino }
1223*e4b17023SJohn Marino #endif /* L_ne_sf || L_ne_df */
1224*e4b17023SJohn Marino
1225*e4b17023SJohn Marino #if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf)
1226*e4b17023SJohn Marino CMPtype
1227*e4b17023SJohn Marino _gt_f2 (FLO_type arg_a, FLO_type arg_b)
1228*e4b17023SJohn Marino {
1229*e4b17023SJohn Marino fp_number_type a;
1230*e4b17023SJohn Marino fp_number_type b;
1231*e4b17023SJohn Marino FLO_union_type au, bu;
1232*e4b17023SJohn Marino
1233*e4b17023SJohn Marino au.value = arg_a;
1234*e4b17023SJohn Marino bu.value = arg_b;
1235*e4b17023SJohn Marino
1236*e4b17023SJohn Marino unpack_d (&au, &a);
1237*e4b17023SJohn Marino unpack_d (&bu, &b);
1238*e4b17023SJohn Marino
1239*e4b17023SJohn Marino if (isnan (&a) || isnan (&b))
1240*e4b17023SJohn Marino return -1; /* false, truth > 0 */
1241*e4b17023SJohn Marino
1242*e4b17023SJohn Marino return __fpcmp_parts (&a, &b);
1243*e4b17023SJohn Marino }
1244*e4b17023SJohn Marino #endif /* L_gt_sf || L_gt_df */
1245*e4b17023SJohn Marino
1246*e4b17023SJohn Marino #if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf)
1247*e4b17023SJohn Marino CMPtype
1248*e4b17023SJohn Marino _ge_f2 (FLO_type arg_a, FLO_type arg_b)
1249*e4b17023SJohn Marino {
1250*e4b17023SJohn Marino fp_number_type a;
1251*e4b17023SJohn Marino fp_number_type b;
1252*e4b17023SJohn Marino FLO_union_type au, bu;
1253*e4b17023SJohn Marino
1254*e4b17023SJohn Marino au.value = arg_a;
1255*e4b17023SJohn Marino bu.value = arg_b;
1256*e4b17023SJohn Marino
1257*e4b17023SJohn Marino unpack_d (&au, &a);
1258*e4b17023SJohn Marino unpack_d (&bu, &b);
1259*e4b17023SJohn Marino
1260*e4b17023SJohn Marino if (isnan (&a) || isnan (&b))
1261*e4b17023SJohn Marino return -1; /* false, truth >= 0 */
1262*e4b17023SJohn Marino return __fpcmp_parts (&a, &b) ;
1263*e4b17023SJohn Marino }
1264*e4b17023SJohn Marino #endif /* L_ge_sf || L_ge_df */
1265*e4b17023SJohn Marino
1266*e4b17023SJohn Marino #if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf)
1267*e4b17023SJohn Marino CMPtype
1268*e4b17023SJohn Marino _lt_f2 (FLO_type arg_a, FLO_type arg_b)
1269*e4b17023SJohn Marino {
1270*e4b17023SJohn Marino fp_number_type a;
1271*e4b17023SJohn Marino fp_number_type b;
1272*e4b17023SJohn Marino FLO_union_type au, bu;
1273*e4b17023SJohn Marino
1274*e4b17023SJohn Marino au.value = arg_a;
1275*e4b17023SJohn Marino bu.value = arg_b;
1276*e4b17023SJohn Marino
1277*e4b17023SJohn Marino unpack_d (&au, &a);
1278*e4b17023SJohn Marino unpack_d (&bu, &b);
1279*e4b17023SJohn Marino
1280*e4b17023SJohn Marino if (isnan (&a) || isnan (&b))
1281*e4b17023SJohn Marino return 1; /* false, truth < 0 */
1282*e4b17023SJohn Marino
1283*e4b17023SJohn Marino return __fpcmp_parts (&a, &b);
1284*e4b17023SJohn Marino }
1285*e4b17023SJohn Marino #endif /* L_lt_sf || L_lt_df */
1286*e4b17023SJohn Marino
1287*e4b17023SJohn Marino #if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf)
1288*e4b17023SJohn Marino CMPtype
1289*e4b17023SJohn Marino _le_f2 (FLO_type arg_a, FLO_type arg_b)
1290*e4b17023SJohn Marino {
1291*e4b17023SJohn Marino fp_number_type a;
1292*e4b17023SJohn Marino fp_number_type b;
1293*e4b17023SJohn Marino FLO_union_type au, bu;
1294*e4b17023SJohn Marino
1295*e4b17023SJohn Marino au.value = arg_a;
1296*e4b17023SJohn Marino bu.value = arg_b;
1297*e4b17023SJohn Marino
1298*e4b17023SJohn Marino unpack_d (&au, &a);
1299*e4b17023SJohn Marino unpack_d (&bu, &b);
1300*e4b17023SJohn Marino
1301*e4b17023SJohn Marino if (isnan (&a) || isnan (&b))
1302*e4b17023SJohn Marino return 1; /* false, truth <= 0 */
1303*e4b17023SJohn Marino
1304*e4b17023SJohn Marino return __fpcmp_parts (&a, &b) ;
1305*e4b17023SJohn Marino }
1306*e4b17023SJohn Marino #endif /* L_le_sf || L_le_df */
1307*e4b17023SJohn Marino
1308*e4b17023SJohn Marino #if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf)
1309*e4b17023SJohn Marino CMPtype
1310*e4b17023SJohn Marino _unord_f2 (FLO_type arg_a, FLO_type arg_b)
1311*e4b17023SJohn Marino {
1312*e4b17023SJohn Marino fp_number_type a;
1313*e4b17023SJohn Marino fp_number_type b;
1314*e4b17023SJohn Marino FLO_union_type au, bu;
1315*e4b17023SJohn Marino
1316*e4b17023SJohn Marino au.value = arg_a;
1317*e4b17023SJohn Marino bu.value = arg_b;
1318*e4b17023SJohn Marino
1319*e4b17023SJohn Marino unpack_d (&au, &a);
1320*e4b17023SJohn Marino unpack_d (&bu, &b);
1321*e4b17023SJohn Marino
1322*e4b17023SJohn Marino return (isnan (&a) || isnan (&b));
1323*e4b17023SJohn Marino }
1324*e4b17023SJohn Marino #endif /* L_unord_sf || L_unord_df */
1325*e4b17023SJohn Marino
1326*e4b17023SJohn Marino #if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf)
1327*e4b17023SJohn Marino FLO_type
1328*e4b17023SJohn Marino si_to_float (SItype arg_a)
1329*e4b17023SJohn Marino {
1330*e4b17023SJohn Marino fp_number_type in;
1331*e4b17023SJohn Marino
1332*e4b17023SJohn Marino in.class = CLASS_NUMBER;
1333*e4b17023SJohn Marino in.sign = arg_a < 0;
1334*e4b17023SJohn Marino if (!arg_a)
1335*e4b17023SJohn Marino {
1336*e4b17023SJohn Marino in.class = CLASS_ZERO;
1337*e4b17023SJohn Marino }
1338*e4b17023SJohn Marino else
1339*e4b17023SJohn Marino {
1340*e4b17023SJohn Marino USItype uarg;
1341*e4b17023SJohn Marino int shift;
1342*e4b17023SJohn Marino in.normal_exp = FRACBITS + NGARDS;
1343*e4b17023SJohn Marino if (in.sign)
1344*e4b17023SJohn Marino {
1345*e4b17023SJohn Marino /* Special case for minint, since there is no +ve integer
1346*e4b17023SJohn Marino representation for it */
1347*e4b17023SJohn Marino if (arg_a == (- MAX_SI_INT - 1))
1348*e4b17023SJohn Marino {
1349*e4b17023SJohn Marino return (FLO_type)(- MAX_SI_INT - 1);
1350*e4b17023SJohn Marino }
1351*e4b17023SJohn Marino uarg = (-arg_a);
1352*e4b17023SJohn Marino }
1353*e4b17023SJohn Marino else
1354*e4b17023SJohn Marino uarg = arg_a;
1355*e4b17023SJohn Marino
1356*e4b17023SJohn Marino in.fraction.ll = uarg;
1357*e4b17023SJohn Marino shift = clzusi (uarg) - (BITS_PER_SI - 1 - FRACBITS - NGARDS);
1358*e4b17023SJohn Marino if (shift > 0)
1359*e4b17023SJohn Marino {
1360*e4b17023SJohn Marino in.fraction.ll <<= shift;
1361*e4b17023SJohn Marino in.normal_exp -= shift;
1362*e4b17023SJohn Marino }
1363*e4b17023SJohn Marino }
1364*e4b17023SJohn Marino return pack_d (&in);
1365*e4b17023SJohn Marino }
1366*e4b17023SJohn Marino #endif /* L_si_to_sf || L_si_to_df */
1367*e4b17023SJohn Marino
1368*e4b17023SJohn Marino #if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf)
1369*e4b17023SJohn Marino FLO_type
1370*e4b17023SJohn Marino usi_to_float (USItype arg_a)
1371*e4b17023SJohn Marino {
1372*e4b17023SJohn Marino fp_number_type in;
1373*e4b17023SJohn Marino
1374*e4b17023SJohn Marino in.sign = 0;
1375*e4b17023SJohn Marino if (!arg_a)
1376*e4b17023SJohn Marino {
1377*e4b17023SJohn Marino in.class = CLASS_ZERO;
1378*e4b17023SJohn Marino }
1379*e4b17023SJohn Marino else
1380*e4b17023SJohn Marino {
1381*e4b17023SJohn Marino int shift;
1382*e4b17023SJohn Marino in.class = CLASS_NUMBER;
1383*e4b17023SJohn Marino in.normal_exp = FRACBITS + NGARDS;
1384*e4b17023SJohn Marino in.fraction.ll = arg_a;
1385*e4b17023SJohn Marino
1386*e4b17023SJohn Marino shift = clzusi (arg_a) - (BITS_PER_SI - 1 - FRACBITS - NGARDS);
1387*e4b17023SJohn Marino if (shift < 0)
1388*e4b17023SJohn Marino {
1389*e4b17023SJohn Marino fractype guard = in.fraction.ll & (((fractype)1 << -shift) - 1);
1390*e4b17023SJohn Marino in.fraction.ll >>= -shift;
1391*e4b17023SJohn Marino in.fraction.ll |= (guard != 0);
1392*e4b17023SJohn Marino in.normal_exp -= shift;
1393*e4b17023SJohn Marino }
1394*e4b17023SJohn Marino else if (shift > 0)
1395*e4b17023SJohn Marino {
1396*e4b17023SJohn Marino in.fraction.ll <<= shift;
1397*e4b17023SJohn Marino in.normal_exp -= shift;
1398*e4b17023SJohn Marino }
1399*e4b17023SJohn Marino }
1400*e4b17023SJohn Marino return pack_d (&in);
1401*e4b17023SJohn Marino }
1402*e4b17023SJohn Marino #endif
1403*e4b17023SJohn Marino
1404*e4b17023SJohn Marino #if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si)
1405*e4b17023SJohn Marino SItype
1406*e4b17023SJohn Marino float_to_si (FLO_type arg_a)
1407*e4b17023SJohn Marino {
1408*e4b17023SJohn Marino fp_number_type a;
1409*e4b17023SJohn Marino SItype tmp;
1410*e4b17023SJohn Marino FLO_union_type au;
1411*e4b17023SJohn Marino
1412*e4b17023SJohn Marino au.value = arg_a;
1413*e4b17023SJohn Marino unpack_d (&au, &a);
1414*e4b17023SJohn Marino
1415*e4b17023SJohn Marino if (iszero (&a))
1416*e4b17023SJohn Marino return 0;
1417*e4b17023SJohn Marino if (isnan (&a))
1418*e4b17023SJohn Marino return 0;
1419*e4b17023SJohn Marino /* get reasonable MAX_SI_INT... */
1420*e4b17023SJohn Marino if (isinf (&a))
1421*e4b17023SJohn Marino return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
1422*e4b17023SJohn Marino /* it is a number, but a small one */
1423*e4b17023SJohn Marino if (a.normal_exp < 0)
1424*e4b17023SJohn Marino return 0;
1425*e4b17023SJohn Marino if (a.normal_exp > BITS_PER_SI - 2)
1426*e4b17023SJohn Marino return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
1427*e4b17023SJohn Marino tmp = a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
1428*e4b17023SJohn Marino return a.sign ? (-tmp) : (tmp);
1429*e4b17023SJohn Marino }
1430*e4b17023SJohn Marino #endif /* L_sf_to_si || L_df_to_si */
1431*e4b17023SJohn Marino
1432*e4b17023SJohn Marino #if defined(L_tf_to_usi)
1433*e4b17023SJohn Marino USItype
1434*e4b17023SJohn Marino float_to_usi (FLO_type arg_a)
1435*e4b17023SJohn Marino {
1436*e4b17023SJohn Marino fp_number_type a;
1437*e4b17023SJohn Marino FLO_union_type au;
1438*e4b17023SJohn Marino
1439*e4b17023SJohn Marino au.value = arg_a;
1440*e4b17023SJohn Marino unpack_d (&au, &a);
1441*e4b17023SJohn Marino
1442*e4b17023SJohn Marino if (iszero (&a))
1443*e4b17023SJohn Marino return 0;
1444*e4b17023SJohn Marino if (isnan (&a))
1445*e4b17023SJohn Marino return 0;
1446*e4b17023SJohn Marino /* it is a negative number */
1447*e4b17023SJohn Marino if (a.sign)
1448*e4b17023SJohn Marino return 0;
1449*e4b17023SJohn Marino /* get reasonable MAX_USI_INT... */
1450*e4b17023SJohn Marino if (isinf (&a))
1451*e4b17023SJohn Marino return MAX_USI_INT;
1452*e4b17023SJohn Marino /* it is a number, but a small one */
1453*e4b17023SJohn Marino if (a.normal_exp < 0)
1454*e4b17023SJohn Marino return 0;
1455*e4b17023SJohn Marino if (a.normal_exp > BITS_PER_SI - 1)
1456*e4b17023SJohn Marino return MAX_USI_INT;
1457*e4b17023SJohn Marino else if (a.normal_exp > (FRACBITS + NGARDS))
1458*e4b17023SJohn Marino return a.fraction.ll << (a.normal_exp - (FRACBITS + NGARDS));
1459*e4b17023SJohn Marino else
1460*e4b17023SJohn Marino return a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
1461*e4b17023SJohn Marino }
1462*e4b17023SJohn Marino #endif /* L_tf_to_usi */
1463*e4b17023SJohn Marino
1464*e4b17023SJohn Marino #if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf)
1465*e4b17023SJohn Marino FLO_type
1466*e4b17023SJohn Marino negate (FLO_type arg_a)
1467*e4b17023SJohn Marino {
1468*e4b17023SJohn Marino fp_number_type a;
1469*e4b17023SJohn Marino FLO_union_type au;
1470*e4b17023SJohn Marino
1471*e4b17023SJohn Marino au.value = arg_a;
1472*e4b17023SJohn Marino unpack_d (&au, &a);
1473*e4b17023SJohn Marino
1474*e4b17023SJohn Marino flip_sign (&a);
1475*e4b17023SJohn Marino return pack_d (&a);
1476*e4b17023SJohn Marino }
1477*e4b17023SJohn Marino #endif /* L_negate_sf || L_negate_df */
1478*e4b17023SJohn Marino
1479*e4b17023SJohn Marino #ifdef FLOAT
1480*e4b17023SJohn Marino
1481*e4b17023SJohn Marino #if defined(L_make_sf)
1482*e4b17023SJohn Marino SFtype
1483*e4b17023SJohn Marino __make_fp(fp_class_type class,
1484*e4b17023SJohn Marino unsigned int sign,
1485*e4b17023SJohn Marino int exp,
1486*e4b17023SJohn Marino USItype frac)
1487*e4b17023SJohn Marino {
1488*e4b17023SJohn Marino fp_number_type in;
1489*e4b17023SJohn Marino
1490*e4b17023SJohn Marino in.class = class;
1491*e4b17023SJohn Marino in.sign = sign;
1492*e4b17023SJohn Marino in.normal_exp = exp;
1493*e4b17023SJohn Marino in.fraction.ll = frac;
1494*e4b17023SJohn Marino return pack_d (&in);
1495*e4b17023SJohn Marino }
1496*e4b17023SJohn Marino #endif /* L_make_sf */
1497*e4b17023SJohn Marino
1498*e4b17023SJohn Marino #ifndef FLOAT_ONLY
1499*e4b17023SJohn Marino
1500*e4b17023SJohn Marino /* This enables one to build an fp library that supports float but not double.
1501*e4b17023SJohn Marino Otherwise, we would get an undefined reference to __make_dp.
1502*e4b17023SJohn Marino This is needed for some 8-bit ports that can't handle well values that
1503*e4b17023SJohn Marino are 8-bytes in size, so we just don't support double for them at all. */
1504*e4b17023SJohn Marino
1505*e4b17023SJohn Marino #if defined(L_sf_to_df)
1506*e4b17023SJohn Marino DFtype
1507*e4b17023SJohn Marino sf_to_df (SFtype arg_a)
1508*e4b17023SJohn Marino {
1509*e4b17023SJohn Marino fp_number_type in;
1510*e4b17023SJohn Marino FLO_union_type au;
1511*e4b17023SJohn Marino
1512*e4b17023SJohn Marino au.value = arg_a;
1513*e4b17023SJohn Marino unpack_d (&au, &in);
1514*e4b17023SJohn Marino
1515*e4b17023SJohn Marino return __make_dp (in.class, in.sign, in.normal_exp,
1516*e4b17023SJohn Marino ((UDItype) in.fraction.ll) << F_D_BITOFF);
1517*e4b17023SJohn Marino }
1518*e4b17023SJohn Marino #endif /* L_sf_to_df */
1519*e4b17023SJohn Marino
1520*e4b17023SJohn Marino #if defined(L_sf_to_tf) && defined(TMODES)
1521*e4b17023SJohn Marino TFtype
1522*e4b17023SJohn Marino sf_to_tf (SFtype arg_a)
1523*e4b17023SJohn Marino {
1524*e4b17023SJohn Marino fp_number_type in;
1525*e4b17023SJohn Marino FLO_union_type au;
1526*e4b17023SJohn Marino
1527*e4b17023SJohn Marino au.value = arg_a;
1528*e4b17023SJohn Marino unpack_d (&au, &in);
1529*e4b17023SJohn Marino
1530*e4b17023SJohn Marino return __make_tp (in.class, in.sign, in.normal_exp,
1531*e4b17023SJohn Marino ((UTItype) in.fraction.ll) << F_T_BITOFF);
1532*e4b17023SJohn Marino }
1533*e4b17023SJohn Marino #endif /* L_sf_to_df */
1534*e4b17023SJohn Marino
1535*e4b17023SJohn Marino #endif /* ! FLOAT_ONLY */
1536*e4b17023SJohn Marino #endif /* FLOAT */
1537*e4b17023SJohn Marino
1538*e4b17023SJohn Marino #ifndef FLOAT
1539*e4b17023SJohn Marino
1540*e4b17023SJohn Marino extern SFtype __make_fp (fp_class_type, unsigned int, int, USItype);
1541*e4b17023SJohn Marino
1542*e4b17023SJohn Marino #if defined(L_make_df)
1543*e4b17023SJohn Marino DFtype
1544*e4b17023SJohn Marino __make_dp (fp_class_type class, unsigned int sign, int exp, UDItype frac)
1545*e4b17023SJohn Marino {
1546*e4b17023SJohn Marino fp_number_type in;
1547*e4b17023SJohn Marino
1548*e4b17023SJohn Marino in.class = class;
1549*e4b17023SJohn Marino in.sign = sign;
1550*e4b17023SJohn Marino in.normal_exp = exp;
1551*e4b17023SJohn Marino in.fraction.ll = frac;
1552*e4b17023SJohn Marino return pack_d (&in);
1553*e4b17023SJohn Marino }
1554*e4b17023SJohn Marino #endif /* L_make_df */
1555*e4b17023SJohn Marino
1556*e4b17023SJohn Marino #if defined(L_df_to_sf)
1557*e4b17023SJohn Marino SFtype
1558*e4b17023SJohn Marino df_to_sf (DFtype arg_a)
1559*e4b17023SJohn Marino {
1560*e4b17023SJohn Marino fp_number_type in;
1561*e4b17023SJohn Marino USItype sffrac;
1562*e4b17023SJohn Marino FLO_union_type au;
1563*e4b17023SJohn Marino
1564*e4b17023SJohn Marino au.value = arg_a;
1565*e4b17023SJohn Marino unpack_d (&au, &in);
1566*e4b17023SJohn Marino
1567*e4b17023SJohn Marino sffrac = in.fraction.ll >> F_D_BITOFF;
1568*e4b17023SJohn Marino
1569*e4b17023SJohn Marino /* We set the lowest guard bit in SFFRAC if we discarded any non
1570*e4b17023SJohn Marino zero bits. */
1571*e4b17023SJohn Marino if ((in.fraction.ll & (((USItype) 1 << F_D_BITOFF) - 1)) != 0)
1572*e4b17023SJohn Marino sffrac |= 1;
1573*e4b17023SJohn Marino
1574*e4b17023SJohn Marino return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
1575*e4b17023SJohn Marino }
1576*e4b17023SJohn Marino #endif /* L_df_to_sf */
1577*e4b17023SJohn Marino
1578*e4b17023SJohn Marino #if defined(L_df_to_tf) && defined(TMODES) \
1579*e4b17023SJohn Marino && !defined(FLOAT) && !defined(TFLOAT)
1580*e4b17023SJohn Marino TFtype
1581*e4b17023SJohn Marino df_to_tf (DFtype arg_a)
1582*e4b17023SJohn Marino {
1583*e4b17023SJohn Marino fp_number_type in;
1584*e4b17023SJohn Marino FLO_union_type au;
1585*e4b17023SJohn Marino
1586*e4b17023SJohn Marino au.value = arg_a;
1587*e4b17023SJohn Marino unpack_d (&au, &in);
1588*e4b17023SJohn Marino
1589*e4b17023SJohn Marino return __make_tp (in.class, in.sign, in.normal_exp,
1590*e4b17023SJohn Marino ((UTItype) in.fraction.ll) << D_T_BITOFF);
1591*e4b17023SJohn Marino }
1592*e4b17023SJohn Marino #endif /* L_sf_to_df */
1593*e4b17023SJohn Marino
1594*e4b17023SJohn Marino #ifdef TFLOAT
1595*e4b17023SJohn Marino #if defined(L_make_tf)
1596*e4b17023SJohn Marino TFtype
1597*e4b17023SJohn Marino __make_tp(fp_class_type class,
1598*e4b17023SJohn Marino unsigned int sign,
1599*e4b17023SJohn Marino int exp,
1600*e4b17023SJohn Marino UTItype frac)
1601*e4b17023SJohn Marino {
1602*e4b17023SJohn Marino fp_number_type in;
1603*e4b17023SJohn Marino
1604*e4b17023SJohn Marino in.class = class;
1605*e4b17023SJohn Marino in.sign = sign;
1606*e4b17023SJohn Marino in.normal_exp = exp;
1607*e4b17023SJohn Marino in.fraction.ll = frac;
1608*e4b17023SJohn Marino return pack_d (&in);
1609*e4b17023SJohn Marino }
1610*e4b17023SJohn Marino #endif /* L_make_tf */
1611*e4b17023SJohn Marino
1612*e4b17023SJohn Marino #if defined(L_tf_to_df)
1613*e4b17023SJohn Marino DFtype
1614*e4b17023SJohn Marino tf_to_df (TFtype arg_a)
1615*e4b17023SJohn Marino {
1616*e4b17023SJohn Marino fp_number_type in;
1617*e4b17023SJohn Marino UDItype sffrac;
1618*e4b17023SJohn Marino FLO_union_type au;
1619*e4b17023SJohn Marino
1620*e4b17023SJohn Marino au.value = arg_a;
1621*e4b17023SJohn Marino unpack_d (&au, &in);
1622*e4b17023SJohn Marino
1623*e4b17023SJohn Marino sffrac = in.fraction.ll >> D_T_BITOFF;
1624*e4b17023SJohn Marino
1625*e4b17023SJohn Marino /* We set the lowest guard bit in SFFRAC if we discarded any non
1626*e4b17023SJohn Marino zero bits. */
1627*e4b17023SJohn Marino if ((in.fraction.ll & (((UTItype) 1 << D_T_BITOFF) - 1)) != 0)
1628*e4b17023SJohn Marino sffrac |= 1;
1629*e4b17023SJohn Marino
1630*e4b17023SJohn Marino return __make_dp (in.class, in.sign, in.normal_exp, sffrac);
1631*e4b17023SJohn Marino }
1632*e4b17023SJohn Marino #endif /* L_tf_to_df */
1633*e4b17023SJohn Marino
1634*e4b17023SJohn Marino #if defined(L_tf_to_sf)
1635*e4b17023SJohn Marino SFtype
1636*e4b17023SJohn Marino tf_to_sf (TFtype arg_a)
1637*e4b17023SJohn Marino {
1638*e4b17023SJohn Marino fp_number_type in;
1639*e4b17023SJohn Marino USItype sffrac;
1640*e4b17023SJohn Marino FLO_union_type au;
1641*e4b17023SJohn Marino
1642*e4b17023SJohn Marino au.value = arg_a;
1643*e4b17023SJohn Marino unpack_d (&au, &in);
1644*e4b17023SJohn Marino
1645*e4b17023SJohn Marino sffrac = in.fraction.ll >> F_T_BITOFF;
1646*e4b17023SJohn Marino
1647*e4b17023SJohn Marino /* We set the lowest guard bit in SFFRAC if we discarded any non
1648*e4b17023SJohn Marino zero bits. */
1649*e4b17023SJohn Marino if ((in.fraction.ll & (((UTItype) 1 << F_T_BITOFF) - 1)) != 0)
1650*e4b17023SJohn Marino sffrac |= 1;
1651*e4b17023SJohn Marino
1652*e4b17023SJohn Marino return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
1653*e4b17023SJohn Marino }
1654*e4b17023SJohn Marino #endif /* L_tf_to_sf */
1655*e4b17023SJohn Marino #endif /* TFLOAT */
1656*e4b17023SJohn Marino
1657*e4b17023SJohn Marino #endif /* ! FLOAT */
1658*e4b17023SJohn Marino #endif /* !EXTENDED_FLOAT_STUBS */
1659