xref: /dflybsd-src/contrib/gcc-4.7/libgcc/fp-bit.c (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
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