xref: /netbsd-src/external/gpl3/gcc/dist/libgcc/fp-bit.c (revision b1e838363e3c6fc78a55519254d99869742dd33c)
148fb7bfaSmrg /* This is a software floating point library which can be used
248fb7bfaSmrg    for targets without hardware floating point.
3*b1e83836Smrg    Copyright (C) 1994-2022 Free Software Foundation, Inc.
448fb7bfaSmrg 
548fb7bfaSmrg This file is part of GCC.
648fb7bfaSmrg 
748fb7bfaSmrg GCC is free software; you can redistribute it and/or modify it under
848fb7bfaSmrg the terms of the GNU General Public License as published by the Free
948fb7bfaSmrg Software Foundation; either version 3, or (at your option) any later
1048fb7bfaSmrg version.
1148fb7bfaSmrg 
1248fb7bfaSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
1348fb7bfaSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
1448fb7bfaSmrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1548fb7bfaSmrg for more details.
1648fb7bfaSmrg 
1748fb7bfaSmrg Under Section 7 of GPL version 3, you are granted additional
1848fb7bfaSmrg permissions described in the GCC Runtime Library Exception, version
1948fb7bfaSmrg 3.1, as published by the Free Software Foundation.
2048fb7bfaSmrg 
2148fb7bfaSmrg You should have received a copy of the GNU General Public License and
2248fb7bfaSmrg a copy of the GCC Runtime Library Exception along with this program;
2348fb7bfaSmrg see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2448fb7bfaSmrg <http://www.gnu.org/licenses/>.  */
2548fb7bfaSmrg 
2648fb7bfaSmrg /* This implements IEEE 754 format arithmetic, but does not provide a
2748fb7bfaSmrg    mechanism for setting the rounding mode, or for generating or handling
2848fb7bfaSmrg    exceptions.
2948fb7bfaSmrg 
3048fb7bfaSmrg    The original code by Steve Chamberlain, hacked by Mark Eichin and Jim
3148fb7bfaSmrg    Wilson, all of Cygnus Support.  */
3248fb7bfaSmrg 
3348fb7bfaSmrg /* The intended way to use this file is to make two copies, add `#define FLOAT'
3448fb7bfaSmrg    to one copy, then compile both copies and add them to libgcc.a.  */
3548fb7bfaSmrg 
3648fb7bfaSmrg #include "tconfig.h"
3748fb7bfaSmrg #include "coretypes.h"
3848fb7bfaSmrg #include "tm.h"
3948fb7bfaSmrg #include "libgcc_tm.h"
4048fb7bfaSmrg #include "fp-bit.h"
4148fb7bfaSmrg 
4248fb7bfaSmrg /* The following macros can be defined to change the behavior of this file:
4348fb7bfaSmrg    FLOAT: Implement a `float', aka SFmode, fp library.  If this is not
4448fb7bfaSmrg      defined, then this file implements a `double', aka DFmode, fp library.
4548fb7bfaSmrg    FLOAT_ONLY: Used with FLOAT, to implement a `float' only library, i.e.
4648fb7bfaSmrg      don't include float->double conversion which requires the double library.
4748fb7bfaSmrg      This is useful only for machines which can't support doubles, e.g. some
4848fb7bfaSmrg      8-bit processors.
4948fb7bfaSmrg    CMPtype: Specify the type that floating point compares should return.
5048fb7bfaSmrg      This defaults to SItype, aka int.
5148fb7bfaSmrg    _DEBUG_BITFLOAT: This makes debugging the code a little easier, by adding
5248fb7bfaSmrg      two integers to the FLO_union_type.
5348fb7bfaSmrg    NO_DENORMALS: Disable handling of denormals.
5448fb7bfaSmrg    NO_NANS: Disable nan and infinity handling
5548fb7bfaSmrg    SMALL_MACHINE: Useful when operations on QIs and HIs are faster
5648fb7bfaSmrg      than on an SI */
5748fb7bfaSmrg 
5848fb7bfaSmrg /* We don't currently support extended floats (long doubles) on machines
5948fb7bfaSmrg    without hardware to deal with them.
6048fb7bfaSmrg 
6148fb7bfaSmrg    These stubs are just to keep the linker from complaining about unresolved
6248fb7bfaSmrg    references which can be pulled in from libio & libstdc++, even if the
6348fb7bfaSmrg    user isn't using long doubles.  However, they may generate an unresolved
6448fb7bfaSmrg    external to abort if abort is not used by the function, and the stubs
6548fb7bfaSmrg    are referenced from within libc, since libgcc goes before and after the
6648fb7bfaSmrg    system library.  */
6748fb7bfaSmrg 
6848fb7bfaSmrg #ifdef DECLARE_LIBRARY_RENAMES
6948fb7bfaSmrg   DECLARE_LIBRARY_RENAMES
7048fb7bfaSmrg #endif
7148fb7bfaSmrg 
7248fb7bfaSmrg #ifdef EXTENDED_FLOAT_STUBS
7348fb7bfaSmrg extern void abort (void);
__extendsfxf2(void)7448fb7bfaSmrg void __extendsfxf2 (void) { abort(); }
__extenddfxf2(void)7548fb7bfaSmrg void __extenddfxf2 (void) { abort(); }
__truncxfdf2(void)7648fb7bfaSmrg void __truncxfdf2 (void) { abort(); }
__truncxfsf2(void)7748fb7bfaSmrg void __truncxfsf2 (void) { abort(); }
__fixxfsi(void)7848fb7bfaSmrg void __fixxfsi (void) { abort(); }
__floatsixf(void)7948fb7bfaSmrg void __floatsixf (void) { abort(); }
__addxf3(void)8048fb7bfaSmrg void __addxf3 (void) { abort(); }
__subxf3(void)8148fb7bfaSmrg void __subxf3 (void) { abort(); }
__mulxf3(void)8248fb7bfaSmrg void __mulxf3 (void) { abort(); }
__divxf3(void)8348fb7bfaSmrg void __divxf3 (void) { abort(); }
__negxf2(void)8448fb7bfaSmrg void __negxf2 (void) { abort(); }
__eqxf2(void)8548fb7bfaSmrg void __eqxf2 (void) { abort(); }
__nexf2(void)8648fb7bfaSmrg void __nexf2 (void) { abort(); }
__gtxf2(void)8748fb7bfaSmrg void __gtxf2 (void) { abort(); }
__gexf2(void)8848fb7bfaSmrg void __gexf2 (void) { abort(); }
__lexf2(void)8948fb7bfaSmrg void __lexf2 (void) { abort(); }
__ltxf2(void)9048fb7bfaSmrg void __ltxf2 (void) { abort(); }
9148fb7bfaSmrg 
__extendsftf2(void)9248fb7bfaSmrg void __extendsftf2 (void) { abort(); }
__extenddftf2(void)9348fb7bfaSmrg void __extenddftf2 (void) { abort(); }
__trunctfdf2(void)9448fb7bfaSmrg void __trunctfdf2 (void) { abort(); }
__trunctfsf2(void)9548fb7bfaSmrg void __trunctfsf2 (void) { abort(); }
__fixtfsi(void)9648fb7bfaSmrg void __fixtfsi (void) { abort(); }
__floatsitf(void)9748fb7bfaSmrg void __floatsitf (void) { abort(); }
__addtf3(void)9848fb7bfaSmrg void __addtf3 (void) { abort(); }
__subtf3(void)9948fb7bfaSmrg void __subtf3 (void) { abort(); }
__multf3(void)10048fb7bfaSmrg void __multf3 (void) { abort(); }
__divtf3(void)10148fb7bfaSmrg void __divtf3 (void) { abort(); }
__negtf2(void)10248fb7bfaSmrg void __negtf2 (void) { abort(); }
__eqtf2(void)10348fb7bfaSmrg void __eqtf2 (void) { abort(); }
__netf2(void)10448fb7bfaSmrg void __netf2 (void) { abort(); }
__gttf2(void)10548fb7bfaSmrg void __gttf2 (void) { abort(); }
__getf2(void)10648fb7bfaSmrg void __getf2 (void) { abort(); }
__letf2(void)10748fb7bfaSmrg void __letf2 (void) { abort(); }
__lttf2(void)10848fb7bfaSmrg void __lttf2 (void) { abort(); }
10948fb7bfaSmrg #else	/* !EXTENDED_FLOAT_STUBS, rest of file */
11048fb7bfaSmrg 
11148fb7bfaSmrg /* IEEE "special" number predicates */
11248fb7bfaSmrg 
11348fb7bfaSmrg #ifdef NO_NANS
11448fb7bfaSmrg 
11548fb7bfaSmrg #define nan() 0
11648fb7bfaSmrg #define isnan(x) 0
11748fb7bfaSmrg #define isinf(x) 0
11848fb7bfaSmrg #else
11948fb7bfaSmrg 
12048fb7bfaSmrg #if   defined L_thenan_sf
12148fb7bfaSmrg const fp_number_type __thenan_sf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
12248fb7bfaSmrg #elif defined L_thenan_df
12348fb7bfaSmrg const fp_number_type __thenan_df = { CLASS_SNAN, 0, 0, {(fractype) 0} };
12448fb7bfaSmrg #elif defined L_thenan_tf
12548fb7bfaSmrg const fp_number_type __thenan_tf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
12648fb7bfaSmrg #elif defined TFLOAT
12748fb7bfaSmrg extern const fp_number_type __thenan_tf;
12848fb7bfaSmrg #elif defined FLOAT
12948fb7bfaSmrg extern const fp_number_type __thenan_sf;
13048fb7bfaSmrg #else
13148fb7bfaSmrg extern const fp_number_type __thenan_df;
13248fb7bfaSmrg #endif
13348fb7bfaSmrg 
13448fb7bfaSmrg INLINE
13548fb7bfaSmrg static const fp_number_type *
13648fb7bfaSmrg makenan (void)
13748fb7bfaSmrg {
13848fb7bfaSmrg #ifdef TFLOAT
13948fb7bfaSmrg   return & __thenan_tf;
14048fb7bfaSmrg #elif defined FLOAT
14148fb7bfaSmrg   return & __thenan_sf;
14248fb7bfaSmrg #else
14348fb7bfaSmrg   return & __thenan_df;
14448fb7bfaSmrg #endif
14548fb7bfaSmrg }
14648fb7bfaSmrg 
14748fb7bfaSmrg INLINE
14848fb7bfaSmrg static int
14948fb7bfaSmrg isnan (const fp_number_type *x)
15048fb7bfaSmrg {
15148fb7bfaSmrg   return __builtin_expect (x->class == CLASS_SNAN || x->class == CLASS_QNAN,
15248fb7bfaSmrg 			   0);
15348fb7bfaSmrg }
15448fb7bfaSmrg 
15548fb7bfaSmrg INLINE
15648fb7bfaSmrg static int
15748fb7bfaSmrg isinf (const fp_number_type *  x)
15848fb7bfaSmrg {
15948fb7bfaSmrg   return __builtin_expect (x->class == CLASS_INFINITY, 0);
16048fb7bfaSmrg }
16148fb7bfaSmrg 
16248fb7bfaSmrg #endif /* NO_NANS */
16348fb7bfaSmrg 
16448fb7bfaSmrg INLINE
16548fb7bfaSmrg static int
16648fb7bfaSmrg iszero (const fp_number_type *  x)
16748fb7bfaSmrg {
16848fb7bfaSmrg   return x->class == CLASS_ZERO;
16948fb7bfaSmrg }
17048fb7bfaSmrg 
17148fb7bfaSmrg INLINE
17248fb7bfaSmrg static void
17348fb7bfaSmrg flip_sign ( fp_number_type *  x)
17448fb7bfaSmrg {
17548fb7bfaSmrg   x->sign = !x->sign;
17648fb7bfaSmrg }
17748fb7bfaSmrg 
17848fb7bfaSmrg /* Count leading zeroes in N.  */
17948fb7bfaSmrg INLINE
18048fb7bfaSmrg static int
18148fb7bfaSmrg clzusi (USItype n)
18248fb7bfaSmrg {
18348fb7bfaSmrg   extern int __clzsi2 (USItype);
18448fb7bfaSmrg   if (sizeof (USItype) == sizeof (unsigned int))
18548fb7bfaSmrg     return __builtin_clz (n);
18648fb7bfaSmrg   else if (sizeof (USItype) == sizeof (unsigned long))
18748fb7bfaSmrg     return __builtin_clzl (n);
18848fb7bfaSmrg   else if (sizeof (USItype) == sizeof (unsigned long long))
18948fb7bfaSmrg     return __builtin_clzll (n);
19048fb7bfaSmrg   else
19148fb7bfaSmrg     return __clzsi2 (n);
19248fb7bfaSmrg }
19348fb7bfaSmrg 
19448fb7bfaSmrg extern FLO_type pack_d (const fp_number_type * );
19548fb7bfaSmrg 
19648fb7bfaSmrg #if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf)
19748fb7bfaSmrg FLO_type
19848fb7bfaSmrg pack_d (const fp_number_type *src)
19948fb7bfaSmrg {
20048fb7bfaSmrg   FLO_union_type dst;
20148fb7bfaSmrg   fractype fraction = src->fraction.ll;	/* wasn't unsigned before? */
20248fb7bfaSmrg   int sign = src->sign;
20348fb7bfaSmrg   int exp = 0;
20448fb7bfaSmrg 
2054d5abbe8Smrg   if (isnan (src))
20648fb7bfaSmrg     {
20748fb7bfaSmrg       exp = EXPMAX;
2084d5abbe8Smrg       /* Restore the NaN's payload.  */
2094d5abbe8Smrg       fraction >>= NGARDS;
2104d5abbe8Smrg       fraction &= QUIET_NAN - 1;
21148fb7bfaSmrg       if (src->class == CLASS_QNAN || 1)
21248fb7bfaSmrg 	{
21348fb7bfaSmrg #ifdef QUIET_NAN_NEGATED
2144d5abbe8Smrg 	  /* The quiet/signaling bit remains unset.  */
2154d5abbe8Smrg 	  /* Make sure the fraction has a non-zero value.  */
2164d5abbe8Smrg 	  if (fraction == 0)
21748fb7bfaSmrg 	    fraction |= QUIET_NAN - 1;
21848fb7bfaSmrg #else
2194d5abbe8Smrg 	  /* Set the quiet/signaling bit.  */
22048fb7bfaSmrg 	  fraction |= QUIET_NAN;
22148fb7bfaSmrg #endif
22248fb7bfaSmrg 	}
22348fb7bfaSmrg     }
22448fb7bfaSmrg   else if (isinf (src))
22548fb7bfaSmrg     {
22648fb7bfaSmrg       exp = EXPMAX;
22748fb7bfaSmrg       fraction = 0;
22848fb7bfaSmrg     }
22948fb7bfaSmrg   else if (iszero (src))
23048fb7bfaSmrg     {
23148fb7bfaSmrg       exp = 0;
23248fb7bfaSmrg       fraction = 0;
23348fb7bfaSmrg     }
23448fb7bfaSmrg   else if (fraction == 0)
23548fb7bfaSmrg     {
23648fb7bfaSmrg       exp = 0;
23748fb7bfaSmrg     }
23848fb7bfaSmrg   else
23948fb7bfaSmrg     {
24048fb7bfaSmrg       if (__builtin_expect (src->normal_exp < NORMAL_EXPMIN, 0))
24148fb7bfaSmrg 	{
24248fb7bfaSmrg #ifdef NO_DENORMALS
24348fb7bfaSmrg 	  /* Go straight to a zero representation if denormals are not
24448fb7bfaSmrg  	     supported.  The denormal handling would be harmless but
24548fb7bfaSmrg  	     isn't unnecessary.  */
24648fb7bfaSmrg 	  exp = 0;
24748fb7bfaSmrg 	  fraction = 0;
24848fb7bfaSmrg #else /* NO_DENORMALS */
24948fb7bfaSmrg 	  /* This number's exponent is too low to fit into the bits
25048fb7bfaSmrg 	     available in the number, so we'll store 0 in the exponent and
25148fb7bfaSmrg 	     shift the fraction to the right to make up for it.  */
25248fb7bfaSmrg 
25348fb7bfaSmrg 	  int shift = NORMAL_EXPMIN - src->normal_exp;
25448fb7bfaSmrg 
25548fb7bfaSmrg 	  exp = 0;
25648fb7bfaSmrg 
25748fb7bfaSmrg 	  if (shift > FRAC_NBITS - NGARDS)
25848fb7bfaSmrg 	    {
25948fb7bfaSmrg 	      /* No point shifting, since it's more that 64 out.  */
26048fb7bfaSmrg 	      fraction = 0;
26148fb7bfaSmrg 	    }
26248fb7bfaSmrg 	  else
26348fb7bfaSmrg 	    {
26448fb7bfaSmrg 	      int lowbit = (fraction & (((fractype)1 << shift) - 1)) ? 1 : 0;
26548fb7bfaSmrg 	      fraction = (fraction >> shift) | lowbit;
26648fb7bfaSmrg 	    }
26748fb7bfaSmrg 	  if ((fraction & GARDMASK) == GARDMSB)
26848fb7bfaSmrg 	    {
26948fb7bfaSmrg 	      if ((fraction & (1 << NGARDS)))
27048fb7bfaSmrg 		fraction += GARDROUND + 1;
27148fb7bfaSmrg 	    }
27248fb7bfaSmrg 	  else
27348fb7bfaSmrg 	    {
27448fb7bfaSmrg 	      /* Add to the guards to round up.  */
27548fb7bfaSmrg 	      fraction += GARDROUND;
27648fb7bfaSmrg 	    }
27748fb7bfaSmrg 	  /* Perhaps the rounding means we now need to change the
27848fb7bfaSmrg              exponent, because the fraction is no longer denormal.  */
27948fb7bfaSmrg 	  if (fraction >= IMPLICIT_1)
28048fb7bfaSmrg 	    {
28148fb7bfaSmrg 	      exp += 1;
28248fb7bfaSmrg 	    }
28348fb7bfaSmrg 	  fraction >>= NGARDS;
28448fb7bfaSmrg #endif /* NO_DENORMALS */
28548fb7bfaSmrg 	}
2864d5abbe8Smrg       else if (__builtin_expect (src->normal_exp > EXPBIAS, 0))
28748fb7bfaSmrg 	{
28848fb7bfaSmrg 	  exp = EXPMAX;
28948fb7bfaSmrg 	  fraction = 0;
29048fb7bfaSmrg 	}
29148fb7bfaSmrg       else
29248fb7bfaSmrg 	{
29348fb7bfaSmrg 	  exp = src->normal_exp + EXPBIAS;
29448fb7bfaSmrg 	  /* IF the gard bits are the all zero, but the first, then we're
29548fb7bfaSmrg 	     half way between two numbers, choose the one which makes the
29648fb7bfaSmrg 	     lsb of the answer 0.  */
29748fb7bfaSmrg 	  if ((fraction & GARDMASK) == GARDMSB)
29848fb7bfaSmrg 	    {
29948fb7bfaSmrg 	      if (fraction & (1 << NGARDS))
30048fb7bfaSmrg 		fraction += GARDROUND + 1;
30148fb7bfaSmrg 	    }
30248fb7bfaSmrg 	  else
30348fb7bfaSmrg 	    {
30448fb7bfaSmrg 	      /* Add a one to the guards to round up */
30548fb7bfaSmrg 	      fraction += GARDROUND;
30648fb7bfaSmrg 	    }
30748fb7bfaSmrg 	  if (fraction >= IMPLICIT_2)
30848fb7bfaSmrg 	    {
30948fb7bfaSmrg 	      fraction >>= 1;
31048fb7bfaSmrg 	      exp += 1;
31148fb7bfaSmrg 	    }
31248fb7bfaSmrg 	  fraction >>= NGARDS;
31348fb7bfaSmrg 	}
31448fb7bfaSmrg     }
31548fb7bfaSmrg 
31648fb7bfaSmrg   /* We previously used bitfields to store the number, but this doesn't
31748fb7bfaSmrg      handle little/big endian systems conveniently, so use shifts and
31848fb7bfaSmrg      masks */
31948fb7bfaSmrg #if defined TFLOAT && defined HALFFRACBITS
32048fb7bfaSmrg  {
32148fb7bfaSmrg    halffractype high, low, unity;
32248fb7bfaSmrg    int lowsign, lowexp;
32348fb7bfaSmrg 
32448fb7bfaSmrg    unity = (halffractype) 1 << HALFFRACBITS;
32548fb7bfaSmrg 
32648fb7bfaSmrg    /* Set HIGH to the high double's significand, masking out the implicit 1.
32748fb7bfaSmrg       Set LOW to the low double's full significand.  */
32848fb7bfaSmrg    high = (fraction >> (FRACBITS - HALFFRACBITS)) & (unity - 1);
32948fb7bfaSmrg    low = fraction & (unity * 2 - 1);
33048fb7bfaSmrg 
33148fb7bfaSmrg    /* Get the initial sign and exponent of the low double.  */
33248fb7bfaSmrg    lowexp = exp - HALFFRACBITS - 1;
33348fb7bfaSmrg    lowsign = sign;
33448fb7bfaSmrg 
33548fb7bfaSmrg    /* HIGH should be rounded like a normal double, making |LOW| <=
33648fb7bfaSmrg       0.5 ULP of HIGH.  Assume round-to-nearest.  */
33748fb7bfaSmrg    if (exp < EXPMAX)
33848fb7bfaSmrg      if (low > unity || (low == unity && (high & 1) == 1))
33948fb7bfaSmrg        {
34048fb7bfaSmrg 	 /* Round HIGH up and adjust LOW to match.  */
34148fb7bfaSmrg 	 high++;
34248fb7bfaSmrg 	 if (high == unity)
34348fb7bfaSmrg 	   {
34448fb7bfaSmrg 	     /* May make it infinite, but that's OK.  */
34548fb7bfaSmrg 	     high = 0;
34648fb7bfaSmrg 	     exp++;
34748fb7bfaSmrg 	   }
34848fb7bfaSmrg 	 low = unity * 2 - low;
34948fb7bfaSmrg 	 lowsign ^= 1;
35048fb7bfaSmrg        }
35148fb7bfaSmrg 
35248fb7bfaSmrg    high |= (halffractype) exp << HALFFRACBITS;
35348fb7bfaSmrg    high |= (halffractype) sign << (HALFFRACBITS + EXPBITS);
35448fb7bfaSmrg 
35548fb7bfaSmrg    if (exp == EXPMAX || exp == 0 || low == 0)
35648fb7bfaSmrg      low = 0;
35748fb7bfaSmrg    else
35848fb7bfaSmrg      {
35948fb7bfaSmrg        while (lowexp > 0 && low < unity)
36048fb7bfaSmrg 	 {
36148fb7bfaSmrg 	   low <<= 1;
36248fb7bfaSmrg 	   lowexp--;
36348fb7bfaSmrg 	 }
36448fb7bfaSmrg 
36548fb7bfaSmrg        if (lowexp <= 0)
36648fb7bfaSmrg 	 {
36748fb7bfaSmrg 	   halffractype roundmsb, round;
36848fb7bfaSmrg 	   int shift;
36948fb7bfaSmrg 
37048fb7bfaSmrg 	   shift = 1 - lowexp;
37148fb7bfaSmrg 	   roundmsb = (1 << (shift - 1));
37248fb7bfaSmrg 	   round = low & ((roundmsb << 1) - 1);
37348fb7bfaSmrg 
37448fb7bfaSmrg 	   low >>= shift;
37548fb7bfaSmrg 	   lowexp = 0;
37648fb7bfaSmrg 
37748fb7bfaSmrg 	   if (round > roundmsb || (round == roundmsb && (low & 1) == 1))
37848fb7bfaSmrg 	     {
37948fb7bfaSmrg 	       low++;
38048fb7bfaSmrg 	       if (low == unity)
38148fb7bfaSmrg 		 /* LOW rounds up to the smallest normal number.  */
38248fb7bfaSmrg 		 lowexp++;
38348fb7bfaSmrg 	     }
38448fb7bfaSmrg 	 }
38548fb7bfaSmrg 
38648fb7bfaSmrg        low &= unity - 1;
38748fb7bfaSmrg        low |= (halffractype) lowexp << HALFFRACBITS;
38848fb7bfaSmrg        low |= (halffractype) lowsign << (HALFFRACBITS + EXPBITS);
38948fb7bfaSmrg      }
39048fb7bfaSmrg    dst.value_raw = ((fractype) high << HALFSHIFT) | low;
39148fb7bfaSmrg  }
39248fb7bfaSmrg #else
39348fb7bfaSmrg   dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1);
39448fb7bfaSmrg   dst.value_raw |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << FRACBITS;
39548fb7bfaSmrg   dst.value_raw |= ((fractype) (sign & 1)) << (FRACBITS | EXPBITS);
39648fb7bfaSmrg #endif
39748fb7bfaSmrg 
39848fb7bfaSmrg #if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
39948fb7bfaSmrg #ifdef TFLOAT
40048fb7bfaSmrg   {
40148fb7bfaSmrg     qrtrfractype tmp1 = dst.words[0];
40248fb7bfaSmrg     qrtrfractype tmp2 = dst.words[1];
40348fb7bfaSmrg     dst.words[0] = dst.words[3];
40448fb7bfaSmrg     dst.words[1] = dst.words[2];
40548fb7bfaSmrg     dst.words[2] = tmp2;
40648fb7bfaSmrg     dst.words[3] = tmp1;
40748fb7bfaSmrg   }
40848fb7bfaSmrg #else
40948fb7bfaSmrg   {
41048fb7bfaSmrg     halffractype tmp = dst.words[0];
41148fb7bfaSmrg     dst.words[0] = dst.words[1];
41248fb7bfaSmrg     dst.words[1] = tmp;
41348fb7bfaSmrg   }
41448fb7bfaSmrg #endif
41548fb7bfaSmrg #endif
41648fb7bfaSmrg 
41748fb7bfaSmrg   return dst.value;
41848fb7bfaSmrg }
41948fb7bfaSmrg #endif
42048fb7bfaSmrg 
42148fb7bfaSmrg #if defined(L_unpack_df) || defined(L_unpack_sf) || defined(L_unpack_tf)
42248fb7bfaSmrg void
42348fb7bfaSmrg unpack_d (FLO_union_type * src, fp_number_type * dst)
42448fb7bfaSmrg {
42548fb7bfaSmrg   /* We previously used bitfields to store the number, but this doesn't
42648fb7bfaSmrg      handle little/big endian systems conveniently, so use shifts and
42748fb7bfaSmrg      masks */
42848fb7bfaSmrg   fractype fraction;
42948fb7bfaSmrg   int exp;
43048fb7bfaSmrg   int sign;
43148fb7bfaSmrg 
43248fb7bfaSmrg #if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
43348fb7bfaSmrg   FLO_union_type swapped;
43448fb7bfaSmrg 
43548fb7bfaSmrg #ifdef TFLOAT
43648fb7bfaSmrg   swapped.words[0] = src->words[3];
43748fb7bfaSmrg   swapped.words[1] = src->words[2];
43848fb7bfaSmrg   swapped.words[2] = src->words[1];
43948fb7bfaSmrg   swapped.words[3] = src->words[0];
44048fb7bfaSmrg #else
44148fb7bfaSmrg   swapped.words[0] = src->words[1];
44248fb7bfaSmrg   swapped.words[1] = src->words[0];
44348fb7bfaSmrg #endif
44448fb7bfaSmrg   src = &swapped;
44548fb7bfaSmrg #endif
44648fb7bfaSmrg 
44748fb7bfaSmrg #if defined TFLOAT && defined HALFFRACBITS
44848fb7bfaSmrg  {
44948fb7bfaSmrg    halffractype high, low;
45048fb7bfaSmrg 
45148fb7bfaSmrg    high = src->value_raw >> HALFSHIFT;
45248fb7bfaSmrg    low = src->value_raw & (((fractype)1 << HALFSHIFT) - 1);
45348fb7bfaSmrg 
45448fb7bfaSmrg    fraction = high & ((((fractype)1) << HALFFRACBITS) - 1);
45548fb7bfaSmrg    fraction <<= FRACBITS - HALFFRACBITS;
45648fb7bfaSmrg    exp = ((int)(high >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
45748fb7bfaSmrg    sign = ((int)(high >> (((HALFFRACBITS + EXPBITS))))) & 1;
45848fb7bfaSmrg 
45948fb7bfaSmrg    if (exp != EXPMAX && exp != 0 && low != 0)
46048fb7bfaSmrg      {
46148fb7bfaSmrg        int lowexp = ((int)(low >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
46248fb7bfaSmrg        int lowsign = ((int)(low >> (((HALFFRACBITS + EXPBITS))))) & 1;
46348fb7bfaSmrg        int shift;
46448fb7bfaSmrg        fractype xlow;
46548fb7bfaSmrg 
46648fb7bfaSmrg        xlow = low & ((((fractype)1) << HALFFRACBITS) - 1);
46748fb7bfaSmrg        if (lowexp)
46848fb7bfaSmrg 	 xlow |= (((halffractype)1) << HALFFRACBITS);
46948fb7bfaSmrg        else
47048fb7bfaSmrg 	 lowexp = 1;
47148fb7bfaSmrg        shift = (FRACBITS - HALFFRACBITS) - (exp - lowexp);
47248fb7bfaSmrg        if (shift > 0)
47348fb7bfaSmrg 	 xlow <<= shift;
47448fb7bfaSmrg        else if (shift < 0)
47548fb7bfaSmrg 	 xlow >>= -shift;
47648fb7bfaSmrg        if (sign == lowsign)
47748fb7bfaSmrg 	 fraction += xlow;
47848fb7bfaSmrg        else if (fraction >= xlow)
47948fb7bfaSmrg 	 fraction -= xlow;
48048fb7bfaSmrg        else
48148fb7bfaSmrg 	 {
48248fb7bfaSmrg 	   /* The high part is a power of two but the full number is lower.
48348fb7bfaSmrg 	      This code will leave the implicit 1 in FRACTION, but we'd
48448fb7bfaSmrg 	      have added that below anyway.  */
48548fb7bfaSmrg 	   fraction = (((fractype) 1 << FRACBITS) - xlow) << 1;
48648fb7bfaSmrg 	   exp--;
48748fb7bfaSmrg 	 }
48848fb7bfaSmrg      }
48948fb7bfaSmrg  }
49048fb7bfaSmrg #else
49148fb7bfaSmrg   fraction = src->value_raw & ((((fractype)1) << FRACBITS) - 1);
49248fb7bfaSmrg   exp = ((int)(src->value_raw >> FRACBITS)) & ((1 << EXPBITS) - 1);
49348fb7bfaSmrg   sign = ((int)(src->value_raw >> (FRACBITS + EXPBITS))) & 1;
49448fb7bfaSmrg #endif
49548fb7bfaSmrg 
49648fb7bfaSmrg   dst->sign = sign;
49748fb7bfaSmrg   if (exp == 0)
49848fb7bfaSmrg     {
49948fb7bfaSmrg       /* Hmm.  Looks like 0 */
50048fb7bfaSmrg       if (fraction == 0
50148fb7bfaSmrg #ifdef NO_DENORMALS
50248fb7bfaSmrg 	  || 1
50348fb7bfaSmrg #endif
50448fb7bfaSmrg 	  )
50548fb7bfaSmrg 	{
50648fb7bfaSmrg 	  /* tastes like zero */
50748fb7bfaSmrg 	  dst->class = CLASS_ZERO;
50848fb7bfaSmrg 	}
50948fb7bfaSmrg       else
51048fb7bfaSmrg 	{
51148fb7bfaSmrg 	  /* Zero exponent with nonzero fraction - it's denormalized,
51248fb7bfaSmrg 	     so there isn't a leading implicit one - we'll shift it so
51348fb7bfaSmrg 	     it gets one.  */
51448fb7bfaSmrg 	  dst->normal_exp = exp - EXPBIAS + 1;
51548fb7bfaSmrg 	  fraction <<= NGARDS;
51648fb7bfaSmrg 
51748fb7bfaSmrg 	  dst->class = CLASS_NUMBER;
51848fb7bfaSmrg #if 1
51948fb7bfaSmrg 	  while (fraction < IMPLICIT_1)
52048fb7bfaSmrg 	    {
52148fb7bfaSmrg 	      fraction <<= 1;
52248fb7bfaSmrg 	      dst->normal_exp--;
52348fb7bfaSmrg 	    }
52448fb7bfaSmrg #endif
52548fb7bfaSmrg 	  dst->fraction.ll = fraction;
52648fb7bfaSmrg 	}
52748fb7bfaSmrg     }
5284d5abbe8Smrg   else if (__builtin_expect (exp == EXPMAX, 0))
52948fb7bfaSmrg     {
53048fb7bfaSmrg       /* Huge exponent*/
53148fb7bfaSmrg       if (fraction == 0)
53248fb7bfaSmrg 	{
53348fb7bfaSmrg 	  /* Attached to a zero fraction - means infinity */
53448fb7bfaSmrg 	  dst->class = CLASS_INFINITY;
53548fb7bfaSmrg 	}
53648fb7bfaSmrg       else
53748fb7bfaSmrg 	{
53848fb7bfaSmrg 	  /* Nonzero fraction, means nan */
53948fb7bfaSmrg #ifdef QUIET_NAN_NEGATED
54048fb7bfaSmrg 	  if ((fraction & QUIET_NAN) == 0)
54148fb7bfaSmrg #else
54248fb7bfaSmrg 	  if (fraction & QUIET_NAN)
54348fb7bfaSmrg #endif
54448fb7bfaSmrg 	    {
54548fb7bfaSmrg 	      dst->class = CLASS_QNAN;
54648fb7bfaSmrg 	    }
54748fb7bfaSmrg 	  else
54848fb7bfaSmrg 	    {
54948fb7bfaSmrg 	      dst->class = CLASS_SNAN;
55048fb7bfaSmrg 	    }
5514d5abbe8Smrg 	  /* Now that we know which kind of NaN we got, discard the
5524d5abbe8Smrg 	     quiet/signaling bit, but do preserve the NaN payload.  */
5534d5abbe8Smrg 	  fraction &= ~QUIET_NAN;
5544d5abbe8Smrg 	  dst->fraction.ll = fraction << NGARDS;
55548fb7bfaSmrg 	}
55648fb7bfaSmrg     }
55748fb7bfaSmrg   else
55848fb7bfaSmrg     {
55948fb7bfaSmrg       /* Nothing strange about this number */
56048fb7bfaSmrg       dst->normal_exp = exp - EXPBIAS;
56148fb7bfaSmrg       dst->class = CLASS_NUMBER;
56248fb7bfaSmrg       dst->fraction.ll = (fraction << NGARDS) | IMPLICIT_1;
56348fb7bfaSmrg     }
56448fb7bfaSmrg }
56548fb7bfaSmrg #endif /* L_unpack_df || L_unpack_sf */
56648fb7bfaSmrg 
56748fb7bfaSmrg #if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf)
56848fb7bfaSmrg static const fp_number_type *
56948fb7bfaSmrg _fpadd_parts (fp_number_type * a,
57048fb7bfaSmrg 	      fp_number_type * b,
57148fb7bfaSmrg 	      fp_number_type * tmp)
57248fb7bfaSmrg {
57348fb7bfaSmrg   intfrac tfraction;
57448fb7bfaSmrg 
57548fb7bfaSmrg   /* Put commonly used fields in local variables.  */
57648fb7bfaSmrg   int a_normal_exp;
57748fb7bfaSmrg   int b_normal_exp;
57848fb7bfaSmrg   fractype a_fraction;
57948fb7bfaSmrg   fractype b_fraction;
58048fb7bfaSmrg 
58148fb7bfaSmrg   if (isnan (a))
58248fb7bfaSmrg     {
58348fb7bfaSmrg       return a;
58448fb7bfaSmrg     }
58548fb7bfaSmrg   if (isnan (b))
58648fb7bfaSmrg     {
58748fb7bfaSmrg       return b;
58848fb7bfaSmrg     }
58948fb7bfaSmrg   if (isinf (a))
59048fb7bfaSmrg     {
59148fb7bfaSmrg       /* Adding infinities with opposite signs yields a NaN.  */
59248fb7bfaSmrg       if (isinf (b) && a->sign != b->sign)
59348fb7bfaSmrg 	return makenan ();
59448fb7bfaSmrg       return a;
59548fb7bfaSmrg     }
59648fb7bfaSmrg   if (isinf (b))
59748fb7bfaSmrg     {
59848fb7bfaSmrg       return b;
59948fb7bfaSmrg     }
60048fb7bfaSmrg   if (iszero (b))
60148fb7bfaSmrg     {
60248fb7bfaSmrg       if (iszero (a))
60348fb7bfaSmrg 	{
60448fb7bfaSmrg 	  *tmp = *a;
60548fb7bfaSmrg 	  tmp->sign = a->sign & b->sign;
60648fb7bfaSmrg 	  return tmp;
60748fb7bfaSmrg 	}
60848fb7bfaSmrg       return a;
60948fb7bfaSmrg     }
61048fb7bfaSmrg   if (iszero (a))
61148fb7bfaSmrg     {
61248fb7bfaSmrg       return b;
61348fb7bfaSmrg     }
61448fb7bfaSmrg 
61548fb7bfaSmrg   /* Got two numbers. shift the smaller and increment the exponent till
61648fb7bfaSmrg      they're the same */
61748fb7bfaSmrg   {
61848fb7bfaSmrg     int diff;
61948fb7bfaSmrg     int sdiff;
62048fb7bfaSmrg 
62148fb7bfaSmrg     a_normal_exp = a->normal_exp;
62248fb7bfaSmrg     b_normal_exp = b->normal_exp;
62348fb7bfaSmrg     a_fraction = a->fraction.ll;
62448fb7bfaSmrg     b_fraction = b->fraction.ll;
62548fb7bfaSmrg 
62648fb7bfaSmrg     diff = a_normal_exp - b_normal_exp;
62748fb7bfaSmrg     sdiff = diff;
62848fb7bfaSmrg 
62948fb7bfaSmrg     if (diff < 0)
63048fb7bfaSmrg       diff = -diff;
63148fb7bfaSmrg     if (diff < FRAC_NBITS)
63248fb7bfaSmrg       {
63348fb7bfaSmrg 	if (sdiff > 0)
63448fb7bfaSmrg 	  {
63548fb7bfaSmrg 	    b_normal_exp += diff;
63648fb7bfaSmrg 	    LSHIFT (b_fraction, diff);
63748fb7bfaSmrg 	  }
63848fb7bfaSmrg 	else if (sdiff < 0)
63948fb7bfaSmrg 	  {
64048fb7bfaSmrg 	    a_normal_exp += diff;
64148fb7bfaSmrg 	    LSHIFT (a_fraction, diff);
64248fb7bfaSmrg 	  }
64348fb7bfaSmrg       }
64448fb7bfaSmrg     else
64548fb7bfaSmrg       {
64648fb7bfaSmrg 	/* Somethings's up.. choose the biggest */
64748fb7bfaSmrg 	if (a_normal_exp > b_normal_exp)
64848fb7bfaSmrg 	  {
64948fb7bfaSmrg 	    b_normal_exp = a_normal_exp;
65048fb7bfaSmrg 	    b_fraction = 0;
65148fb7bfaSmrg 	  }
65248fb7bfaSmrg 	else
65348fb7bfaSmrg 	  {
65448fb7bfaSmrg 	    a_normal_exp = b_normal_exp;
65548fb7bfaSmrg 	    a_fraction = 0;
65648fb7bfaSmrg 	  }
65748fb7bfaSmrg       }
65848fb7bfaSmrg   }
65948fb7bfaSmrg 
66048fb7bfaSmrg   if (a->sign != b->sign)
66148fb7bfaSmrg     {
66248fb7bfaSmrg       if (a->sign)
66348fb7bfaSmrg 	{
66448fb7bfaSmrg 	  tfraction = -a_fraction + b_fraction;
66548fb7bfaSmrg 	}
66648fb7bfaSmrg       else
66748fb7bfaSmrg 	{
66848fb7bfaSmrg 	  tfraction = a_fraction - b_fraction;
66948fb7bfaSmrg 	}
67048fb7bfaSmrg       if (tfraction >= 0)
67148fb7bfaSmrg 	{
67248fb7bfaSmrg 	  tmp->sign = 0;
67348fb7bfaSmrg 	  tmp->normal_exp = a_normal_exp;
67448fb7bfaSmrg 	  tmp->fraction.ll = tfraction;
67548fb7bfaSmrg 	}
67648fb7bfaSmrg       else
67748fb7bfaSmrg 	{
67848fb7bfaSmrg 	  tmp->sign = 1;
67948fb7bfaSmrg 	  tmp->normal_exp = a_normal_exp;
68048fb7bfaSmrg 	  tmp->fraction.ll = -tfraction;
68148fb7bfaSmrg 	}
68248fb7bfaSmrg       /* and renormalize it */
68348fb7bfaSmrg 
68448fb7bfaSmrg       while (tmp->fraction.ll < IMPLICIT_1 && tmp->fraction.ll)
68548fb7bfaSmrg 	{
68648fb7bfaSmrg 	  tmp->fraction.ll <<= 1;
68748fb7bfaSmrg 	  tmp->normal_exp--;
68848fb7bfaSmrg 	}
68948fb7bfaSmrg     }
69048fb7bfaSmrg   else
69148fb7bfaSmrg     {
69248fb7bfaSmrg       tmp->sign = a->sign;
69348fb7bfaSmrg       tmp->normal_exp = a_normal_exp;
69448fb7bfaSmrg       tmp->fraction.ll = a_fraction + b_fraction;
69548fb7bfaSmrg     }
69648fb7bfaSmrg   tmp->class = CLASS_NUMBER;
69748fb7bfaSmrg   /* Now the fraction is added, we have to shift down to renormalize the
69848fb7bfaSmrg      number */
69948fb7bfaSmrg 
70048fb7bfaSmrg   if (tmp->fraction.ll >= IMPLICIT_2)
70148fb7bfaSmrg     {
70248fb7bfaSmrg       LSHIFT (tmp->fraction.ll, 1);
70348fb7bfaSmrg       tmp->normal_exp++;
70448fb7bfaSmrg     }
70548fb7bfaSmrg   return tmp;
70648fb7bfaSmrg }
70748fb7bfaSmrg 
70848fb7bfaSmrg FLO_type
70948fb7bfaSmrg add (FLO_type arg_a, FLO_type arg_b)
71048fb7bfaSmrg {
71148fb7bfaSmrg   fp_number_type a;
71248fb7bfaSmrg   fp_number_type b;
71348fb7bfaSmrg   fp_number_type tmp;
71448fb7bfaSmrg   const fp_number_type *res;
71548fb7bfaSmrg   FLO_union_type au, bu;
71648fb7bfaSmrg 
71748fb7bfaSmrg   au.value = arg_a;
71848fb7bfaSmrg   bu.value = arg_b;
71948fb7bfaSmrg 
72048fb7bfaSmrg   unpack_d (&au, &a);
72148fb7bfaSmrg   unpack_d (&bu, &b);
72248fb7bfaSmrg 
72348fb7bfaSmrg   res = _fpadd_parts (&a, &b, &tmp);
72448fb7bfaSmrg 
72548fb7bfaSmrg   return pack_d (res);
72648fb7bfaSmrg }
72748fb7bfaSmrg 
72848fb7bfaSmrg FLO_type
72948fb7bfaSmrg sub (FLO_type arg_a, FLO_type arg_b)
73048fb7bfaSmrg {
73148fb7bfaSmrg   fp_number_type a;
73248fb7bfaSmrg   fp_number_type b;
73348fb7bfaSmrg   fp_number_type tmp;
73448fb7bfaSmrg   const fp_number_type *res;
73548fb7bfaSmrg   FLO_union_type au, bu;
73648fb7bfaSmrg 
73748fb7bfaSmrg   au.value = arg_a;
73848fb7bfaSmrg   bu.value = arg_b;
73948fb7bfaSmrg 
74048fb7bfaSmrg   unpack_d (&au, &a);
74148fb7bfaSmrg   unpack_d (&bu, &b);
74248fb7bfaSmrg 
74348fb7bfaSmrg   b.sign ^= 1;
74448fb7bfaSmrg 
74548fb7bfaSmrg   res = _fpadd_parts (&a, &b, &tmp);
74648fb7bfaSmrg 
74748fb7bfaSmrg   return pack_d (res);
74848fb7bfaSmrg }
74948fb7bfaSmrg #endif /* L_addsub_sf || L_addsub_df */
75048fb7bfaSmrg 
75148fb7bfaSmrg #if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf)
75248fb7bfaSmrg static inline __attribute__ ((__always_inline__)) const fp_number_type *
75348fb7bfaSmrg _fpmul_parts ( fp_number_type *  a,
75448fb7bfaSmrg 	       fp_number_type *  b,
75548fb7bfaSmrg 	       fp_number_type * tmp)
75648fb7bfaSmrg {
75748fb7bfaSmrg   fractype low = 0;
75848fb7bfaSmrg   fractype high = 0;
75948fb7bfaSmrg 
76048fb7bfaSmrg   if (isnan (a))
76148fb7bfaSmrg     {
76248fb7bfaSmrg       a->sign = a->sign != b->sign;
76348fb7bfaSmrg       return a;
76448fb7bfaSmrg     }
76548fb7bfaSmrg   if (isnan (b))
76648fb7bfaSmrg     {
76748fb7bfaSmrg       b->sign = a->sign != b->sign;
76848fb7bfaSmrg       return b;
76948fb7bfaSmrg     }
77048fb7bfaSmrg   if (isinf (a))
77148fb7bfaSmrg     {
77248fb7bfaSmrg       if (iszero (b))
77348fb7bfaSmrg 	return makenan ();
77448fb7bfaSmrg       a->sign = a->sign != b->sign;
77548fb7bfaSmrg       return a;
77648fb7bfaSmrg     }
77748fb7bfaSmrg   if (isinf (b))
77848fb7bfaSmrg     {
77948fb7bfaSmrg       if (iszero (a))
78048fb7bfaSmrg 	{
78148fb7bfaSmrg 	  return makenan ();
78248fb7bfaSmrg 	}
78348fb7bfaSmrg       b->sign = a->sign != b->sign;
78448fb7bfaSmrg       return b;
78548fb7bfaSmrg     }
78648fb7bfaSmrg   if (iszero (a))
78748fb7bfaSmrg     {
78848fb7bfaSmrg       a->sign = a->sign != b->sign;
78948fb7bfaSmrg       return a;
79048fb7bfaSmrg     }
79148fb7bfaSmrg   if (iszero (b))
79248fb7bfaSmrg     {
79348fb7bfaSmrg       b->sign = a->sign != b->sign;
79448fb7bfaSmrg       return b;
79548fb7bfaSmrg     }
79648fb7bfaSmrg 
79748fb7bfaSmrg   /* Calculate the mantissa by multiplying both numbers to get a
79848fb7bfaSmrg      twice-as-wide number.  */
79948fb7bfaSmrg   {
80048fb7bfaSmrg #if defined(NO_DI_MODE) || defined(TFLOAT)
80148fb7bfaSmrg     {
80248fb7bfaSmrg       fractype x = a->fraction.ll;
80348fb7bfaSmrg       fractype ylow = b->fraction.ll;
80448fb7bfaSmrg       fractype yhigh = 0;
80548fb7bfaSmrg       int bit;
80648fb7bfaSmrg 
80748fb7bfaSmrg       /* ??? This does multiplies one bit at a time.  Optimize.  */
80848fb7bfaSmrg       for (bit = 0; bit < FRAC_NBITS; bit++)
80948fb7bfaSmrg 	{
81048fb7bfaSmrg 	  int carry;
81148fb7bfaSmrg 
81248fb7bfaSmrg 	  if (x & 1)
81348fb7bfaSmrg 	    {
81448fb7bfaSmrg 	      carry = (low += ylow) < ylow;
81548fb7bfaSmrg 	      high += yhigh + carry;
81648fb7bfaSmrg 	    }
81748fb7bfaSmrg 	  yhigh <<= 1;
81848fb7bfaSmrg 	  if (ylow & FRACHIGH)
81948fb7bfaSmrg 	    {
82048fb7bfaSmrg 	      yhigh |= 1;
82148fb7bfaSmrg 	    }
82248fb7bfaSmrg 	  ylow <<= 1;
82348fb7bfaSmrg 	  x >>= 1;
82448fb7bfaSmrg 	}
82548fb7bfaSmrg     }
82648fb7bfaSmrg #elif defined(FLOAT)
82748fb7bfaSmrg     /* Multiplying two USIs to get a UDI, we're safe.  */
82848fb7bfaSmrg     {
82948fb7bfaSmrg       UDItype answer = (UDItype)a->fraction.ll * (UDItype)b->fraction.ll;
83048fb7bfaSmrg 
83148fb7bfaSmrg       high = answer >> BITS_PER_SI;
83248fb7bfaSmrg       low = answer;
83348fb7bfaSmrg     }
83448fb7bfaSmrg #else
83548fb7bfaSmrg     /* fractype is DImode, but we need the result to be twice as wide.
83648fb7bfaSmrg        Assuming a widening multiply from DImode to TImode is not
83748fb7bfaSmrg        available, build one by hand.  */
83848fb7bfaSmrg     {
83948fb7bfaSmrg       USItype nl = a->fraction.ll;
84048fb7bfaSmrg       USItype nh = a->fraction.ll >> BITS_PER_SI;
84148fb7bfaSmrg       USItype ml = b->fraction.ll;
84248fb7bfaSmrg       USItype mh = b->fraction.ll >> BITS_PER_SI;
84348fb7bfaSmrg       UDItype pp_ll = (UDItype) ml * nl;
84448fb7bfaSmrg       UDItype pp_hl = (UDItype) mh * nl;
84548fb7bfaSmrg       UDItype pp_lh = (UDItype) ml * nh;
84648fb7bfaSmrg       UDItype pp_hh = (UDItype) mh * nh;
84748fb7bfaSmrg       UDItype res2 = 0;
84848fb7bfaSmrg       UDItype res0 = 0;
84948fb7bfaSmrg       UDItype ps_hh__ = pp_hl + pp_lh;
85048fb7bfaSmrg       if (ps_hh__ < pp_hl)
85148fb7bfaSmrg 	res2 += (UDItype)1 << BITS_PER_SI;
85248fb7bfaSmrg       pp_hl = (UDItype)(USItype)ps_hh__ << BITS_PER_SI;
85348fb7bfaSmrg       res0 = pp_ll + pp_hl;
85448fb7bfaSmrg       if (res0 < pp_ll)
85548fb7bfaSmrg 	res2++;
85648fb7bfaSmrg       res2 += (ps_hh__ >> BITS_PER_SI) + pp_hh;
85748fb7bfaSmrg       high = res2;
85848fb7bfaSmrg       low = res0;
85948fb7bfaSmrg     }
86048fb7bfaSmrg #endif
86148fb7bfaSmrg   }
86248fb7bfaSmrg 
86348fb7bfaSmrg   tmp->normal_exp = a->normal_exp + b->normal_exp
86448fb7bfaSmrg     + FRAC_NBITS - (FRACBITS + NGARDS);
86548fb7bfaSmrg   tmp->sign = a->sign != b->sign;
86648fb7bfaSmrg   while (high >= IMPLICIT_2)
86748fb7bfaSmrg     {
86848fb7bfaSmrg       tmp->normal_exp++;
86948fb7bfaSmrg       if (high & 1)
87048fb7bfaSmrg 	{
87148fb7bfaSmrg 	  low >>= 1;
87248fb7bfaSmrg 	  low |= FRACHIGH;
87348fb7bfaSmrg 	}
87448fb7bfaSmrg       high >>= 1;
87548fb7bfaSmrg     }
87648fb7bfaSmrg   while (high < IMPLICIT_1)
87748fb7bfaSmrg     {
87848fb7bfaSmrg       tmp->normal_exp--;
87948fb7bfaSmrg 
88048fb7bfaSmrg       high <<= 1;
88148fb7bfaSmrg       if (low & FRACHIGH)
88248fb7bfaSmrg 	high |= 1;
88348fb7bfaSmrg       low <<= 1;
88448fb7bfaSmrg     }
88548fb7bfaSmrg 
8864d5abbe8Smrg   if ((high & GARDMASK) == GARDMSB)
88748fb7bfaSmrg     {
88848fb7bfaSmrg       if (high & (1 << NGARDS))
88948fb7bfaSmrg 	{
89048fb7bfaSmrg 	  /* Because we're half way, we would round to even by adding
89148fb7bfaSmrg 	     GARDROUND + 1, except that's also done in the packing
89248fb7bfaSmrg 	     function, and rounding twice will lose precision and cause
89348fb7bfaSmrg 	     the result to be too far off.  Example: 32-bit floats with
89448fb7bfaSmrg 	     bit patterns 0xfff * 0x3f800400 ~= 0xfff (less than 0.5ulp
89548fb7bfaSmrg 	     off), not 0x1000 (more than 0.5ulp off).  */
89648fb7bfaSmrg 	}
89748fb7bfaSmrg       else if (low)
89848fb7bfaSmrg 	{
89948fb7bfaSmrg 	  /* We're a further than half way by a small amount corresponding
90048fb7bfaSmrg 	     to the bits set in "low".  Knowing that, we round here and
90148fb7bfaSmrg 	     not in pack_d, because there we don't have "low" available
90248fb7bfaSmrg 	     anymore.  */
90348fb7bfaSmrg 	  high += GARDROUND + 1;
90448fb7bfaSmrg 
90548fb7bfaSmrg 	  /* Avoid further rounding in pack_d.  */
90648fb7bfaSmrg 	  high &= ~(fractype) GARDMASK;
90748fb7bfaSmrg 	}
90848fb7bfaSmrg     }
90948fb7bfaSmrg   tmp->fraction.ll = high;
91048fb7bfaSmrg   tmp->class = CLASS_NUMBER;
91148fb7bfaSmrg   return tmp;
91248fb7bfaSmrg }
91348fb7bfaSmrg 
91448fb7bfaSmrg FLO_type
91548fb7bfaSmrg multiply (FLO_type arg_a, FLO_type arg_b)
91648fb7bfaSmrg {
91748fb7bfaSmrg   fp_number_type a;
91848fb7bfaSmrg   fp_number_type b;
91948fb7bfaSmrg   fp_number_type tmp;
92048fb7bfaSmrg   const fp_number_type *res;
92148fb7bfaSmrg   FLO_union_type au, bu;
92248fb7bfaSmrg 
92348fb7bfaSmrg   au.value = arg_a;
92448fb7bfaSmrg   bu.value = arg_b;
92548fb7bfaSmrg 
92648fb7bfaSmrg   unpack_d (&au, &a);
92748fb7bfaSmrg   unpack_d (&bu, &b);
92848fb7bfaSmrg 
92948fb7bfaSmrg   res = _fpmul_parts (&a, &b, &tmp);
93048fb7bfaSmrg 
93148fb7bfaSmrg   return pack_d (res);
93248fb7bfaSmrg }
93348fb7bfaSmrg #endif /* L_mul_sf || L_mul_df || L_mul_tf */
93448fb7bfaSmrg 
93548fb7bfaSmrg #if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf)
93648fb7bfaSmrg static inline __attribute__ ((__always_inline__)) const fp_number_type *
93748fb7bfaSmrg _fpdiv_parts (fp_number_type * a,
93848fb7bfaSmrg 	      fp_number_type * b)
93948fb7bfaSmrg {
94048fb7bfaSmrg   fractype bit;
94148fb7bfaSmrg   fractype numerator;
94248fb7bfaSmrg   fractype denominator;
94348fb7bfaSmrg   fractype quotient;
94448fb7bfaSmrg 
94548fb7bfaSmrg   if (isnan (a))
94648fb7bfaSmrg     {
94748fb7bfaSmrg       return a;
94848fb7bfaSmrg     }
94948fb7bfaSmrg   if (isnan (b))
95048fb7bfaSmrg     {
95148fb7bfaSmrg       return b;
95248fb7bfaSmrg     }
95348fb7bfaSmrg 
95448fb7bfaSmrg   a->sign = a->sign ^ b->sign;
95548fb7bfaSmrg 
95648fb7bfaSmrg   if (isinf (a) || iszero (a))
95748fb7bfaSmrg     {
95848fb7bfaSmrg       if (a->class == b->class)
95948fb7bfaSmrg 	return makenan ();
96048fb7bfaSmrg       return a;
96148fb7bfaSmrg     }
96248fb7bfaSmrg 
96348fb7bfaSmrg   if (isinf (b))
96448fb7bfaSmrg     {
96548fb7bfaSmrg       a->fraction.ll = 0;
96648fb7bfaSmrg       a->normal_exp = 0;
96748fb7bfaSmrg       return a;
96848fb7bfaSmrg     }
96948fb7bfaSmrg   if (iszero (b))
97048fb7bfaSmrg     {
97148fb7bfaSmrg       a->class = CLASS_INFINITY;
97248fb7bfaSmrg       return a;
97348fb7bfaSmrg     }
97448fb7bfaSmrg 
97548fb7bfaSmrg   /* Calculate the mantissa by multiplying both 64bit numbers to get a
97648fb7bfaSmrg      128 bit number */
97748fb7bfaSmrg   {
97848fb7bfaSmrg     /* quotient =
97948fb7bfaSmrg        ( numerator / denominator) * 2^(numerator exponent -  denominator exponent)
98048fb7bfaSmrg      */
98148fb7bfaSmrg 
98248fb7bfaSmrg     a->normal_exp = a->normal_exp - b->normal_exp;
98348fb7bfaSmrg     numerator = a->fraction.ll;
98448fb7bfaSmrg     denominator = b->fraction.ll;
98548fb7bfaSmrg 
98648fb7bfaSmrg     if (numerator < denominator)
98748fb7bfaSmrg       {
98848fb7bfaSmrg 	/* Fraction will be less than 1.0 */
98948fb7bfaSmrg 	numerator *= 2;
99048fb7bfaSmrg 	a->normal_exp--;
99148fb7bfaSmrg       }
99248fb7bfaSmrg     bit = IMPLICIT_1;
99348fb7bfaSmrg     quotient = 0;
99448fb7bfaSmrg     /* ??? Does divide one bit at a time.  Optimize.  */
99548fb7bfaSmrg     while (bit)
99648fb7bfaSmrg       {
99748fb7bfaSmrg 	if (numerator >= denominator)
99848fb7bfaSmrg 	  {
99948fb7bfaSmrg 	    quotient |= bit;
100048fb7bfaSmrg 	    numerator -= denominator;
100148fb7bfaSmrg 	  }
100248fb7bfaSmrg 	bit >>= 1;
100348fb7bfaSmrg 	numerator *= 2;
100448fb7bfaSmrg       }
100548fb7bfaSmrg 
10064d5abbe8Smrg     if ((quotient & GARDMASK) == GARDMSB)
100748fb7bfaSmrg       {
100848fb7bfaSmrg 	if (quotient & (1 << NGARDS))
100948fb7bfaSmrg 	  {
101048fb7bfaSmrg 	    /* Because we're half way, we would round to even by adding
101148fb7bfaSmrg 	       GARDROUND + 1, except that's also done in the packing
101248fb7bfaSmrg 	       function, and rounding twice will lose precision and cause
101348fb7bfaSmrg 	       the result to be too far off.  */
101448fb7bfaSmrg 	  }
101548fb7bfaSmrg 	else if (numerator)
101648fb7bfaSmrg 	  {
101748fb7bfaSmrg 	    /* We're a further than half way by the small amount
101848fb7bfaSmrg 	       corresponding to the bits set in "numerator".  Knowing
101948fb7bfaSmrg 	       that, we round here and not in pack_d, because there we
102048fb7bfaSmrg 	       don't have "numerator" available anymore.  */
102148fb7bfaSmrg 	    quotient += GARDROUND + 1;
102248fb7bfaSmrg 
102348fb7bfaSmrg 	    /* Avoid further rounding in pack_d.  */
102448fb7bfaSmrg 	    quotient &= ~(fractype) GARDMASK;
102548fb7bfaSmrg 	  }
102648fb7bfaSmrg       }
102748fb7bfaSmrg 
102848fb7bfaSmrg     a->fraction.ll = quotient;
102948fb7bfaSmrg     return (a);
103048fb7bfaSmrg   }
103148fb7bfaSmrg }
103248fb7bfaSmrg 
103348fb7bfaSmrg FLO_type
103448fb7bfaSmrg divide (FLO_type arg_a, FLO_type arg_b)
103548fb7bfaSmrg {
103648fb7bfaSmrg   fp_number_type a;
103748fb7bfaSmrg   fp_number_type b;
103848fb7bfaSmrg   const fp_number_type *res;
103948fb7bfaSmrg   FLO_union_type au, bu;
104048fb7bfaSmrg 
104148fb7bfaSmrg   au.value = arg_a;
104248fb7bfaSmrg   bu.value = arg_b;
104348fb7bfaSmrg 
104448fb7bfaSmrg   unpack_d (&au, &a);
104548fb7bfaSmrg   unpack_d (&bu, &b);
104648fb7bfaSmrg 
104748fb7bfaSmrg   res = _fpdiv_parts (&a, &b);
104848fb7bfaSmrg 
104948fb7bfaSmrg   return pack_d (res);
105048fb7bfaSmrg }
105148fb7bfaSmrg #endif /* L_div_sf || L_div_df */
105248fb7bfaSmrg 
105348fb7bfaSmrg #if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df) \
105448fb7bfaSmrg     || defined(L_fpcmp_parts_tf)
105548fb7bfaSmrg /* according to the demo, fpcmp returns a comparison with 0... thus
105648fb7bfaSmrg    a<b -> -1
105748fb7bfaSmrg    a==b -> 0
105848fb7bfaSmrg    a>b -> +1
105948fb7bfaSmrg  */
106048fb7bfaSmrg 
106148fb7bfaSmrg int
106248fb7bfaSmrg __fpcmp_parts (fp_number_type * a, fp_number_type * b)
106348fb7bfaSmrg {
106448fb7bfaSmrg #if 0
106548fb7bfaSmrg   /* either nan -> unordered. Must be checked outside of this routine.  */
106648fb7bfaSmrg   if (isnan (a) && isnan (b))
106748fb7bfaSmrg     {
106848fb7bfaSmrg       return 1;			/* still unordered! */
106948fb7bfaSmrg     }
107048fb7bfaSmrg #endif
107148fb7bfaSmrg 
107248fb7bfaSmrg   if (isnan (a) || isnan (b))
107348fb7bfaSmrg     {
107448fb7bfaSmrg       return 1;			/* how to indicate unordered compare? */
107548fb7bfaSmrg     }
107648fb7bfaSmrg   if (isinf (a) && isinf (b))
107748fb7bfaSmrg     {
107848fb7bfaSmrg       /* +inf > -inf, but +inf != +inf */
107948fb7bfaSmrg       /* b    \a| +inf(0)| -inf(1)
108048fb7bfaSmrg        ______\+--------+--------
108148fb7bfaSmrg        +inf(0)| a==b(0)| a<b(-1)
108248fb7bfaSmrg        -------+--------+--------
108348fb7bfaSmrg        -inf(1)| a>b(1) | a==b(0)
108448fb7bfaSmrg        -------+--------+--------
108548fb7bfaSmrg        So since unordered must be nonzero, just line up the columns...
108648fb7bfaSmrg        */
108748fb7bfaSmrg       return b->sign - a->sign;
108848fb7bfaSmrg     }
108948fb7bfaSmrg   /* but not both...  */
109048fb7bfaSmrg   if (isinf (a))
109148fb7bfaSmrg     {
109248fb7bfaSmrg       return a->sign ? -1 : 1;
109348fb7bfaSmrg     }
109448fb7bfaSmrg   if (isinf (b))
109548fb7bfaSmrg     {
109648fb7bfaSmrg       return b->sign ? 1 : -1;
109748fb7bfaSmrg     }
109848fb7bfaSmrg   if (iszero (a) && iszero (b))
109948fb7bfaSmrg     {
110048fb7bfaSmrg       return 0;
110148fb7bfaSmrg     }
110248fb7bfaSmrg   if (iszero (a))
110348fb7bfaSmrg     {
110448fb7bfaSmrg       return b->sign ? 1 : -1;
110548fb7bfaSmrg     }
110648fb7bfaSmrg   if (iszero (b))
110748fb7bfaSmrg     {
110848fb7bfaSmrg       return a->sign ? -1 : 1;
110948fb7bfaSmrg     }
111048fb7bfaSmrg   /* now both are "normal".  */
111148fb7bfaSmrg   if (a->sign != b->sign)
111248fb7bfaSmrg     {
111348fb7bfaSmrg       /* opposite signs */
111448fb7bfaSmrg       return a->sign ? -1 : 1;
111548fb7bfaSmrg     }
111648fb7bfaSmrg   /* same sign; exponents? */
111748fb7bfaSmrg   if (a->normal_exp > b->normal_exp)
111848fb7bfaSmrg     {
111948fb7bfaSmrg       return a->sign ? -1 : 1;
112048fb7bfaSmrg     }
112148fb7bfaSmrg   if (a->normal_exp < b->normal_exp)
112248fb7bfaSmrg     {
112348fb7bfaSmrg       return a->sign ? 1 : -1;
112448fb7bfaSmrg     }
112548fb7bfaSmrg   /* same exponents; check size.  */
112648fb7bfaSmrg   if (a->fraction.ll > b->fraction.ll)
112748fb7bfaSmrg     {
112848fb7bfaSmrg       return a->sign ? -1 : 1;
112948fb7bfaSmrg     }
113048fb7bfaSmrg   if (a->fraction.ll < b->fraction.ll)
113148fb7bfaSmrg     {
113248fb7bfaSmrg       return a->sign ? 1 : -1;
113348fb7bfaSmrg     }
113448fb7bfaSmrg   /* after all that, they're equal.  */
113548fb7bfaSmrg   return 0;
113648fb7bfaSmrg }
113748fb7bfaSmrg #endif
113848fb7bfaSmrg 
113948fb7bfaSmrg #if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compoare_tf)
114048fb7bfaSmrg CMPtype
114148fb7bfaSmrg compare (FLO_type arg_a, FLO_type arg_b)
114248fb7bfaSmrg {
114348fb7bfaSmrg   fp_number_type a;
114448fb7bfaSmrg   fp_number_type b;
114548fb7bfaSmrg   FLO_union_type au, bu;
114648fb7bfaSmrg 
114748fb7bfaSmrg   au.value = arg_a;
114848fb7bfaSmrg   bu.value = arg_b;
114948fb7bfaSmrg 
115048fb7bfaSmrg   unpack_d (&au, &a);
115148fb7bfaSmrg   unpack_d (&bu, &b);
115248fb7bfaSmrg 
115348fb7bfaSmrg   return __fpcmp_parts (&a, &b);
115448fb7bfaSmrg }
115548fb7bfaSmrg #endif /* L_compare_sf || L_compare_df */
115648fb7bfaSmrg 
115748fb7bfaSmrg /* These should be optimized for their specific tasks someday.  */
115848fb7bfaSmrg 
115948fb7bfaSmrg #if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf)
116048fb7bfaSmrg CMPtype
116148fb7bfaSmrg _eq_f2 (FLO_type arg_a, FLO_type arg_b)
116248fb7bfaSmrg {
116348fb7bfaSmrg   fp_number_type a;
116448fb7bfaSmrg   fp_number_type b;
116548fb7bfaSmrg   FLO_union_type au, bu;
116648fb7bfaSmrg 
116748fb7bfaSmrg   au.value = arg_a;
116848fb7bfaSmrg   bu.value = arg_b;
116948fb7bfaSmrg 
117048fb7bfaSmrg   unpack_d (&au, &a);
117148fb7bfaSmrg   unpack_d (&bu, &b);
117248fb7bfaSmrg 
117348fb7bfaSmrg   if (isnan (&a) || isnan (&b))
117448fb7bfaSmrg     return 1;			/* false, truth == 0 */
117548fb7bfaSmrg 
117648fb7bfaSmrg   return __fpcmp_parts (&a, &b) ;
117748fb7bfaSmrg }
117848fb7bfaSmrg #endif /* L_eq_sf || L_eq_df */
117948fb7bfaSmrg 
118048fb7bfaSmrg #if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf)
118148fb7bfaSmrg CMPtype
118248fb7bfaSmrg _ne_f2 (FLO_type arg_a, FLO_type arg_b)
118348fb7bfaSmrg {
118448fb7bfaSmrg   fp_number_type a;
118548fb7bfaSmrg   fp_number_type b;
118648fb7bfaSmrg   FLO_union_type au, bu;
118748fb7bfaSmrg 
118848fb7bfaSmrg   au.value = arg_a;
118948fb7bfaSmrg   bu.value = arg_b;
119048fb7bfaSmrg 
119148fb7bfaSmrg   unpack_d (&au, &a);
119248fb7bfaSmrg   unpack_d (&bu, &b);
119348fb7bfaSmrg 
119448fb7bfaSmrg   if (isnan (&a) || isnan (&b))
119548fb7bfaSmrg     return 1;			/* true, truth != 0 */
119648fb7bfaSmrg 
119748fb7bfaSmrg   return  __fpcmp_parts (&a, &b) ;
119848fb7bfaSmrg }
119948fb7bfaSmrg #endif /* L_ne_sf || L_ne_df */
120048fb7bfaSmrg 
120148fb7bfaSmrg #if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf)
120248fb7bfaSmrg CMPtype
120348fb7bfaSmrg _gt_f2 (FLO_type arg_a, FLO_type arg_b)
120448fb7bfaSmrg {
120548fb7bfaSmrg   fp_number_type a;
120648fb7bfaSmrg   fp_number_type b;
120748fb7bfaSmrg   FLO_union_type au, bu;
120848fb7bfaSmrg 
120948fb7bfaSmrg   au.value = arg_a;
121048fb7bfaSmrg   bu.value = arg_b;
121148fb7bfaSmrg 
121248fb7bfaSmrg   unpack_d (&au, &a);
121348fb7bfaSmrg   unpack_d (&bu, &b);
121448fb7bfaSmrg 
121548fb7bfaSmrg   if (isnan (&a) || isnan (&b))
121648fb7bfaSmrg     return -1;			/* false, truth > 0 */
121748fb7bfaSmrg 
121848fb7bfaSmrg   return __fpcmp_parts (&a, &b);
121948fb7bfaSmrg }
122048fb7bfaSmrg #endif /* L_gt_sf || L_gt_df */
122148fb7bfaSmrg 
122248fb7bfaSmrg #if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf)
122348fb7bfaSmrg CMPtype
122448fb7bfaSmrg _ge_f2 (FLO_type arg_a, FLO_type arg_b)
122548fb7bfaSmrg {
122648fb7bfaSmrg   fp_number_type a;
122748fb7bfaSmrg   fp_number_type b;
122848fb7bfaSmrg   FLO_union_type au, bu;
122948fb7bfaSmrg 
123048fb7bfaSmrg   au.value = arg_a;
123148fb7bfaSmrg   bu.value = arg_b;
123248fb7bfaSmrg 
123348fb7bfaSmrg   unpack_d (&au, &a);
123448fb7bfaSmrg   unpack_d (&bu, &b);
123548fb7bfaSmrg 
123648fb7bfaSmrg   if (isnan (&a) || isnan (&b))
123748fb7bfaSmrg     return -1;			/* false, truth >= 0 */
123848fb7bfaSmrg   return __fpcmp_parts (&a, &b) ;
123948fb7bfaSmrg }
124048fb7bfaSmrg #endif /* L_ge_sf || L_ge_df */
124148fb7bfaSmrg 
124248fb7bfaSmrg #if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf)
124348fb7bfaSmrg CMPtype
124448fb7bfaSmrg _lt_f2 (FLO_type arg_a, FLO_type arg_b)
124548fb7bfaSmrg {
124648fb7bfaSmrg   fp_number_type a;
124748fb7bfaSmrg   fp_number_type b;
124848fb7bfaSmrg   FLO_union_type au, bu;
124948fb7bfaSmrg 
125048fb7bfaSmrg   au.value = arg_a;
125148fb7bfaSmrg   bu.value = arg_b;
125248fb7bfaSmrg 
125348fb7bfaSmrg   unpack_d (&au, &a);
125448fb7bfaSmrg   unpack_d (&bu, &b);
125548fb7bfaSmrg 
125648fb7bfaSmrg   if (isnan (&a) || isnan (&b))
125748fb7bfaSmrg     return 1;			/* false, truth < 0 */
125848fb7bfaSmrg 
125948fb7bfaSmrg   return __fpcmp_parts (&a, &b);
126048fb7bfaSmrg }
126148fb7bfaSmrg #endif /* L_lt_sf || L_lt_df */
126248fb7bfaSmrg 
126348fb7bfaSmrg #if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf)
126448fb7bfaSmrg CMPtype
126548fb7bfaSmrg _le_f2 (FLO_type arg_a, FLO_type arg_b)
126648fb7bfaSmrg {
126748fb7bfaSmrg   fp_number_type a;
126848fb7bfaSmrg   fp_number_type b;
126948fb7bfaSmrg   FLO_union_type au, bu;
127048fb7bfaSmrg 
127148fb7bfaSmrg   au.value = arg_a;
127248fb7bfaSmrg   bu.value = arg_b;
127348fb7bfaSmrg 
127448fb7bfaSmrg   unpack_d (&au, &a);
127548fb7bfaSmrg   unpack_d (&bu, &b);
127648fb7bfaSmrg 
127748fb7bfaSmrg   if (isnan (&a) || isnan (&b))
127848fb7bfaSmrg     return 1;			/* false, truth <= 0 */
127948fb7bfaSmrg 
128048fb7bfaSmrg   return __fpcmp_parts (&a, &b) ;
128148fb7bfaSmrg }
128248fb7bfaSmrg #endif /* L_le_sf || L_le_df */
128348fb7bfaSmrg 
128448fb7bfaSmrg #if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf)
128548fb7bfaSmrg CMPtype
128648fb7bfaSmrg _unord_f2 (FLO_type arg_a, FLO_type arg_b)
128748fb7bfaSmrg {
128848fb7bfaSmrg   fp_number_type a;
128948fb7bfaSmrg   fp_number_type b;
129048fb7bfaSmrg   FLO_union_type au, bu;
129148fb7bfaSmrg 
129248fb7bfaSmrg   au.value = arg_a;
129348fb7bfaSmrg   bu.value = arg_b;
129448fb7bfaSmrg 
129548fb7bfaSmrg   unpack_d (&au, &a);
129648fb7bfaSmrg   unpack_d (&bu, &b);
129748fb7bfaSmrg 
129848fb7bfaSmrg   return (isnan (&a) || isnan (&b));
129948fb7bfaSmrg }
130048fb7bfaSmrg #endif /* L_unord_sf || L_unord_df */
130148fb7bfaSmrg 
130248fb7bfaSmrg #if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf)
130348fb7bfaSmrg FLO_type
130448fb7bfaSmrg si_to_float (SItype arg_a)
130548fb7bfaSmrg {
130648fb7bfaSmrg   fp_number_type in;
130748fb7bfaSmrg 
130848fb7bfaSmrg   in.class = CLASS_NUMBER;
130948fb7bfaSmrg   in.sign = arg_a < 0;
131048fb7bfaSmrg   if (!arg_a)
131148fb7bfaSmrg     {
131248fb7bfaSmrg       in.class = CLASS_ZERO;
131348fb7bfaSmrg     }
131448fb7bfaSmrg   else
131548fb7bfaSmrg     {
131648fb7bfaSmrg       USItype uarg;
131748fb7bfaSmrg       int shift;
131848fb7bfaSmrg       in.normal_exp = FRACBITS + NGARDS;
131948fb7bfaSmrg       if (in.sign)
132048fb7bfaSmrg 	{
132148fb7bfaSmrg 	  /* Special case for minint, since there is no +ve integer
132248fb7bfaSmrg 	     representation for it */
132348fb7bfaSmrg 	  if (arg_a == (- MAX_SI_INT - 1))
132448fb7bfaSmrg 	    {
132548fb7bfaSmrg 	      return (FLO_type)(- MAX_SI_INT - 1);
132648fb7bfaSmrg 	    }
132748fb7bfaSmrg 	  uarg = (-arg_a);
132848fb7bfaSmrg 	}
132948fb7bfaSmrg       else
133048fb7bfaSmrg 	uarg = arg_a;
133148fb7bfaSmrg 
133248fb7bfaSmrg       in.fraction.ll = uarg;
133348fb7bfaSmrg       shift = clzusi (uarg) - (BITS_PER_SI - 1 - FRACBITS - NGARDS);
133448fb7bfaSmrg       if (shift > 0)
133548fb7bfaSmrg 	{
133648fb7bfaSmrg 	  in.fraction.ll <<= shift;
133748fb7bfaSmrg 	  in.normal_exp -= shift;
133848fb7bfaSmrg 	}
133948fb7bfaSmrg     }
134048fb7bfaSmrg   return pack_d (&in);
134148fb7bfaSmrg }
134248fb7bfaSmrg #endif /* L_si_to_sf || L_si_to_df */
134348fb7bfaSmrg 
134448fb7bfaSmrg #if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf)
134548fb7bfaSmrg FLO_type
134648fb7bfaSmrg usi_to_float (USItype arg_a)
134748fb7bfaSmrg {
134848fb7bfaSmrg   fp_number_type in;
134948fb7bfaSmrg 
135048fb7bfaSmrg   in.sign = 0;
135148fb7bfaSmrg   if (!arg_a)
135248fb7bfaSmrg     {
135348fb7bfaSmrg       in.class = CLASS_ZERO;
135448fb7bfaSmrg     }
135548fb7bfaSmrg   else
135648fb7bfaSmrg     {
135748fb7bfaSmrg       int shift;
135848fb7bfaSmrg       in.class = CLASS_NUMBER;
135948fb7bfaSmrg       in.normal_exp = FRACBITS + NGARDS;
136048fb7bfaSmrg       in.fraction.ll = arg_a;
136148fb7bfaSmrg 
136248fb7bfaSmrg       shift = clzusi (arg_a) - (BITS_PER_SI - 1 - FRACBITS - NGARDS);
136348fb7bfaSmrg       if (shift < 0)
136448fb7bfaSmrg 	{
136548fb7bfaSmrg 	  fractype guard = in.fraction.ll & (((fractype)1 << -shift) - 1);
136648fb7bfaSmrg 	  in.fraction.ll >>= -shift;
136748fb7bfaSmrg 	  in.fraction.ll |= (guard != 0);
136848fb7bfaSmrg 	  in.normal_exp -= shift;
136948fb7bfaSmrg 	}
137048fb7bfaSmrg       else if (shift > 0)
137148fb7bfaSmrg 	{
137248fb7bfaSmrg 	  in.fraction.ll <<= shift;
137348fb7bfaSmrg 	  in.normal_exp -= shift;
137448fb7bfaSmrg 	}
137548fb7bfaSmrg     }
137648fb7bfaSmrg   return pack_d (&in);
137748fb7bfaSmrg }
137848fb7bfaSmrg #endif
137948fb7bfaSmrg 
138048fb7bfaSmrg #if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si)
138148fb7bfaSmrg SItype
138248fb7bfaSmrg float_to_si (FLO_type arg_a)
138348fb7bfaSmrg {
138448fb7bfaSmrg   fp_number_type a;
138548fb7bfaSmrg   SItype tmp;
138648fb7bfaSmrg   FLO_union_type au;
138748fb7bfaSmrg 
138848fb7bfaSmrg   au.value = arg_a;
138948fb7bfaSmrg   unpack_d (&au, &a);
139048fb7bfaSmrg 
139148fb7bfaSmrg   if (iszero (&a))
139248fb7bfaSmrg     return 0;
139348fb7bfaSmrg   if (isnan (&a))
139448fb7bfaSmrg     return 0;
139548fb7bfaSmrg   /* get reasonable MAX_SI_INT...  */
139648fb7bfaSmrg   if (isinf (&a))
139748fb7bfaSmrg     return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
139848fb7bfaSmrg   /* it is a number, but a small one */
139948fb7bfaSmrg   if (a.normal_exp < 0)
140048fb7bfaSmrg     return 0;
140148fb7bfaSmrg   if (a.normal_exp > BITS_PER_SI - 2)
140248fb7bfaSmrg     return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
140348fb7bfaSmrg   tmp = a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
140448fb7bfaSmrg   return a.sign ? (-tmp) : (tmp);
140548fb7bfaSmrg }
140648fb7bfaSmrg #endif /* L_sf_to_si || L_df_to_si */
140748fb7bfaSmrg 
140848fb7bfaSmrg #if defined(L_tf_to_usi)
140948fb7bfaSmrg USItype
141048fb7bfaSmrg float_to_usi (FLO_type arg_a)
141148fb7bfaSmrg {
141248fb7bfaSmrg   fp_number_type a;
141348fb7bfaSmrg   FLO_union_type au;
141448fb7bfaSmrg 
141548fb7bfaSmrg   au.value = arg_a;
141648fb7bfaSmrg   unpack_d (&au, &a);
141748fb7bfaSmrg 
141848fb7bfaSmrg   if (iszero (&a))
141948fb7bfaSmrg     return 0;
142048fb7bfaSmrg   if (isnan (&a))
142148fb7bfaSmrg     return 0;
142248fb7bfaSmrg   /* it is a negative number */
142348fb7bfaSmrg   if (a.sign)
142448fb7bfaSmrg     return 0;
142548fb7bfaSmrg   /* get reasonable MAX_USI_INT...  */
142648fb7bfaSmrg   if (isinf (&a))
142748fb7bfaSmrg     return MAX_USI_INT;
142848fb7bfaSmrg   /* it is a number, but a small one */
142948fb7bfaSmrg   if (a.normal_exp < 0)
143048fb7bfaSmrg     return 0;
143148fb7bfaSmrg   if (a.normal_exp > BITS_PER_SI - 1)
143248fb7bfaSmrg     return MAX_USI_INT;
143348fb7bfaSmrg   else if (a.normal_exp > (FRACBITS + NGARDS))
143448fb7bfaSmrg     return a.fraction.ll << (a.normal_exp - (FRACBITS + NGARDS));
143548fb7bfaSmrg   else
143648fb7bfaSmrg     return a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
143748fb7bfaSmrg }
143848fb7bfaSmrg #endif /* L_tf_to_usi */
143948fb7bfaSmrg 
144048fb7bfaSmrg #if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf)
144148fb7bfaSmrg FLO_type
144248fb7bfaSmrg negate (FLO_type arg_a)
144348fb7bfaSmrg {
144448fb7bfaSmrg   fp_number_type a;
144548fb7bfaSmrg   FLO_union_type au;
144648fb7bfaSmrg 
144748fb7bfaSmrg   au.value = arg_a;
144848fb7bfaSmrg   unpack_d (&au, &a);
144948fb7bfaSmrg 
145048fb7bfaSmrg   flip_sign (&a);
145148fb7bfaSmrg   return pack_d (&a);
145248fb7bfaSmrg }
145348fb7bfaSmrg #endif /* L_negate_sf || L_negate_df */
145448fb7bfaSmrg 
145548fb7bfaSmrg #ifdef FLOAT
145648fb7bfaSmrg 
145748fb7bfaSmrg #if defined(L_make_sf)
145848fb7bfaSmrg SFtype
145948fb7bfaSmrg __make_fp(fp_class_type class,
146048fb7bfaSmrg 	     unsigned int sign,
146148fb7bfaSmrg 	     int exp,
146248fb7bfaSmrg 	     USItype frac)
146348fb7bfaSmrg {
146448fb7bfaSmrg   fp_number_type in;
146548fb7bfaSmrg 
146648fb7bfaSmrg   in.class = class;
146748fb7bfaSmrg   in.sign = sign;
146848fb7bfaSmrg   in.normal_exp = exp;
146948fb7bfaSmrg   in.fraction.ll = frac;
147048fb7bfaSmrg   return pack_d (&in);
147148fb7bfaSmrg }
147248fb7bfaSmrg #endif /* L_make_sf */
147348fb7bfaSmrg 
147448fb7bfaSmrg #ifndef FLOAT_ONLY
147548fb7bfaSmrg 
147648fb7bfaSmrg /* This enables one to build an fp library that supports float but not double.
147748fb7bfaSmrg    Otherwise, we would get an undefined reference to __make_dp.
147848fb7bfaSmrg    This is needed for some 8-bit ports that can't handle well values that
147948fb7bfaSmrg    are 8-bytes in size, so we just don't support double for them at all.  */
148048fb7bfaSmrg 
148148fb7bfaSmrg #if defined(L_sf_to_df)
148248fb7bfaSmrg DFtype
148348fb7bfaSmrg sf_to_df (SFtype arg_a)
148448fb7bfaSmrg {
148548fb7bfaSmrg   fp_number_type in;
148648fb7bfaSmrg   FLO_union_type au;
148748fb7bfaSmrg 
148848fb7bfaSmrg   au.value = arg_a;
148948fb7bfaSmrg   unpack_d (&au, &in);
149048fb7bfaSmrg 
149148fb7bfaSmrg   return __make_dp (in.class, in.sign, in.normal_exp,
149248fb7bfaSmrg 		    ((UDItype) in.fraction.ll) << F_D_BITOFF);
149348fb7bfaSmrg }
149448fb7bfaSmrg #endif /* L_sf_to_df */
149548fb7bfaSmrg 
149648fb7bfaSmrg #if defined(L_sf_to_tf) && defined(TMODES)
149748fb7bfaSmrg TFtype
149848fb7bfaSmrg sf_to_tf (SFtype arg_a)
149948fb7bfaSmrg {
150048fb7bfaSmrg   fp_number_type in;
150148fb7bfaSmrg   FLO_union_type au;
150248fb7bfaSmrg 
150348fb7bfaSmrg   au.value = arg_a;
150448fb7bfaSmrg   unpack_d (&au, &in);
150548fb7bfaSmrg 
150648fb7bfaSmrg   return __make_tp (in.class, in.sign, in.normal_exp,
150748fb7bfaSmrg 		    ((UTItype) in.fraction.ll) << F_T_BITOFF);
150848fb7bfaSmrg }
150948fb7bfaSmrg #endif /* L_sf_to_df */
151048fb7bfaSmrg 
151148fb7bfaSmrg #endif /* ! FLOAT_ONLY */
151248fb7bfaSmrg #endif /* FLOAT */
151348fb7bfaSmrg 
151448fb7bfaSmrg #ifndef FLOAT
151548fb7bfaSmrg 
151648fb7bfaSmrg extern SFtype __make_fp (fp_class_type, unsigned int, int, USItype);
151748fb7bfaSmrg 
151848fb7bfaSmrg #if defined(L_make_df)
151948fb7bfaSmrg DFtype
152048fb7bfaSmrg __make_dp (fp_class_type class, unsigned int sign, int exp, UDItype frac)
152148fb7bfaSmrg {
152248fb7bfaSmrg   fp_number_type in;
152348fb7bfaSmrg 
152448fb7bfaSmrg   in.class = class;
152548fb7bfaSmrg   in.sign = sign;
152648fb7bfaSmrg   in.normal_exp = exp;
152748fb7bfaSmrg   in.fraction.ll = frac;
152848fb7bfaSmrg   return pack_d (&in);
152948fb7bfaSmrg }
153048fb7bfaSmrg #endif /* L_make_df */
153148fb7bfaSmrg 
153248fb7bfaSmrg #if defined(L_df_to_sf)
153348fb7bfaSmrg SFtype
153448fb7bfaSmrg df_to_sf (DFtype arg_a)
153548fb7bfaSmrg {
153648fb7bfaSmrg   fp_number_type in;
153748fb7bfaSmrg   USItype sffrac;
153848fb7bfaSmrg   FLO_union_type au;
153948fb7bfaSmrg 
154048fb7bfaSmrg   au.value = arg_a;
154148fb7bfaSmrg   unpack_d (&au, &in);
154248fb7bfaSmrg 
154348fb7bfaSmrg   sffrac = in.fraction.ll >> F_D_BITOFF;
154448fb7bfaSmrg 
154548fb7bfaSmrg   /* We set the lowest guard bit in SFFRAC if we discarded any non
154648fb7bfaSmrg      zero bits.  */
154748fb7bfaSmrg   if ((in.fraction.ll & (((USItype) 1 << F_D_BITOFF) - 1)) != 0)
154848fb7bfaSmrg     sffrac |= 1;
154948fb7bfaSmrg 
155048fb7bfaSmrg   return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
155148fb7bfaSmrg }
155248fb7bfaSmrg #endif /* L_df_to_sf */
155348fb7bfaSmrg 
155448fb7bfaSmrg #if defined(L_df_to_tf) && defined(TMODES) \
155548fb7bfaSmrg     && !defined(FLOAT) && !defined(TFLOAT)
155648fb7bfaSmrg TFtype
155748fb7bfaSmrg df_to_tf (DFtype arg_a)
155848fb7bfaSmrg {
155948fb7bfaSmrg   fp_number_type in;
156048fb7bfaSmrg   FLO_union_type au;
156148fb7bfaSmrg 
156248fb7bfaSmrg   au.value = arg_a;
156348fb7bfaSmrg   unpack_d (&au, &in);
156448fb7bfaSmrg 
156548fb7bfaSmrg   return __make_tp (in.class, in.sign, in.normal_exp,
156648fb7bfaSmrg 		    ((UTItype) in.fraction.ll) << D_T_BITOFF);
156748fb7bfaSmrg }
156848fb7bfaSmrg #endif /* L_sf_to_df */
156948fb7bfaSmrg 
157048fb7bfaSmrg #ifdef TFLOAT
157148fb7bfaSmrg #if defined(L_make_tf)
157248fb7bfaSmrg TFtype
157348fb7bfaSmrg __make_tp(fp_class_type class,
157448fb7bfaSmrg 	     unsigned int sign,
157548fb7bfaSmrg 	     int exp,
157648fb7bfaSmrg 	     UTItype frac)
157748fb7bfaSmrg {
157848fb7bfaSmrg   fp_number_type in;
157948fb7bfaSmrg 
158048fb7bfaSmrg   in.class = class;
158148fb7bfaSmrg   in.sign = sign;
158248fb7bfaSmrg   in.normal_exp = exp;
158348fb7bfaSmrg   in.fraction.ll = frac;
158448fb7bfaSmrg   return pack_d (&in);
158548fb7bfaSmrg }
158648fb7bfaSmrg #endif /* L_make_tf */
158748fb7bfaSmrg 
158848fb7bfaSmrg #if defined(L_tf_to_df)
158948fb7bfaSmrg DFtype
159048fb7bfaSmrg tf_to_df (TFtype arg_a)
159148fb7bfaSmrg {
159248fb7bfaSmrg   fp_number_type in;
159348fb7bfaSmrg   UDItype sffrac;
159448fb7bfaSmrg   FLO_union_type au;
159548fb7bfaSmrg 
159648fb7bfaSmrg   au.value = arg_a;
159748fb7bfaSmrg   unpack_d (&au, &in);
159848fb7bfaSmrg 
159948fb7bfaSmrg   sffrac = in.fraction.ll >> D_T_BITOFF;
160048fb7bfaSmrg 
160148fb7bfaSmrg   /* We set the lowest guard bit in SFFRAC if we discarded any non
160248fb7bfaSmrg      zero bits.  */
160348fb7bfaSmrg   if ((in.fraction.ll & (((UTItype) 1 << D_T_BITOFF) - 1)) != 0)
160448fb7bfaSmrg     sffrac |= 1;
160548fb7bfaSmrg 
160648fb7bfaSmrg   return __make_dp (in.class, in.sign, in.normal_exp, sffrac);
160748fb7bfaSmrg }
160848fb7bfaSmrg #endif /* L_tf_to_df */
160948fb7bfaSmrg 
161048fb7bfaSmrg #if defined(L_tf_to_sf)
161148fb7bfaSmrg SFtype
161248fb7bfaSmrg tf_to_sf (TFtype arg_a)
161348fb7bfaSmrg {
161448fb7bfaSmrg   fp_number_type in;
161548fb7bfaSmrg   USItype sffrac;
161648fb7bfaSmrg   FLO_union_type au;
161748fb7bfaSmrg 
161848fb7bfaSmrg   au.value = arg_a;
161948fb7bfaSmrg   unpack_d (&au, &in);
162048fb7bfaSmrg 
162148fb7bfaSmrg   sffrac = in.fraction.ll >> F_T_BITOFF;
162248fb7bfaSmrg 
162348fb7bfaSmrg   /* We set the lowest guard bit in SFFRAC if we discarded any non
162448fb7bfaSmrg      zero bits.  */
162548fb7bfaSmrg   if ((in.fraction.ll & (((UTItype) 1 << F_T_BITOFF) - 1)) != 0)
162648fb7bfaSmrg     sffrac |= 1;
162748fb7bfaSmrg 
162848fb7bfaSmrg   return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
162948fb7bfaSmrg }
163048fb7bfaSmrg #endif /* L_tf_to_sf */
163148fb7bfaSmrg #endif /* TFLOAT */
163248fb7bfaSmrg 
163348fb7bfaSmrg #endif /* ! FLOAT */
163448fb7bfaSmrg #endif /* !EXTENDED_FLOAT_STUBS */
1635