xref: /netbsd-src/external/gpl3/gcc.old/dist/libgcc/fp-bit.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
11debfc3dSmrg /* This is a software floating point library which can be used
21debfc3dSmrg    for targets without hardware floating point.
3*8feb0f0bSmrg    Copyright (C) 1994-2020 Free Software Foundation, Inc.
41debfc3dSmrg 
51debfc3dSmrg This file is part of GCC.
61debfc3dSmrg 
71debfc3dSmrg GCC is free software; you can redistribute it and/or modify it under
81debfc3dSmrg the terms of the GNU General Public License as published by the Free
91debfc3dSmrg Software Foundation; either version 3, or (at your option) any later
101debfc3dSmrg version.
111debfc3dSmrg 
121debfc3dSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
131debfc3dSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
141debfc3dSmrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
151debfc3dSmrg for more details.
161debfc3dSmrg 
171debfc3dSmrg Under Section 7 of GPL version 3, you are granted additional
181debfc3dSmrg permissions described in the GCC Runtime Library Exception, version
191debfc3dSmrg 3.1, as published by the Free Software Foundation.
201debfc3dSmrg 
211debfc3dSmrg You should have received a copy of the GNU General Public License and
221debfc3dSmrg a copy of the GCC Runtime Library Exception along with this program;
231debfc3dSmrg see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
241debfc3dSmrg <http://www.gnu.org/licenses/>.  */
251debfc3dSmrg 
261debfc3dSmrg /* This implements IEEE 754 format arithmetic, but does not provide a
271debfc3dSmrg    mechanism for setting the rounding mode, or for generating or handling
281debfc3dSmrg    exceptions.
291debfc3dSmrg 
301debfc3dSmrg    The original code by Steve Chamberlain, hacked by Mark Eichin and Jim
311debfc3dSmrg    Wilson, all of Cygnus Support.  */
321debfc3dSmrg 
331debfc3dSmrg /* The intended way to use this file is to make two copies, add `#define FLOAT'
341debfc3dSmrg    to one copy, then compile both copies and add them to libgcc.a.  */
351debfc3dSmrg 
361debfc3dSmrg #include "tconfig.h"
371debfc3dSmrg #include "coretypes.h"
381debfc3dSmrg #include "tm.h"
391debfc3dSmrg #include "libgcc_tm.h"
401debfc3dSmrg #include "fp-bit.h"
411debfc3dSmrg 
421debfc3dSmrg /* The following macros can be defined to change the behavior of this file:
431debfc3dSmrg    FLOAT: Implement a `float', aka SFmode, fp library.  If this is not
441debfc3dSmrg      defined, then this file implements a `double', aka DFmode, fp library.
451debfc3dSmrg    FLOAT_ONLY: Used with FLOAT, to implement a `float' only library, i.e.
461debfc3dSmrg      don't include float->double conversion which requires the double library.
471debfc3dSmrg      This is useful only for machines which can't support doubles, e.g. some
481debfc3dSmrg      8-bit processors.
491debfc3dSmrg    CMPtype: Specify the type that floating point compares should return.
501debfc3dSmrg      This defaults to SItype, aka int.
511debfc3dSmrg    _DEBUG_BITFLOAT: This makes debugging the code a little easier, by adding
521debfc3dSmrg      two integers to the FLO_union_type.
531debfc3dSmrg    NO_DENORMALS: Disable handling of denormals.
541debfc3dSmrg    NO_NANS: Disable nan and infinity handling
551debfc3dSmrg    SMALL_MACHINE: Useful when operations on QIs and HIs are faster
561debfc3dSmrg      than on an SI */
571debfc3dSmrg 
581debfc3dSmrg /* We don't currently support extended floats (long doubles) on machines
591debfc3dSmrg    without hardware to deal with them.
601debfc3dSmrg 
611debfc3dSmrg    These stubs are just to keep the linker from complaining about unresolved
621debfc3dSmrg    references which can be pulled in from libio & libstdc++, even if the
631debfc3dSmrg    user isn't using long doubles.  However, they may generate an unresolved
641debfc3dSmrg    external to abort if abort is not used by the function, and the stubs
651debfc3dSmrg    are referenced from within libc, since libgcc goes before and after the
661debfc3dSmrg    system library.  */
671debfc3dSmrg 
681debfc3dSmrg #ifdef DECLARE_LIBRARY_RENAMES
691debfc3dSmrg   DECLARE_LIBRARY_RENAMES
701debfc3dSmrg #endif
711debfc3dSmrg 
721debfc3dSmrg #ifdef EXTENDED_FLOAT_STUBS
731debfc3dSmrg extern void abort (void);
__extendsfxf2(void)741debfc3dSmrg void __extendsfxf2 (void) { abort(); }
__extenddfxf2(void)751debfc3dSmrg void __extenddfxf2 (void) { abort(); }
__truncxfdf2(void)761debfc3dSmrg void __truncxfdf2 (void) { abort(); }
__truncxfsf2(void)771debfc3dSmrg void __truncxfsf2 (void) { abort(); }
__fixxfsi(void)781debfc3dSmrg void __fixxfsi (void) { abort(); }
__floatsixf(void)791debfc3dSmrg void __floatsixf (void) { abort(); }
__addxf3(void)801debfc3dSmrg void __addxf3 (void) { abort(); }
__subxf3(void)811debfc3dSmrg void __subxf3 (void) { abort(); }
__mulxf3(void)821debfc3dSmrg void __mulxf3 (void) { abort(); }
__divxf3(void)831debfc3dSmrg void __divxf3 (void) { abort(); }
__negxf2(void)841debfc3dSmrg void __negxf2 (void) { abort(); }
__eqxf2(void)851debfc3dSmrg void __eqxf2 (void) { abort(); }
__nexf2(void)861debfc3dSmrg void __nexf2 (void) { abort(); }
__gtxf2(void)871debfc3dSmrg void __gtxf2 (void) { abort(); }
__gexf2(void)881debfc3dSmrg void __gexf2 (void) { abort(); }
__lexf2(void)891debfc3dSmrg void __lexf2 (void) { abort(); }
__ltxf2(void)901debfc3dSmrg void __ltxf2 (void) { abort(); }
911debfc3dSmrg 
__extendsftf2(void)921debfc3dSmrg void __extendsftf2 (void) { abort(); }
__extenddftf2(void)931debfc3dSmrg void __extenddftf2 (void) { abort(); }
__trunctfdf2(void)941debfc3dSmrg void __trunctfdf2 (void) { abort(); }
__trunctfsf2(void)951debfc3dSmrg void __trunctfsf2 (void) { abort(); }
__fixtfsi(void)961debfc3dSmrg void __fixtfsi (void) { abort(); }
__floatsitf(void)971debfc3dSmrg void __floatsitf (void) { abort(); }
__addtf3(void)981debfc3dSmrg void __addtf3 (void) { abort(); }
__subtf3(void)991debfc3dSmrg void __subtf3 (void) { abort(); }
__multf3(void)1001debfc3dSmrg void __multf3 (void) { abort(); }
__divtf3(void)1011debfc3dSmrg void __divtf3 (void) { abort(); }
__negtf2(void)1021debfc3dSmrg void __negtf2 (void) { abort(); }
__eqtf2(void)1031debfc3dSmrg void __eqtf2 (void) { abort(); }
__netf2(void)1041debfc3dSmrg void __netf2 (void) { abort(); }
__gttf2(void)1051debfc3dSmrg void __gttf2 (void) { abort(); }
__getf2(void)1061debfc3dSmrg void __getf2 (void) { abort(); }
__letf2(void)1071debfc3dSmrg void __letf2 (void) { abort(); }
__lttf2(void)1081debfc3dSmrg void __lttf2 (void) { abort(); }
1091debfc3dSmrg #else	/* !EXTENDED_FLOAT_STUBS, rest of file */
1101debfc3dSmrg 
1111debfc3dSmrg /* IEEE "special" number predicates */
1121debfc3dSmrg 
1131debfc3dSmrg #ifdef NO_NANS
1141debfc3dSmrg 
1151debfc3dSmrg #define nan() 0
1161debfc3dSmrg #define isnan(x) 0
1171debfc3dSmrg #define isinf(x) 0
1181debfc3dSmrg #else
1191debfc3dSmrg 
1201debfc3dSmrg #if   defined L_thenan_sf
1211debfc3dSmrg const fp_number_type __thenan_sf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
1221debfc3dSmrg #elif defined L_thenan_df
1231debfc3dSmrg const fp_number_type __thenan_df = { CLASS_SNAN, 0, 0, {(fractype) 0} };
1241debfc3dSmrg #elif defined L_thenan_tf
1251debfc3dSmrg const fp_number_type __thenan_tf = { CLASS_SNAN, 0, 0, {(fractype) 0} };
1261debfc3dSmrg #elif defined TFLOAT
1271debfc3dSmrg extern const fp_number_type __thenan_tf;
1281debfc3dSmrg #elif defined FLOAT
1291debfc3dSmrg extern const fp_number_type __thenan_sf;
1301debfc3dSmrg #else
1311debfc3dSmrg extern const fp_number_type __thenan_df;
1321debfc3dSmrg #endif
1331debfc3dSmrg 
1341debfc3dSmrg INLINE
1351debfc3dSmrg static const fp_number_type *
1361debfc3dSmrg makenan (void)
1371debfc3dSmrg {
1381debfc3dSmrg #ifdef TFLOAT
1391debfc3dSmrg   return & __thenan_tf;
1401debfc3dSmrg #elif defined FLOAT
1411debfc3dSmrg   return & __thenan_sf;
1421debfc3dSmrg #else
1431debfc3dSmrg   return & __thenan_df;
1441debfc3dSmrg #endif
1451debfc3dSmrg }
1461debfc3dSmrg 
1471debfc3dSmrg INLINE
1481debfc3dSmrg static int
1491debfc3dSmrg isnan (const fp_number_type *x)
1501debfc3dSmrg {
1511debfc3dSmrg   return __builtin_expect (x->class == CLASS_SNAN || x->class == CLASS_QNAN,
1521debfc3dSmrg 			   0);
1531debfc3dSmrg }
1541debfc3dSmrg 
1551debfc3dSmrg INLINE
1561debfc3dSmrg static int
1571debfc3dSmrg isinf (const fp_number_type *  x)
1581debfc3dSmrg {
1591debfc3dSmrg   return __builtin_expect (x->class == CLASS_INFINITY, 0);
1601debfc3dSmrg }
1611debfc3dSmrg 
1621debfc3dSmrg #endif /* NO_NANS */
1631debfc3dSmrg 
1641debfc3dSmrg INLINE
1651debfc3dSmrg static int
1661debfc3dSmrg iszero (const fp_number_type *  x)
1671debfc3dSmrg {
1681debfc3dSmrg   return x->class == CLASS_ZERO;
1691debfc3dSmrg }
1701debfc3dSmrg 
1711debfc3dSmrg INLINE
1721debfc3dSmrg static void
1731debfc3dSmrg flip_sign ( fp_number_type *  x)
1741debfc3dSmrg {
1751debfc3dSmrg   x->sign = !x->sign;
1761debfc3dSmrg }
1771debfc3dSmrg 
1781debfc3dSmrg /* Count leading zeroes in N.  */
1791debfc3dSmrg INLINE
1801debfc3dSmrg static int
1811debfc3dSmrg clzusi (USItype n)
1821debfc3dSmrg {
1831debfc3dSmrg   extern int __clzsi2 (USItype);
1841debfc3dSmrg   if (sizeof (USItype) == sizeof (unsigned int))
1851debfc3dSmrg     return __builtin_clz (n);
1861debfc3dSmrg   else if (sizeof (USItype) == sizeof (unsigned long))
1871debfc3dSmrg     return __builtin_clzl (n);
1881debfc3dSmrg   else if (sizeof (USItype) == sizeof (unsigned long long))
1891debfc3dSmrg     return __builtin_clzll (n);
1901debfc3dSmrg   else
1911debfc3dSmrg     return __clzsi2 (n);
1921debfc3dSmrg }
1931debfc3dSmrg 
1941debfc3dSmrg extern FLO_type pack_d (const fp_number_type * );
1951debfc3dSmrg 
1961debfc3dSmrg #if defined(L_pack_df) || defined(L_pack_sf) || defined(L_pack_tf)
1971debfc3dSmrg FLO_type
1981debfc3dSmrg pack_d (const fp_number_type *src)
1991debfc3dSmrg {
2001debfc3dSmrg   FLO_union_type dst;
2011debfc3dSmrg   fractype fraction = src->fraction.ll;	/* wasn't unsigned before? */
2021debfc3dSmrg   int sign = src->sign;
2031debfc3dSmrg   int exp = 0;
2041debfc3dSmrg 
2051debfc3dSmrg   if (isnan (src))
2061debfc3dSmrg     {
2071debfc3dSmrg       exp = EXPMAX;
2081debfc3dSmrg       /* Restore the NaN's payload.  */
2091debfc3dSmrg       fraction >>= NGARDS;
2101debfc3dSmrg       fraction &= QUIET_NAN - 1;
2111debfc3dSmrg       if (src->class == CLASS_QNAN || 1)
2121debfc3dSmrg 	{
2131debfc3dSmrg #ifdef QUIET_NAN_NEGATED
2141debfc3dSmrg 	  /* The quiet/signaling bit remains unset.  */
2151debfc3dSmrg 	  /* Make sure the fraction has a non-zero value.  */
2161debfc3dSmrg 	  if (fraction == 0)
2171debfc3dSmrg 	    fraction |= QUIET_NAN - 1;
2181debfc3dSmrg #else
2191debfc3dSmrg 	  /* Set the quiet/signaling bit.  */
2201debfc3dSmrg 	  fraction |= QUIET_NAN;
2211debfc3dSmrg #endif
2221debfc3dSmrg 	}
2231debfc3dSmrg     }
2241debfc3dSmrg   else if (isinf (src))
2251debfc3dSmrg     {
2261debfc3dSmrg       exp = EXPMAX;
2271debfc3dSmrg       fraction = 0;
2281debfc3dSmrg     }
2291debfc3dSmrg   else if (iszero (src))
2301debfc3dSmrg     {
2311debfc3dSmrg       exp = 0;
2321debfc3dSmrg       fraction = 0;
2331debfc3dSmrg     }
2341debfc3dSmrg   else if (fraction == 0)
2351debfc3dSmrg     {
2361debfc3dSmrg       exp = 0;
2371debfc3dSmrg     }
2381debfc3dSmrg   else
2391debfc3dSmrg     {
2401debfc3dSmrg       if (__builtin_expect (src->normal_exp < NORMAL_EXPMIN, 0))
2411debfc3dSmrg 	{
2421debfc3dSmrg #ifdef NO_DENORMALS
2431debfc3dSmrg 	  /* Go straight to a zero representation if denormals are not
2441debfc3dSmrg  	     supported.  The denormal handling would be harmless but
2451debfc3dSmrg  	     isn't unnecessary.  */
2461debfc3dSmrg 	  exp = 0;
2471debfc3dSmrg 	  fraction = 0;
2481debfc3dSmrg #else /* NO_DENORMALS */
2491debfc3dSmrg 	  /* This number's exponent is too low to fit into the bits
2501debfc3dSmrg 	     available in the number, so we'll store 0 in the exponent and
2511debfc3dSmrg 	     shift the fraction to the right to make up for it.  */
2521debfc3dSmrg 
2531debfc3dSmrg 	  int shift = NORMAL_EXPMIN - src->normal_exp;
2541debfc3dSmrg 
2551debfc3dSmrg 	  exp = 0;
2561debfc3dSmrg 
2571debfc3dSmrg 	  if (shift > FRAC_NBITS - NGARDS)
2581debfc3dSmrg 	    {
2591debfc3dSmrg 	      /* No point shifting, since it's more that 64 out.  */
2601debfc3dSmrg 	      fraction = 0;
2611debfc3dSmrg 	    }
2621debfc3dSmrg 	  else
2631debfc3dSmrg 	    {
2641debfc3dSmrg 	      int lowbit = (fraction & (((fractype)1 << shift) - 1)) ? 1 : 0;
2651debfc3dSmrg 	      fraction = (fraction >> shift) | lowbit;
2661debfc3dSmrg 	    }
2671debfc3dSmrg 	  if ((fraction & GARDMASK) == GARDMSB)
2681debfc3dSmrg 	    {
2691debfc3dSmrg 	      if ((fraction & (1 << NGARDS)))
2701debfc3dSmrg 		fraction += GARDROUND + 1;
2711debfc3dSmrg 	    }
2721debfc3dSmrg 	  else
2731debfc3dSmrg 	    {
2741debfc3dSmrg 	      /* Add to the guards to round up.  */
2751debfc3dSmrg 	      fraction += GARDROUND;
2761debfc3dSmrg 	    }
2771debfc3dSmrg 	  /* Perhaps the rounding means we now need to change the
2781debfc3dSmrg              exponent, because the fraction is no longer denormal.  */
2791debfc3dSmrg 	  if (fraction >= IMPLICIT_1)
2801debfc3dSmrg 	    {
2811debfc3dSmrg 	      exp += 1;
2821debfc3dSmrg 	    }
2831debfc3dSmrg 	  fraction >>= NGARDS;
2841debfc3dSmrg #endif /* NO_DENORMALS */
2851debfc3dSmrg 	}
2861debfc3dSmrg       else if (__builtin_expect (src->normal_exp > EXPBIAS, 0))
2871debfc3dSmrg 	{
2881debfc3dSmrg 	  exp = EXPMAX;
2891debfc3dSmrg 	  fraction = 0;
2901debfc3dSmrg 	}
2911debfc3dSmrg       else
2921debfc3dSmrg 	{
2931debfc3dSmrg 	  exp = src->normal_exp + EXPBIAS;
2941debfc3dSmrg 	  /* IF the gard bits are the all zero, but the first, then we're
2951debfc3dSmrg 	     half way between two numbers, choose the one which makes the
2961debfc3dSmrg 	     lsb of the answer 0.  */
2971debfc3dSmrg 	  if ((fraction & GARDMASK) == GARDMSB)
2981debfc3dSmrg 	    {
2991debfc3dSmrg 	      if (fraction & (1 << NGARDS))
3001debfc3dSmrg 		fraction += GARDROUND + 1;
3011debfc3dSmrg 	    }
3021debfc3dSmrg 	  else
3031debfc3dSmrg 	    {
3041debfc3dSmrg 	      /* Add a one to the guards to round up */
3051debfc3dSmrg 	      fraction += GARDROUND;
3061debfc3dSmrg 	    }
3071debfc3dSmrg 	  if (fraction >= IMPLICIT_2)
3081debfc3dSmrg 	    {
3091debfc3dSmrg 	      fraction >>= 1;
3101debfc3dSmrg 	      exp += 1;
3111debfc3dSmrg 	    }
3121debfc3dSmrg 	  fraction >>= NGARDS;
3131debfc3dSmrg 	}
3141debfc3dSmrg     }
3151debfc3dSmrg 
3161debfc3dSmrg   /* We previously used bitfields to store the number, but this doesn't
3171debfc3dSmrg      handle little/big endian systems conveniently, so use shifts and
3181debfc3dSmrg      masks */
3191debfc3dSmrg #if defined TFLOAT && defined HALFFRACBITS
3201debfc3dSmrg  {
3211debfc3dSmrg    halffractype high, low, unity;
3221debfc3dSmrg    int lowsign, lowexp;
3231debfc3dSmrg 
3241debfc3dSmrg    unity = (halffractype) 1 << HALFFRACBITS;
3251debfc3dSmrg 
3261debfc3dSmrg    /* Set HIGH to the high double's significand, masking out the implicit 1.
3271debfc3dSmrg       Set LOW to the low double's full significand.  */
3281debfc3dSmrg    high = (fraction >> (FRACBITS - HALFFRACBITS)) & (unity - 1);
3291debfc3dSmrg    low = fraction & (unity * 2 - 1);
3301debfc3dSmrg 
3311debfc3dSmrg    /* Get the initial sign and exponent of the low double.  */
3321debfc3dSmrg    lowexp = exp - HALFFRACBITS - 1;
3331debfc3dSmrg    lowsign = sign;
3341debfc3dSmrg 
3351debfc3dSmrg    /* HIGH should be rounded like a normal double, making |LOW| <=
3361debfc3dSmrg       0.5 ULP of HIGH.  Assume round-to-nearest.  */
3371debfc3dSmrg    if (exp < EXPMAX)
3381debfc3dSmrg      if (low > unity || (low == unity && (high & 1) == 1))
3391debfc3dSmrg        {
3401debfc3dSmrg 	 /* Round HIGH up and adjust LOW to match.  */
3411debfc3dSmrg 	 high++;
3421debfc3dSmrg 	 if (high == unity)
3431debfc3dSmrg 	   {
3441debfc3dSmrg 	     /* May make it infinite, but that's OK.  */
3451debfc3dSmrg 	     high = 0;
3461debfc3dSmrg 	     exp++;
3471debfc3dSmrg 	   }
3481debfc3dSmrg 	 low = unity * 2 - low;
3491debfc3dSmrg 	 lowsign ^= 1;
3501debfc3dSmrg        }
3511debfc3dSmrg 
3521debfc3dSmrg    high |= (halffractype) exp << HALFFRACBITS;
3531debfc3dSmrg    high |= (halffractype) sign << (HALFFRACBITS + EXPBITS);
3541debfc3dSmrg 
3551debfc3dSmrg    if (exp == EXPMAX || exp == 0 || low == 0)
3561debfc3dSmrg      low = 0;
3571debfc3dSmrg    else
3581debfc3dSmrg      {
3591debfc3dSmrg        while (lowexp > 0 && low < unity)
3601debfc3dSmrg 	 {
3611debfc3dSmrg 	   low <<= 1;
3621debfc3dSmrg 	   lowexp--;
3631debfc3dSmrg 	 }
3641debfc3dSmrg 
3651debfc3dSmrg        if (lowexp <= 0)
3661debfc3dSmrg 	 {
3671debfc3dSmrg 	   halffractype roundmsb, round;
3681debfc3dSmrg 	   int shift;
3691debfc3dSmrg 
3701debfc3dSmrg 	   shift = 1 - lowexp;
3711debfc3dSmrg 	   roundmsb = (1 << (shift - 1));
3721debfc3dSmrg 	   round = low & ((roundmsb << 1) - 1);
3731debfc3dSmrg 
3741debfc3dSmrg 	   low >>= shift;
3751debfc3dSmrg 	   lowexp = 0;
3761debfc3dSmrg 
3771debfc3dSmrg 	   if (round > roundmsb || (round == roundmsb && (low & 1) == 1))
3781debfc3dSmrg 	     {
3791debfc3dSmrg 	       low++;
3801debfc3dSmrg 	       if (low == unity)
3811debfc3dSmrg 		 /* LOW rounds up to the smallest normal number.  */
3821debfc3dSmrg 		 lowexp++;
3831debfc3dSmrg 	     }
3841debfc3dSmrg 	 }
3851debfc3dSmrg 
3861debfc3dSmrg        low &= unity - 1;
3871debfc3dSmrg        low |= (halffractype) lowexp << HALFFRACBITS;
3881debfc3dSmrg        low |= (halffractype) lowsign << (HALFFRACBITS + EXPBITS);
3891debfc3dSmrg      }
3901debfc3dSmrg    dst.value_raw = ((fractype) high << HALFSHIFT) | low;
3911debfc3dSmrg  }
3921debfc3dSmrg #else
3931debfc3dSmrg   dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1);
3941debfc3dSmrg   dst.value_raw |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << FRACBITS;
3951debfc3dSmrg   dst.value_raw |= ((fractype) (sign & 1)) << (FRACBITS | EXPBITS);
3961debfc3dSmrg #endif
3971debfc3dSmrg 
3981debfc3dSmrg #if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
3991debfc3dSmrg #ifdef TFLOAT
4001debfc3dSmrg   {
4011debfc3dSmrg     qrtrfractype tmp1 = dst.words[0];
4021debfc3dSmrg     qrtrfractype tmp2 = dst.words[1];
4031debfc3dSmrg     dst.words[0] = dst.words[3];
4041debfc3dSmrg     dst.words[1] = dst.words[2];
4051debfc3dSmrg     dst.words[2] = tmp2;
4061debfc3dSmrg     dst.words[3] = tmp1;
4071debfc3dSmrg   }
4081debfc3dSmrg #else
4091debfc3dSmrg   {
4101debfc3dSmrg     halffractype tmp = dst.words[0];
4111debfc3dSmrg     dst.words[0] = dst.words[1];
4121debfc3dSmrg     dst.words[1] = tmp;
4131debfc3dSmrg   }
4141debfc3dSmrg #endif
4151debfc3dSmrg #endif
4161debfc3dSmrg 
4171debfc3dSmrg   return dst.value;
4181debfc3dSmrg }
4191debfc3dSmrg #endif
4201debfc3dSmrg 
4211debfc3dSmrg #if defined(L_unpack_df) || defined(L_unpack_sf) || defined(L_unpack_tf)
4221debfc3dSmrg void
4231debfc3dSmrg unpack_d (FLO_union_type * src, fp_number_type * dst)
4241debfc3dSmrg {
4251debfc3dSmrg   /* We previously used bitfields to store the number, but this doesn't
4261debfc3dSmrg      handle little/big endian systems conveniently, so use shifts and
4271debfc3dSmrg      masks */
4281debfc3dSmrg   fractype fraction;
4291debfc3dSmrg   int exp;
4301debfc3dSmrg   int sign;
4311debfc3dSmrg 
4321debfc3dSmrg #if defined(FLOAT_WORD_ORDER_MISMATCH) && !defined(FLOAT)
4331debfc3dSmrg   FLO_union_type swapped;
4341debfc3dSmrg 
4351debfc3dSmrg #ifdef TFLOAT
4361debfc3dSmrg   swapped.words[0] = src->words[3];
4371debfc3dSmrg   swapped.words[1] = src->words[2];
4381debfc3dSmrg   swapped.words[2] = src->words[1];
4391debfc3dSmrg   swapped.words[3] = src->words[0];
4401debfc3dSmrg #else
4411debfc3dSmrg   swapped.words[0] = src->words[1];
4421debfc3dSmrg   swapped.words[1] = src->words[0];
4431debfc3dSmrg #endif
4441debfc3dSmrg   src = &swapped;
4451debfc3dSmrg #endif
4461debfc3dSmrg 
4471debfc3dSmrg #if defined TFLOAT && defined HALFFRACBITS
4481debfc3dSmrg  {
4491debfc3dSmrg    halffractype high, low;
4501debfc3dSmrg 
4511debfc3dSmrg    high = src->value_raw >> HALFSHIFT;
4521debfc3dSmrg    low = src->value_raw & (((fractype)1 << HALFSHIFT) - 1);
4531debfc3dSmrg 
4541debfc3dSmrg    fraction = high & ((((fractype)1) << HALFFRACBITS) - 1);
4551debfc3dSmrg    fraction <<= FRACBITS - HALFFRACBITS;
4561debfc3dSmrg    exp = ((int)(high >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
4571debfc3dSmrg    sign = ((int)(high >> (((HALFFRACBITS + EXPBITS))))) & 1;
4581debfc3dSmrg 
4591debfc3dSmrg    if (exp != EXPMAX && exp != 0 && low != 0)
4601debfc3dSmrg      {
4611debfc3dSmrg        int lowexp = ((int)(low >> HALFFRACBITS)) & ((1 << EXPBITS) - 1);
4621debfc3dSmrg        int lowsign = ((int)(low >> (((HALFFRACBITS + EXPBITS))))) & 1;
4631debfc3dSmrg        int shift;
4641debfc3dSmrg        fractype xlow;
4651debfc3dSmrg 
4661debfc3dSmrg        xlow = low & ((((fractype)1) << HALFFRACBITS) - 1);
4671debfc3dSmrg        if (lowexp)
4681debfc3dSmrg 	 xlow |= (((halffractype)1) << HALFFRACBITS);
4691debfc3dSmrg        else
4701debfc3dSmrg 	 lowexp = 1;
4711debfc3dSmrg        shift = (FRACBITS - HALFFRACBITS) - (exp - lowexp);
4721debfc3dSmrg        if (shift > 0)
4731debfc3dSmrg 	 xlow <<= shift;
4741debfc3dSmrg        else if (shift < 0)
4751debfc3dSmrg 	 xlow >>= -shift;
4761debfc3dSmrg        if (sign == lowsign)
4771debfc3dSmrg 	 fraction += xlow;
4781debfc3dSmrg        else if (fraction >= xlow)
4791debfc3dSmrg 	 fraction -= xlow;
4801debfc3dSmrg        else
4811debfc3dSmrg 	 {
4821debfc3dSmrg 	   /* The high part is a power of two but the full number is lower.
4831debfc3dSmrg 	      This code will leave the implicit 1 in FRACTION, but we'd
4841debfc3dSmrg 	      have added that below anyway.  */
4851debfc3dSmrg 	   fraction = (((fractype) 1 << FRACBITS) - xlow) << 1;
4861debfc3dSmrg 	   exp--;
4871debfc3dSmrg 	 }
4881debfc3dSmrg      }
4891debfc3dSmrg  }
4901debfc3dSmrg #else
4911debfc3dSmrg   fraction = src->value_raw & ((((fractype)1) << FRACBITS) - 1);
4921debfc3dSmrg   exp = ((int)(src->value_raw >> FRACBITS)) & ((1 << EXPBITS) - 1);
4931debfc3dSmrg   sign = ((int)(src->value_raw >> (FRACBITS + EXPBITS))) & 1;
4941debfc3dSmrg #endif
4951debfc3dSmrg 
4961debfc3dSmrg   dst->sign = sign;
4971debfc3dSmrg   if (exp == 0)
4981debfc3dSmrg     {
4991debfc3dSmrg       /* Hmm.  Looks like 0 */
5001debfc3dSmrg       if (fraction == 0
5011debfc3dSmrg #ifdef NO_DENORMALS
5021debfc3dSmrg 	  || 1
5031debfc3dSmrg #endif
5041debfc3dSmrg 	  )
5051debfc3dSmrg 	{
5061debfc3dSmrg 	  /* tastes like zero */
5071debfc3dSmrg 	  dst->class = CLASS_ZERO;
5081debfc3dSmrg 	}
5091debfc3dSmrg       else
5101debfc3dSmrg 	{
5111debfc3dSmrg 	  /* Zero exponent with nonzero fraction - it's denormalized,
5121debfc3dSmrg 	     so there isn't a leading implicit one - we'll shift it so
5131debfc3dSmrg 	     it gets one.  */
5141debfc3dSmrg 	  dst->normal_exp = exp - EXPBIAS + 1;
5151debfc3dSmrg 	  fraction <<= NGARDS;
5161debfc3dSmrg 
5171debfc3dSmrg 	  dst->class = CLASS_NUMBER;
5181debfc3dSmrg #if 1
5191debfc3dSmrg 	  while (fraction < IMPLICIT_1)
5201debfc3dSmrg 	    {
5211debfc3dSmrg 	      fraction <<= 1;
5221debfc3dSmrg 	      dst->normal_exp--;
5231debfc3dSmrg 	    }
5241debfc3dSmrg #endif
5251debfc3dSmrg 	  dst->fraction.ll = fraction;
5261debfc3dSmrg 	}
5271debfc3dSmrg     }
5281debfc3dSmrg   else if (__builtin_expect (exp == EXPMAX, 0))
5291debfc3dSmrg     {
5301debfc3dSmrg       /* Huge exponent*/
5311debfc3dSmrg       if (fraction == 0)
5321debfc3dSmrg 	{
5331debfc3dSmrg 	  /* Attached to a zero fraction - means infinity */
5341debfc3dSmrg 	  dst->class = CLASS_INFINITY;
5351debfc3dSmrg 	}
5361debfc3dSmrg       else
5371debfc3dSmrg 	{
5381debfc3dSmrg 	  /* Nonzero fraction, means nan */
5391debfc3dSmrg #ifdef QUIET_NAN_NEGATED
5401debfc3dSmrg 	  if ((fraction & QUIET_NAN) == 0)
5411debfc3dSmrg #else
5421debfc3dSmrg 	  if (fraction & QUIET_NAN)
5431debfc3dSmrg #endif
5441debfc3dSmrg 	    {
5451debfc3dSmrg 	      dst->class = CLASS_QNAN;
5461debfc3dSmrg 	    }
5471debfc3dSmrg 	  else
5481debfc3dSmrg 	    {
5491debfc3dSmrg 	      dst->class = CLASS_SNAN;
5501debfc3dSmrg 	    }
5511debfc3dSmrg 	  /* Now that we know which kind of NaN we got, discard the
5521debfc3dSmrg 	     quiet/signaling bit, but do preserve the NaN payload.  */
5531debfc3dSmrg 	  fraction &= ~QUIET_NAN;
5541debfc3dSmrg 	  dst->fraction.ll = fraction << NGARDS;
5551debfc3dSmrg 	}
5561debfc3dSmrg     }
5571debfc3dSmrg   else
5581debfc3dSmrg     {
5591debfc3dSmrg       /* Nothing strange about this number */
5601debfc3dSmrg       dst->normal_exp = exp - EXPBIAS;
5611debfc3dSmrg       dst->class = CLASS_NUMBER;
5621debfc3dSmrg       dst->fraction.ll = (fraction << NGARDS) | IMPLICIT_1;
5631debfc3dSmrg     }
5641debfc3dSmrg }
5651debfc3dSmrg #endif /* L_unpack_df || L_unpack_sf */
5661debfc3dSmrg 
5671debfc3dSmrg #if defined(L_addsub_sf) || defined(L_addsub_df) || defined(L_addsub_tf)
5681debfc3dSmrg static const fp_number_type *
5691debfc3dSmrg _fpadd_parts (fp_number_type * a,
5701debfc3dSmrg 	      fp_number_type * b,
5711debfc3dSmrg 	      fp_number_type * tmp)
5721debfc3dSmrg {
5731debfc3dSmrg   intfrac tfraction;
5741debfc3dSmrg 
5751debfc3dSmrg   /* Put commonly used fields in local variables.  */
5761debfc3dSmrg   int a_normal_exp;
5771debfc3dSmrg   int b_normal_exp;
5781debfc3dSmrg   fractype a_fraction;
5791debfc3dSmrg   fractype b_fraction;
5801debfc3dSmrg 
5811debfc3dSmrg   if (isnan (a))
5821debfc3dSmrg     {
5831debfc3dSmrg       return a;
5841debfc3dSmrg     }
5851debfc3dSmrg   if (isnan (b))
5861debfc3dSmrg     {
5871debfc3dSmrg       return b;
5881debfc3dSmrg     }
5891debfc3dSmrg   if (isinf (a))
5901debfc3dSmrg     {
5911debfc3dSmrg       /* Adding infinities with opposite signs yields a NaN.  */
5921debfc3dSmrg       if (isinf (b) && a->sign != b->sign)
5931debfc3dSmrg 	return makenan ();
5941debfc3dSmrg       return a;
5951debfc3dSmrg     }
5961debfc3dSmrg   if (isinf (b))
5971debfc3dSmrg     {
5981debfc3dSmrg       return b;
5991debfc3dSmrg     }
6001debfc3dSmrg   if (iszero (b))
6011debfc3dSmrg     {
6021debfc3dSmrg       if (iszero (a))
6031debfc3dSmrg 	{
6041debfc3dSmrg 	  *tmp = *a;
6051debfc3dSmrg 	  tmp->sign = a->sign & b->sign;
6061debfc3dSmrg 	  return tmp;
6071debfc3dSmrg 	}
6081debfc3dSmrg       return a;
6091debfc3dSmrg     }
6101debfc3dSmrg   if (iszero (a))
6111debfc3dSmrg     {
6121debfc3dSmrg       return b;
6131debfc3dSmrg     }
6141debfc3dSmrg 
6151debfc3dSmrg   /* Got two numbers. shift the smaller and increment the exponent till
6161debfc3dSmrg      they're the same */
6171debfc3dSmrg   {
6181debfc3dSmrg     int diff;
6191debfc3dSmrg     int sdiff;
6201debfc3dSmrg 
6211debfc3dSmrg     a_normal_exp = a->normal_exp;
6221debfc3dSmrg     b_normal_exp = b->normal_exp;
6231debfc3dSmrg     a_fraction = a->fraction.ll;
6241debfc3dSmrg     b_fraction = b->fraction.ll;
6251debfc3dSmrg 
6261debfc3dSmrg     diff = a_normal_exp - b_normal_exp;
6271debfc3dSmrg     sdiff = diff;
6281debfc3dSmrg 
6291debfc3dSmrg     if (diff < 0)
6301debfc3dSmrg       diff = -diff;
6311debfc3dSmrg     if (diff < FRAC_NBITS)
6321debfc3dSmrg       {
6331debfc3dSmrg 	if (sdiff > 0)
6341debfc3dSmrg 	  {
6351debfc3dSmrg 	    b_normal_exp += diff;
6361debfc3dSmrg 	    LSHIFT (b_fraction, diff);
6371debfc3dSmrg 	  }
6381debfc3dSmrg 	else if (sdiff < 0)
6391debfc3dSmrg 	  {
6401debfc3dSmrg 	    a_normal_exp += diff;
6411debfc3dSmrg 	    LSHIFT (a_fraction, diff);
6421debfc3dSmrg 	  }
6431debfc3dSmrg       }
6441debfc3dSmrg     else
6451debfc3dSmrg       {
6461debfc3dSmrg 	/* Somethings's up.. choose the biggest */
6471debfc3dSmrg 	if (a_normal_exp > b_normal_exp)
6481debfc3dSmrg 	  {
6491debfc3dSmrg 	    b_normal_exp = a_normal_exp;
6501debfc3dSmrg 	    b_fraction = 0;
6511debfc3dSmrg 	  }
6521debfc3dSmrg 	else
6531debfc3dSmrg 	  {
6541debfc3dSmrg 	    a_normal_exp = b_normal_exp;
6551debfc3dSmrg 	    a_fraction = 0;
6561debfc3dSmrg 	  }
6571debfc3dSmrg       }
6581debfc3dSmrg   }
6591debfc3dSmrg 
6601debfc3dSmrg   if (a->sign != b->sign)
6611debfc3dSmrg     {
6621debfc3dSmrg       if (a->sign)
6631debfc3dSmrg 	{
6641debfc3dSmrg 	  tfraction = -a_fraction + b_fraction;
6651debfc3dSmrg 	}
6661debfc3dSmrg       else
6671debfc3dSmrg 	{
6681debfc3dSmrg 	  tfraction = a_fraction - b_fraction;
6691debfc3dSmrg 	}
6701debfc3dSmrg       if (tfraction >= 0)
6711debfc3dSmrg 	{
6721debfc3dSmrg 	  tmp->sign = 0;
6731debfc3dSmrg 	  tmp->normal_exp = a_normal_exp;
6741debfc3dSmrg 	  tmp->fraction.ll = tfraction;
6751debfc3dSmrg 	}
6761debfc3dSmrg       else
6771debfc3dSmrg 	{
6781debfc3dSmrg 	  tmp->sign = 1;
6791debfc3dSmrg 	  tmp->normal_exp = a_normal_exp;
6801debfc3dSmrg 	  tmp->fraction.ll = -tfraction;
6811debfc3dSmrg 	}
6821debfc3dSmrg       /* and renormalize it */
6831debfc3dSmrg 
6841debfc3dSmrg       while (tmp->fraction.ll < IMPLICIT_1 && tmp->fraction.ll)
6851debfc3dSmrg 	{
6861debfc3dSmrg 	  tmp->fraction.ll <<= 1;
6871debfc3dSmrg 	  tmp->normal_exp--;
6881debfc3dSmrg 	}
6891debfc3dSmrg     }
6901debfc3dSmrg   else
6911debfc3dSmrg     {
6921debfc3dSmrg       tmp->sign = a->sign;
6931debfc3dSmrg       tmp->normal_exp = a_normal_exp;
6941debfc3dSmrg       tmp->fraction.ll = a_fraction + b_fraction;
6951debfc3dSmrg     }
6961debfc3dSmrg   tmp->class = CLASS_NUMBER;
6971debfc3dSmrg   /* Now the fraction is added, we have to shift down to renormalize the
6981debfc3dSmrg      number */
6991debfc3dSmrg 
7001debfc3dSmrg   if (tmp->fraction.ll >= IMPLICIT_2)
7011debfc3dSmrg     {
7021debfc3dSmrg       LSHIFT (tmp->fraction.ll, 1);
7031debfc3dSmrg       tmp->normal_exp++;
7041debfc3dSmrg     }
7051debfc3dSmrg   return tmp;
7061debfc3dSmrg }
7071debfc3dSmrg 
7081debfc3dSmrg FLO_type
7091debfc3dSmrg add (FLO_type arg_a, FLO_type arg_b)
7101debfc3dSmrg {
7111debfc3dSmrg   fp_number_type a;
7121debfc3dSmrg   fp_number_type b;
7131debfc3dSmrg   fp_number_type tmp;
7141debfc3dSmrg   const fp_number_type *res;
7151debfc3dSmrg   FLO_union_type au, bu;
7161debfc3dSmrg 
7171debfc3dSmrg   au.value = arg_a;
7181debfc3dSmrg   bu.value = arg_b;
7191debfc3dSmrg 
7201debfc3dSmrg   unpack_d (&au, &a);
7211debfc3dSmrg   unpack_d (&bu, &b);
7221debfc3dSmrg 
7231debfc3dSmrg   res = _fpadd_parts (&a, &b, &tmp);
7241debfc3dSmrg 
7251debfc3dSmrg   return pack_d (res);
7261debfc3dSmrg }
7271debfc3dSmrg 
7281debfc3dSmrg FLO_type
7291debfc3dSmrg sub (FLO_type arg_a, FLO_type arg_b)
7301debfc3dSmrg {
7311debfc3dSmrg   fp_number_type a;
7321debfc3dSmrg   fp_number_type b;
7331debfc3dSmrg   fp_number_type tmp;
7341debfc3dSmrg   const fp_number_type *res;
7351debfc3dSmrg   FLO_union_type au, bu;
7361debfc3dSmrg 
7371debfc3dSmrg   au.value = arg_a;
7381debfc3dSmrg   bu.value = arg_b;
7391debfc3dSmrg 
7401debfc3dSmrg   unpack_d (&au, &a);
7411debfc3dSmrg   unpack_d (&bu, &b);
7421debfc3dSmrg 
7431debfc3dSmrg   b.sign ^= 1;
7441debfc3dSmrg 
7451debfc3dSmrg   res = _fpadd_parts (&a, &b, &tmp);
7461debfc3dSmrg 
7471debfc3dSmrg   return pack_d (res);
7481debfc3dSmrg }
7491debfc3dSmrg #endif /* L_addsub_sf || L_addsub_df */
7501debfc3dSmrg 
7511debfc3dSmrg #if defined(L_mul_sf) || defined(L_mul_df) || defined(L_mul_tf)
7521debfc3dSmrg static inline __attribute__ ((__always_inline__)) const fp_number_type *
7531debfc3dSmrg _fpmul_parts ( fp_number_type *  a,
7541debfc3dSmrg 	       fp_number_type *  b,
7551debfc3dSmrg 	       fp_number_type * tmp)
7561debfc3dSmrg {
7571debfc3dSmrg   fractype low = 0;
7581debfc3dSmrg   fractype high = 0;
7591debfc3dSmrg 
7601debfc3dSmrg   if (isnan (a))
7611debfc3dSmrg     {
7621debfc3dSmrg       a->sign = a->sign != b->sign;
7631debfc3dSmrg       return a;
7641debfc3dSmrg     }
7651debfc3dSmrg   if (isnan (b))
7661debfc3dSmrg     {
7671debfc3dSmrg       b->sign = a->sign != b->sign;
7681debfc3dSmrg       return b;
7691debfc3dSmrg     }
7701debfc3dSmrg   if (isinf (a))
7711debfc3dSmrg     {
7721debfc3dSmrg       if (iszero (b))
7731debfc3dSmrg 	return makenan ();
7741debfc3dSmrg       a->sign = a->sign != b->sign;
7751debfc3dSmrg       return a;
7761debfc3dSmrg     }
7771debfc3dSmrg   if (isinf (b))
7781debfc3dSmrg     {
7791debfc3dSmrg       if (iszero (a))
7801debfc3dSmrg 	{
7811debfc3dSmrg 	  return makenan ();
7821debfc3dSmrg 	}
7831debfc3dSmrg       b->sign = a->sign != b->sign;
7841debfc3dSmrg       return b;
7851debfc3dSmrg     }
7861debfc3dSmrg   if (iszero (a))
7871debfc3dSmrg     {
7881debfc3dSmrg       a->sign = a->sign != b->sign;
7891debfc3dSmrg       return a;
7901debfc3dSmrg     }
7911debfc3dSmrg   if (iszero (b))
7921debfc3dSmrg     {
7931debfc3dSmrg       b->sign = a->sign != b->sign;
7941debfc3dSmrg       return b;
7951debfc3dSmrg     }
7961debfc3dSmrg 
7971debfc3dSmrg   /* Calculate the mantissa by multiplying both numbers to get a
7981debfc3dSmrg      twice-as-wide number.  */
7991debfc3dSmrg   {
8001debfc3dSmrg #if defined(NO_DI_MODE) || defined(TFLOAT)
8011debfc3dSmrg     {
8021debfc3dSmrg       fractype x = a->fraction.ll;
8031debfc3dSmrg       fractype ylow = b->fraction.ll;
8041debfc3dSmrg       fractype yhigh = 0;
8051debfc3dSmrg       int bit;
8061debfc3dSmrg 
8071debfc3dSmrg       /* ??? This does multiplies one bit at a time.  Optimize.  */
8081debfc3dSmrg       for (bit = 0; bit < FRAC_NBITS; bit++)
8091debfc3dSmrg 	{
8101debfc3dSmrg 	  int carry;
8111debfc3dSmrg 
8121debfc3dSmrg 	  if (x & 1)
8131debfc3dSmrg 	    {
8141debfc3dSmrg 	      carry = (low += ylow) < ylow;
8151debfc3dSmrg 	      high += yhigh + carry;
8161debfc3dSmrg 	    }
8171debfc3dSmrg 	  yhigh <<= 1;
8181debfc3dSmrg 	  if (ylow & FRACHIGH)
8191debfc3dSmrg 	    {
8201debfc3dSmrg 	      yhigh |= 1;
8211debfc3dSmrg 	    }
8221debfc3dSmrg 	  ylow <<= 1;
8231debfc3dSmrg 	  x >>= 1;
8241debfc3dSmrg 	}
8251debfc3dSmrg     }
8261debfc3dSmrg #elif defined(FLOAT)
8271debfc3dSmrg     /* Multiplying two USIs to get a UDI, we're safe.  */
8281debfc3dSmrg     {
8291debfc3dSmrg       UDItype answer = (UDItype)a->fraction.ll * (UDItype)b->fraction.ll;
8301debfc3dSmrg 
8311debfc3dSmrg       high = answer >> BITS_PER_SI;
8321debfc3dSmrg       low = answer;
8331debfc3dSmrg     }
8341debfc3dSmrg #else
8351debfc3dSmrg     /* fractype is DImode, but we need the result to be twice as wide.
8361debfc3dSmrg        Assuming a widening multiply from DImode to TImode is not
8371debfc3dSmrg        available, build one by hand.  */
8381debfc3dSmrg     {
8391debfc3dSmrg       USItype nl = a->fraction.ll;
8401debfc3dSmrg       USItype nh = a->fraction.ll >> BITS_PER_SI;
8411debfc3dSmrg       USItype ml = b->fraction.ll;
8421debfc3dSmrg       USItype mh = b->fraction.ll >> BITS_PER_SI;
8431debfc3dSmrg       UDItype pp_ll = (UDItype) ml * nl;
8441debfc3dSmrg       UDItype pp_hl = (UDItype) mh * nl;
8451debfc3dSmrg       UDItype pp_lh = (UDItype) ml * nh;
8461debfc3dSmrg       UDItype pp_hh = (UDItype) mh * nh;
8471debfc3dSmrg       UDItype res2 = 0;
8481debfc3dSmrg       UDItype res0 = 0;
8491debfc3dSmrg       UDItype ps_hh__ = pp_hl + pp_lh;
8501debfc3dSmrg       if (ps_hh__ < pp_hl)
8511debfc3dSmrg 	res2 += (UDItype)1 << BITS_PER_SI;
8521debfc3dSmrg       pp_hl = (UDItype)(USItype)ps_hh__ << BITS_PER_SI;
8531debfc3dSmrg       res0 = pp_ll + pp_hl;
8541debfc3dSmrg       if (res0 < pp_ll)
8551debfc3dSmrg 	res2++;
8561debfc3dSmrg       res2 += (ps_hh__ >> BITS_PER_SI) + pp_hh;
8571debfc3dSmrg       high = res2;
8581debfc3dSmrg       low = res0;
8591debfc3dSmrg     }
8601debfc3dSmrg #endif
8611debfc3dSmrg   }
8621debfc3dSmrg 
8631debfc3dSmrg   tmp->normal_exp = a->normal_exp + b->normal_exp
8641debfc3dSmrg     + FRAC_NBITS - (FRACBITS + NGARDS);
8651debfc3dSmrg   tmp->sign = a->sign != b->sign;
8661debfc3dSmrg   while (high >= IMPLICIT_2)
8671debfc3dSmrg     {
8681debfc3dSmrg       tmp->normal_exp++;
8691debfc3dSmrg       if (high & 1)
8701debfc3dSmrg 	{
8711debfc3dSmrg 	  low >>= 1;
8721debfc3dSmrg 	  low |= FRACHIGH;
8731debfc3dSmrg 	}
8741debfc3dSmrg       high >>= 1;
8751debfc3dSmrg     }
8761debfc3dSmrg   while (high < IMPLICIT_1)
8771debfc3dSmrg     {
8781debfc3dSmrg       tmp->normal_exp--;
8791debfc3dSmrg 
8801debfc3dSmrg       high <<= 1;
8811debfc3dSmrg       if (low & FRACHIGH)
8821debfc3dSmrg 	high |= 1;
8831debfc3dSmrg       low <<= 1;
8841debfc3dSmrg     }
8851debfc3dSmrg 
8861debfc3dSmrg   if ((high & GARDMASK) == GARDMSB)
8871debfc3dSmrg     {
8881debfc3dSmrg       if (high & (1 << NGARDS))
8891debfc3dSmrg 	{
8901debfc3dSmrg 	  /* Because we're half way, we would round to even by adding
8911debfc3dSmrg 	     GARDROUND + 1, except that's also done in the packing
8921debfc3dSmrg 	     function, and rounding twice will lose precision and cause
8931debfc3dSmrg 	     the result to be too far off.  Example: 32-bit floats with
8941debfc3dSmrg 	     bit patterns 0xfff * 0x3f800400 ~= 0xfff (less than 0.5ulp
8951debfc3dSmrg 	     off), not 0x1000 (more than 0.5ulp off).  */
8961debfc3dSmrg 	}
8971debfc3dSmrg       else if (low)
8981debfc3dSmrg 	{
8991debfc3dSmrg 	  /* We're a further than half way by a small amount corresponding
9001debfc3dSmrg 	     to the bits set in "low".  Knowing that, we round here and
9011debfc3dSmrg 	     not in pack_d, because there we don't have "low" available
9021debfc3dSmrg 	     anymore.  */
9031debfc3dSmrg 	  high += GARDROUND + 1;
9041debfc3dSmrg 
9051debfc3dSmrg 	  /* Avoid further rounding in pack_d.  */
9061debfc3dSmrg 	  high &= ~(fractype) GARDMASK;
9071debfc3dSmrg 	}
9081debfc3dSmrg     }
9091debfc3dSmrg   tmp->fraction.ll = high;
9101debfc3dSmrg   tmp->class = CLASS_NUMBER;
9111debfc3dSmrg   return tmp;
9121debfc3dSmrg }
9131debfc3dSmrg 
9141debfc3dSmrg FLO_type
9151debfc3dSmrg multiply (FLO_type arg_a, FLO_type arg_b)
9161debfc3dSmrg {
9171debfc3dSmrg   fp_number_type a;
9181debfc3dSmrg   fp_number_type b;
9191debfc3dSmrg   fp_number_type tmp;
9201debfc3dSmrg   const fp_number_type *res;
9211debfc3dSmrg   FLO_union_type au, bu;
9221debfc3dSmrg 
9231debfc3dSmrg   au.value = arg_a;
9241debfc3dSmrg   bu.value = arg_b;
9251debfc3dSmrg 
9261debfc3dSmrg   unpack_d (&au, &a);
9271debfc3dSmrg   unpack_d (&bu, &b);
9281debfc3dSmrg 
9291debfc3dSmrg   res = _fpmul_parts (&a, &b, &tmp);
9301debfc3dSmrg 
9311debfc3dSmrg   return pack_d (res);
9321debfc3dSmrg }
9331debfc3dSmrg #endif /* L_mul_sf || L_mul_df || L_mul_tf */
9341debfc3dSmrg 
9351debfc3dSmrg #if defined(L_div_sf) || defined(L_div_df) || defined(L_div_tf)
9361debfc3dSmrg static inline __attribute__ ((__always_inline__)) const fp_number_type *
9371debfc3dSmrg _fpdiv_parts (fp_number_type * a,
9381debfc3dSmrg 	      fp_number_type * b)
9391debfc3dSmrg {
9401debfc3dSmrg   fractype bit;
9411debfc3dSmrg   fractype numerator;
9421debfc3dSmrg   fractype denominator;
9431debfc3dSmrg   fractype quotient;
9441debfc3dSmrg 
9451debfc3dSmrg   if (isnan (a))
9461debfc3dSmrg     {
9471debfc3dSmrg       return a;
9481debfc3dSmrg     }
9491debfc3dSmrg   if (isnan (b))
9501debfc3dSmrg     {
9511debfc3dSmrg       return b;
9521debfc3dSmrg     }
9531debfc3dSmrg 
9541debfc3dSmrg   a->sign = a->sign ^ b->sign;
9551debfc3dSmrg 
9561debfc3dSmrg   if (isinf (a) || iszero (a))
9571debfc3dSmrg     {
9581debfc3dSmrg       if (a->class == b->class)
9591debfc3dSmrg 	return makenan ();
9601debfc3dSmrg       return a;
9611debfc3dSmrg     }
9621debfc3dSmrg 
9631debfc3dSmrg   if (isinf (b))
9641debfc3dSmrg     {
9651debfc3dSmrg       a->fraction.ll = 0;
9661debfc3dSmrg       a->normal_exp = 0;
9671debfc3dSmrg       return a;
9681debfc3dSmrg     }
9691debfc3dSmrg   if (iszero (b))
9701debfc3dSmrg     {
9711debfc3dSmrg       a->class = CLASS_INFINITY;
9721debfc3dSmrg       return a;
9731debfc3dSmrg     }
9741debfc3dSmrg 
9751debfc3dSmrg   /* Calculate the mantissa by multiplying both 64bit numbers to get a
9761debfc3dSmrg      128 bit number */
9771debfc3dSmrg   {
9781debfc3dSmrg     /* quotient =
9791debfc3dSmrg        ( numerator / denominator) * 2^(numerator exponent -  denominator exponent)
9801debfc3dSmrg      */
9811debfc3dSmrg 
9821debfc3dSmrg     a->normal_exp = a->normal_exp - b->normal_exp;
9831debfc3dSmrg     numerator = a->fraction.ll;
9841debfc3dSmrg     denominator = b->fraction.ll;
9851debfc3dSmrg 
9861debfc3dSmrg     if (numerator < denominator)
9871debfc3dSmrg       {
9881debfc3dSmrg 	/* Fraction will be less than 1.0 */
9891debfc3dSmrg 	numerator *= 2;
9901debfc3dSmrg 	a->normal_exp--;
9911debfc3dSmrg       }
9921debfc3dSmrg     bit = IMPLICIT_1;
9931debfc3dSmrg     quotient = 0;
9941debfc3dSmrg     /* ??? Does divide one bit at a time.  Optimize.  */
9951debfc3dSmrg     while (bit)
9961debfc3dSmrg       {
9971debfc3dSmrg 	if (numerator >= denominator)
9981debfc3dSmrg 	  {
9991debfc3dSmrg 	    quotient |= bit;
10001debfc3dSmrg 	    numerator -= denominator;
10011debfc3dSmrg 	  }
10021debfc3dSmrg 	bit >>= 1;
10031debfc3dSmrg 	numerator *= 2;
10041debfc3dSmrg       }
10051debfc3dSmrg 
10061debfc3dSmrg     if ((quotient & GARDMASK) == GARDMSB)
10071debfc3dSmrg       {
10081debfc3dSmrg 	if (quotient & (1 << NGARDS))
10091debfc3dSmrg 	  {
10101debfc3dSmrg 	    /* Because we're half way, we would round to even by adding
10111debfc3dSmrg 	       GARDROUND + 1, except that's also done in the packing
10121debfc3dSmrg 	       function, and rounding twice will lose precision and cause
10131debfc3dSmrg 	       the result to be too far off.  */
10141debfc3dSmrg 	  }
10151debfc3dSmrg 	else if (numerator)
10161debfc3dSmrg 	  {
10171debfc3dSmrg 	    /* We're a further than half way by the small amount
10181debfc3dSmrg 	       corresponding to the bits set in "numerator".  Knowing
10191debfc3dSmrg 	       that, we round here and not in pack_d, because there we
10201debfc3dSmrg 	       don't have "numerator" available anymore.  */
10211debfc3dSmrg 	    quotient += GARDROUND + 1;
10221debfc3dSmrg 
10231debfc3dSmrg 	    /* Avoid further rounding in pack_d.  */
10241debfc3dSmrg 	    quotient &= ~(fractype) GARDMASK;
10251debfc3dSmrg 	  }
10261debfc3dSmrg       }
10271debfc3dSmrg 
10281debfc3dSmrg     a->fraction.ll = quotient;
10291debfc3dSmrg     return (a);
10301debfc3dSmrg   }
10311debfc3dSmrg }
10321debfc3dSmrg 
10331debfc3dSmrg FLO_type
10341debfc3dSmrg divide (FLO_type arg_a, FLO_type arg_b)
10351debfc3dSmrg {
10361debfc3dSmrg   fp_number_type a;
10371debfc3dSmrg   fp_number_type b;
10381debfc3dSmrg   const fp_number_type *res;
10391debfc3dSmrg   FLO_union_type au, bu;
10401debfc3dSmrg 
10411debfc3dSmrg   au.value = arg_a;
10421debfc3dSmrg   bu.value = arg_b;
10431debfc3dSmrg 
10441debfc3dSmrg   unpack_d (&au, &a);
10451debfc3dSmrg   unpack_d (&bu, &b);
10461debfc3dSmrg 
10471debfc3dSmrg   res = _fpdiv_parts (&a, &b);
10481debfc3dSmrg 
10491debfc3dSmrg   return pack_d (res);
10501debfc3dSmrg }
10511debfc3dSmrg #endif /* L_div_sf || L_div_df */
10521debfc3dSmrg 
10531debfc3dSmrg #if defined(L_fpcmp_parts_sf) || defined(L_fpcmp_parts_df) \
10541debfc3dSmrg     || defined(L_fpcmp_parts_tf)
10551debfc3dSmrg /* according to the demo, fpcmp returns a comparison with 0... thus
10561debfc3dSmrg    a<b -> -1
10571debfc3dSmrg    a==b -> 0
10581debfc3dSmrg    a>b -> +1
10591debfc3dSmrg  */
10601debfc3dSmrg 
10611debfc3dSmrg int
10621debfc3dSmrg __fpcmp_parts (fp_number_type * a, fp_number_type * b)
10631debfc3dSmrg {
10641debfc3dSmrg #if 0
10651debfc3dSmrg   /* either nan -> unordered. Must be checked outside of this routine.  */
10661debfc3dSmrg   if (isnan (a) && isnan (b))
10671debfc3dSmrg     {
10681debfc3dSmrg       return 1;			/* still unordered! */
10691debfc3dSmrg     }
10701debfc3dSmrg #endif
10711debfc3dSmrg 
10721debfc3dSmrg   if (isnan (a) || isnan (b))
10731debfc3dSmrg     {
10741debfc3dSmrg       return 1;			/* how to indicate unordered compare? */
10751debfc3dSmrg     }
10761debfc3dSmrg   if (isinf (a) && isinf (b))
10771debfc3dSmrg     {
10781debfc3dSmrg       /* +inf > -inf, but +inf != +inf */
10791debfc3dSmrg       /* b    \a| +inf(0)| -inf(1)
10801debfc3dSmrg        ______\+--------+--------
10811debfc3dSmrg        +inf(0)| a==b(0)| a<b(-1)
10821debfc3dSmrg        -------+--------+--------
10831debfc3dSmrg        -inf(1)| a>b(1) | a==b(0)
10841debfc3dSmrg        -------+--------+--------
10851debfc3dSmrg        So since unordered must be nonzero, just line up the columns...
10861debfc3dSmrg        */
10871debfc3dSmrg       return b->sign - a->sign;
10881debfc3dSmrg     }
10891debfc3dSmrg   /* but not both...  */
10901debfc3dSmrg   if (isinf (a))
10911debfc3dSmrg     {
10921debfc3dSmrg       return a->sign ? -1 : 1;
10931debfc3dSmrg     }
10941debfc3dSmrg   if (isinf (b))
10951debfc3dSmrg     {
10961debfc3dSmrg       return b->sign ? 1 : -1;
10971debfc3dSmrg     }
10981debfc3dSmrg   if (iszero (a) && iszero (b))
10991debfc3dSmrg     {
11001debfc3dSmrg       return 0;
11011debfc3dSmrg     }
11021debfc3dSmrg   if (iszero (a))
11031debfc3dSmrg     {
11041debfc3dSmrg       return b->sign ? 1 : -1;
11051debfc3dSmrg     }
11061debfc3dSmrg   if (iszero (b))
11071debfc3dSmrg     {
11081debfc3dSmrg       return a->sign ? -1 : 1;
11091debfc3dSmrg     }
11101debfc3dSmrg   /* now both are "normal".  */
11111debfc3dSmrg   if (a->sign != b->sign)
11121debfc3dSmrg     {
11131debfc3dSmrg       /* opposite signs */
11141debfc3dSmrg       return a->sign ? -1 : 1;
11151debfc3dSmrg     }
11161debfc3dSmrg   /* same sign; exponents? */
11171debfc3dSmrg   if (a->normal_exp > b->normal_exp)
11181debfc3dSmrg     {
11191debfc3dSmrg       return a->sign ? -1 : 1;
11201debfc3dSmrg     }
11211debfc3dSmrg   if (a->normal_exp < b->normal_exp)
11221debfc3dSmrg     {
11231debfc3dSmrg       return a->sign ? 1 : -1;
11241debfc3dSmrg     }
11251debfc3dSmrg   /* same exponents; check size.  */
11261debfc3dSmrg   if (a->fraction.ll > b->fraction.ll)
11271debfc3dSmrg     {
11281debfc3dSmrg       return a->sign ? -1 : 1;
11291debfc3dSmrg     }
11301debfc3dSmrg   if (a->fraction.ll < b->fraction.ll)
11311debfc3dSmrg     {
11321debfc3dSmrg       return a->sign ? 1 : -1;
11331debfc3dSmrg     }
11341debfc3dSmrg   /* after all that, they're equal.  */
11351debfc3dSmrg   return 0;
11361debfc3dSmrg }
11371debfc3dSmrg #endif
11381debfc3dSmrg 
11391debfc3dSmrg #if defined(L_compare_sf) || defined(L_compare_df) || defined(L_compoare_tf)
11401debfc3dSmrg CMPtype
11411debfc3dSmrg compare (FLO_type arg_a, FLO_type arg_b)
11421debfc3dSmrg {
11431debfc3dSmrg   fp_number_type a;
11441debfc3dSmrg   fp_number_type b;
11451debfc3dSmrg   FLO_union_type au, bu;
11461debfc3dSmrg 
11471debfc3dSmrg   au.value = arg_a;
11481debfc3dSmrg   bu.value = arg_b;
11491debfc3dSmrg 
11501debfc3dSmrg   unpack_d (&au, &a);
11511debfc3dSmrg   unpack_d (&bu, &b);
11521debfc3dSmrg 
11531debfc3dSmrg   return __fpcmp_parts (&a, &b);
11541debfc3dSmrg }
11551debfc3dSmrg #endif /* L_compare_sf || L_compare_df */
11561debfc3dSmrg 
11571debfc3dSmrg /* These should be optimized for their specific tasks someday.  */
11581debfc3dSmrg 
11591debfc3dSmrg #if defined(L_eq_sf) || defined(L_eq_df) || defined(L_eq_tf)
11601debfc3dSmrg CMPtype
11611debfc3dSmrg _eq_f2 (FLO_type arg_a, FLO_type arg_b)
11621debfc3dSmrg {
11631debfc3dSmrg   fp_number_type a;
11641debfc3dSmrg   fp_number_type b;
11651debfc3dSmrg   FLO_union_type au, bu;
11661debfc3dSmrg 
11671debfc3dSmrg   au.value = arg_a;
11681debfc3dSmrg   bu.value = arg_b;
11691debfc3dSmrg 
11701debfc3dSmrg   unpack_d (&au, &a);
11711debfc3dSmrg   unpack_d (&bu, &b);
11721debfc3dSmrg 
11731debfc3dSmrg   if (isnan (&a) || isnan (&b))
11741debfc3dSmrg     return 1;			/* false, truth == 0 */
11751debfc3dSmrg 
11761debfc3dSmrg   return __fpcmp_parts (&a, &b) ;
11771debfc3dSmrg }
11781debfc3dSmrg #endif /* L_eq_sf || L_eq_df */
11791debfc3dSmrg 
11801debfc3dSmrg #if defined(L_ne_sf) || defined(L_ne_df) || defined(L_ne_tf)
11811debfc3dSmrg CMPtype
11821debfc3dSmrg _ne_f2 (FLO_type arg_a, FLO_type arg_b)
11831debfc3dSmrg {
11841debfc3dSmrg   fp_number_type a;
11851debfc3dSmrg   fp_number_type b;
11861debfc3dSmrg   FLO_union_type au, bu;
11871debfc3dSmrg 
11881debfc3dSmrg   au.value = arg_a;
11891debfc3dSmrg   bu.value = arg_b;
11901debfc3dSmrg 
11911debfc3dSmrg   unpack_d (&au, &a);
11921debfc3dSmrg   unpack_d (&bu, &b);
11931debfc3dSmrg 
11941debfc3dSmrg   if (isnan (&a) || isnan (&b))
11951debfc3dSmrg     return 1;			/* true, truth != 0 */
11961debfc3dSmrg 
11971debfc3dSmrg   return  __fpcmp_parts (&a, &b) ;
11981debfc3dSmrg }
11991debfc3dSmrg #endif /* L_ne_sf || L_ne_df */
12001debfc3dSmrg 
12011debfc3dSmrg #if defined(L_gt_sf) || defined(L_gt_df) || defined(L_gt_tf)
12021debfc3dSmrg CMPtype
12031debfc3dSmrg _gt_f2 (FLO_type arg_a, FLO_type arg_b)
12041debfc3dSmrg {
12051debfc3dSmrg   fp_number_type a;
12061debfc3dSmrg   fp_number_type b;
12071debfc3dSmrg   FLO_union_type au, bu;
12081debfc3dSmrg 
12091debfc3dSmrg   au.value = arg_a;
12101debfc3dSmrg   bu.value = arg_b;
12111debfc3dSmrg 
12121debfc3dSmrg   unpack_d (&au, &a);
12131debfc3dSmrg   unpack_d (&bu, &b);
12141debfc3dSmrg 
12151debfc3dSmrg   if (isnan (&a) || isnan (&b))
12161debfc3dSmrg     return -1;			/* false, truth > 0 */
12171debfc3dSmrg 
12181debfc3dSmrg   return __fpcmp_parts (&a, &b);
12191debfc3dSmrg }
12201debfc3dSmrg #endif /* L_gt_sf || L_gt_df */
12211debfc3dSmrg 
12221debfc3dSmrg #if defined(L_ge_sf) || defined(L_ge_df) || defined(L_ge_tf)
12231debfc3dSmrg CMPtype
12241debfc3dSmrg _ge_f2 (FLO_type arg_a, FLO_type arg_b)
12251debfc3dSmrg {
12261debfc3dSmrg   fp_number_type a;
12271debfc3dSmrg   fp_number_type b;
12281debfc3dSmrg   FLO_union_type au, bu;
12291debfc3dSmrg 
12301debfc3dSmrg   au.value = arg_a;
12311debfc3dSmrg   bu.value = arg_b;
12321debfc3dSmrg 
12331debfc3dSmrg   unpack_d (&au, &a);
12341debfc3dSmrg   unpack_d (&bu, &b);
12351debfc3dSmrg 
12361debfc3dSmrg   if (isnan (&a) || isnan (&b))
12371debfc3dSmrg     return -1;			/* false, truth >= 0 */
12381debfc3dSmrg   return __fpcmp_parts (&a, &b) ;
12391debfc3dSmrg }
12401debfc3dSmrg #endif /* L_ge_sf || L_ge_df */
12411debfc3dSmrg 
12421debfc3dSmrg #if defined(L_lt_sf) || defined(L_lt_df) || defined(L_lt_tf)
12431debfc3dSmrg CMPtype
12441debfc3dSmrg _lt_f2 (FLO_type arg_a, FLO_type arg_b)
12451debfc3dSmrg {
12461debfc3dSmrg   fp_number_type a;
12471debfc3dSmrg   fp_number_type b;
12481debfc3dSmrg   FLO_union_type au, bu;
12491debfc3dSmrg 
12501debfc3dSmrg   au.value = arg_a;
12511debfc3dSmrg   bu.value = arg_b;
12521debfc3dSmrg 
12531debfc3dSmrg   unpack_d (&au, &a);
12541debfc3dSmrg   unpack_d (&bu, &b);
12551debfc3dSmrg 
12561debfc3dSmrg   if (isnan (&a) || isnan (&b))
12571debfc3dSmrg     return 1;			/* false, truth < 0 */
12581debfc3dSmrg 
12591debfc3dSmrg   return __fpcmp_parts (&a, &b);
12601debfc3dSmrg }
12611debfc3dSmrg #endif /* L_lt_sf || L_lt_df */
12621debfc3dSmrg 
12631debfc3dSmrg #if defined(L_le_sf) || defined(L_le_df) || defined(L_le_tf)
12641debfc3dSmrg CMPtype
12651debfc3dSmrg _le_f2 (FLO_type arg_a, FLO_type arg_b)
12661debfc3dSmrg {
12671debfc3dSmrg   fp_number_type a;
12681debfc3dSmrg   fp_number_type b;
12691debfc3dSmrg   FLO_union_type au, bu;
12701debfc3dSmrg 
12711debfc3dSmrg   au.value = arg_a;
12721debfc3dSmrg   bu.value = arg_b;
12731debfc3dSmrg 
12741debfc3dSmrg   unpack_d (&au, &a);
12751debfc3dSmrg   unpack_d (&bu, &b);
12761debfc3dSmrg 
12771debfc3dSmrg   if (isnan (&a) || isnan (&b))
12781debfc3dSmrg     return 1;			/* false, truth <= 0 */
12791debfc3dSmrg 
12801debfc3dSmrg   return __fpcmp_parts (&a, &b) ;
12811debfc3dSmrg }
12821debfc3dSmrg #endif /* L_le_sf || L_le_df */
12831debfc3dSmrg 
12841debfc3dSmrg #if defined(L_unord_sf) || defined(L_unord_df) || defined(L_unord_tf)
12851debfc3dSmrg CMPtype
12861debfc3dSmrg _unord_f2 (FLO_type arg_a, FLO_type arg_b)
12871debfc3dSmrg {
12881debfc3dSmrg   fp_number_type a;
12891debfc3dSmrg   fp_number_type b;
12901debfc3dSmrg   FLO_union_type au, bu;
12911debfc3dSmrg 
12921debfc3dSmrg   au.value = arg_a;
12931debfc3dSmrg   bu.value = arg_b;
12941debfc3dSmrg 
12951debfc3dSmrg   unpack_d (&au, &a);
12961debfc3dSmrg   unpack_d (&bu, &b);
12971debfc3dSmrg 
12981debfc3dSmrg   return (isnan (&a) || isnan (&b));
12991debfc3dSmrg }
13001debfc3dSmrg #endif /* L_unord_sf || L_unord_df */
13011debfc3dSmrg 
13021debfc3dSmrg #if defined(L_si_to_sf) || defined(L_si_to_df) || defined(L_si_to_tf)
13031debfc3dSmrg FLO_type
13041debfc3dSmrg si_to_float (SItype arg_a)
13051debfc3dSmrg {
13061debfc3dSmrg   fp_number_type in;
13071debfc3dSmrg 
13081debfc3dSmrg   in.class = CLASS_NUMBER;
13091debfc3dSmrg   in.sign = arg_a < 0;
13101debfc3dSmrg   if (!arg_a)
13111debfc3dSmrg     {
13121debfc3dSmrg       in.class = CLASS_ZERO;
13131debfc3dSmrg     }
13141debfc3dSmrg   else
13151debfc3dSmrg     {
13161debfc3dSmrg       USItype uarg;
13171debfc3dSmrg       int shift;
13181debfc3dSmrg       in.normal_exp = FRACBITS + NGARDS;
13191debfc3dSmrg       if (in.sign)
13201debfc3dSmrg 	{
13211debfc3dSmrg 	  /* Special case for minint, since there is no +ve integer
13221debfc3dSmrg 	     representation for it */
13231debfc3dSmrg 	  if (arg_a == (- MAX_SI_INT - 1))
13241debfc3dSmrg 	    {
13251debfc3dSmrg 	      return (FLO_type)(- MAX_SI_INT - 1);
13261debfc3dSmrg 	    }
13271debfc3dSmrg 	  uarg = (-arg_a);
13281debfc3dSmrg 	}
13291debfc3dSmrg       else
13301debfc3dSmrg 	uarg = arg_a;
13311debfc3dSmrg 
13321debfc3dSmrg       in.fraction.ll = uarg;
13331debfc3dSmrg       shift = clzusi (uarg) - (BITS_PER_SI - 1 - FRACBITS - NGARDS);
13341debfc3dSmrg       if (shift > 0)
13351debfc3dSmrg 	{
13361debfc3dSmrg 	  in.fraction.ll <<= shift;
13371debfc3dSmrg 	  in.normal_exp -= shift;
13381debfc3dSmrg 	}
13391debfc3dSmrg     }
13401debfc3dSmrg   return pack_d (&in);
13411debfc3dSmrg }
13421debfc3dSmrg #endif /* L_si_to_sf || L_si_to_df */
13431debfc3dSmrg 
13441debfc3dSmrg #if defined(L_usi_to_sf) || defined(L_usi_to_df) || defined(L_usi_to_tf)
13451debfc3dSmrg FLO_type
13461debfc3dSmrg usi_to_float (USItype arg_a)
13471debfc3dSmrg {
13481debfc3dSmrg   fp_number_type in;
13491debfc3dSmrg 
13501debfc3dSmrg   in.sign = 0;
13511debfc3dSmrg   if (!arg_a)
13521debfc3dSmrg     {
13531debfc3dSmrg       in.class = CLASS_ZERO;
13541debfc3dSmrg     }
13551debfc3dSmrg   else
13561debfc3dSmrg     {
13571debfc3dSmrg       int shift;
13581debfc3dSmrg       in.class = CLASS_NUMBER;
13591debfc3dSmrg       in.normal_exp = FRACBITS + NGARDS;
13601debfc3dSmrg       in.fraction.ll = arg_a;
13611debfc3dSmrg 
13621debfc3dSmrg       shift = clzusi (arg_a) - (BITS_PER_SI - 1 - FRACBITS - NGARDS);
13631debfc3dSmrg       if (shift < 0)
13641debfc3dSmrg 	{
13651debfc3dSmrg 	  fractype guard = in.fraction.ll & (((fractype)1 << -shift) - 1);
13661debfc3dSmrg 	  in.fraction.ll >>= -shift;
13671debfc3dSmrg 	  in.fraction.ll |= (guard != 0);
13681debfc3dSmrg 	  in.normal_exp -= shift;
13691debfc3dSmrg 	}
13701debfc3dSmrg       else if (shift > 0)
13711debfc3dSmrg 	{
13721debfc3dSmrg 	  in.fraction.ll <<= shift;
13731debfc3dSmrg 	  in.normal_exp -= shift;
13741debfc3dSmrg 	}
13751debfc3dSmrg     }
13761debfc3dSmrg   return pack_d (&in);
13771debfc3dSmrg }
13781debfc3dSmrg #endif
13791debfc3dSmrg 
13801debfc3dSmrg #if defined(L_sf_to_si) || defined(L_df_to_si) || defined(L_tf_to_si)
13811debfc3dSmrg SItype
13821debfc3dSmrg float_to_si (FLO_type arg_a)
13831debfc3dSmrg {
13841debfc3dSmrg   fp_number_type a;
13851debfc3dSmrg   SItype tmp;
13861debfc3dSmrg   FLO_union_type au;
13871debfc3dSmrg 
13881debfc3dSmrg   au.value = arg_a;
13891debfc3dSmrg   unpack_d (&au, &a);
13901debfc3dSmrg 
13911debfc3dSmrg   if (iszero (&a))
13921debfc3dSmrg     return 0;
13931debfc3dSmrg   if (isnan (&a))
13941debfc3dSmrg     return 0;
13951debfc3dSmrg   /* get reasonable MAX_SI_INT...  */
13961debfc3dSmrg   if (isinf (&a))
13971debfc3dSmrg     return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
13981debfc3dSmrg   /* it is a number, but a small one */
13991debfc3dSmrg   if (a.normal_exp < 0)
14001debfc3dSmrg     return 0;
14011debfc3dSmrg   if (a.normal_exp > BITS_PER_SI - 2)
14021debfc3dSmrg     return a.sign ? (-MAX_SI_INT)-1 : MAX_SI_INT;
14031debfc3dSmrg   tmp = a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
14041debfc3dSmrg   return a.sign ? (-tmp) : (tmp);
14051debfc3dSmrg }
14061debfc3dSmrg #endif /* L_sf_to_si || L_df_to_si */
14071debfc3dSmrg 
14081debfc3dSmrg #if defined(L_tf_to_usi)
14091debfc3dSmrg USItype
14101debfc3dSmrg float_to_usi (FLO_type arg_a)
14111debfc3dSmrg {
14121debfc3dSmrg   fp_number_type a;
14131debfc3dSmrg   FLO_union_type au;
14141debfc3dSmrg 
14151debfc3dSmrg   au.value = arg_a;
14161debfc3dSmrg   unpack_d (&au, &a);
14171debfc3dSmrg 
14181debfc3dSmrg   if (iszero (&a))
14191debfc3dSmrg     return 0;
14201debfc3dSmrg   if (isnan (&a))
14211debfc3dSmrg     return 0;
14221debfc3dSmrg   /* it is a negative number */
14231debfc3dSmrg   if (a.sign)
14241debfc3dSmrg     return 0;
14251debfc3dSmrg   /* get reasonable MAX_USI_INT...  */
14261debfc3dSmrg   if (isinf (&a))
14271debfc3dSmrg     return MAX_USI_INT;
14281debfc3dSmrg   /* it is a number, but a small one */
14291debfc3dSmrg   if (a.normal_exp < 0)
14301debfc3dSmrg     return 0;
14311debfc3dSmrg   if (a.normal_exp > BITS_PER_SI - 1)
14321debfc3dSmrg     return MAX_USI_INT;
14331debfc3dSmrg   else if (a.normal_exp > (FRACBITS + NGARDS))
14341debfc3dSmrg     return a.fraction.ll << (a.normal_exp - (FRACBITS + NGARDS));
14351debfc3dSmrg   else
14361debfc3dSmrg     return a.fraction.ll >> ((FRACBITS + NGARDS) - a.normal_exp);
14371debfc3dSmrg }
14381debfc3dSmrg #endif /* L_tf_to_usi */
14391debfc3dSmrg 
14401debfc3dSmrg #if defined(L_negate_sf) || defined(L_negate_df) || defined(L_negate_tf)
14411debfc3dSmrg FLO_type
14421debfc3dSmrg negate (FLO_type arg_a)
14431debfc3dSmrg {
14441debfc3dSmrg   fp_number_type a;
14451debfc3dSmrg   FLO_union_type au;
14461debfc3dSmrg 
14471debfc3dSmrg   au.value = arg_a;
14481debfc3dSmrg   unpack_d (&au, &a);
14491debfc3dSmrg 
14501debfc3dSmrg   flip_sign (&a);
14511debfc3dSmrg   return pack_d (&a);
14521debfc3dSmrg }
14531debfc3dSmrg #endif /* L_negate_sf || L_negate_df */
14541debfc3dSmrg 
14551debfc3dSmrg #ifdef FLOAT
14561debfc3dSmrg 
14571debfc3dSmrg #if defined(L_make_sf)
14581debfc3dSmrg SFtype
14591debfc3dSmrg __make_fp(fp_class_type class,
14601debfc3dSmrg 	     unsigned int sign,
14611debfc3dSmrg 	     int exp,
14621debfc3dSmrg 	     USItype frac)
14631debfc3dSmrg {
14641debfc3dSmrg   fp_number_type in;
14651debfc3dSmrg 
14661debfc3dSmrg   in.class = class;
14671debfc3dSmrg   in.sign = sign;
14681debfc3dSmrg   in.normal_exp = exp;
14691debfc3dSmrg   in.fraction.ll = frac;
14701debfc3dSmrg   return pack_d (&in);
14711debfc3dSmrg }
14721debfc3dSmrg #endif /* L_make_sf */
14731debfc3dSmrg 
14741debfc3dSmrg #ifndef FLOAT_ONLY
14751debfc3dSmrg 
14761debfc3dSmrg /* This enables one to build an fp library that supports float but not double.
14771debfc3dSmrg    Otherwise, we would get an undefined reference to __make_dp.
14781debfc3dSmrg    This is needed for some 8-bit ports that can't handle well values that
14791debfc3dSmrg    are 8-bytes in size, so we just don't support double for them at all.  */
14801debfc3dSmrg 
14811debfc3dSmrg #if defined(L_sf_to_df)
14821debfc3dSmrg DFtype
14831debfc3dSmrg sf_to_df (SFtype arg_a)
14841debfc3dSmrg {
14851debfc3dSmrg   fp_number_type in;
14861debfc3dSmrg   FLO_union_type au;
14871debfc3dSmrg 
14881debfc3dSmrg   au.value = arg_a;
14891debfc3dSmrg   unpack_d (&au, &in);
14901debfc3dSmrg 
14911debfc3dSmrg   return __make_dp (in.class, in.sign, in.normal_exp,
14921debfc3dSmrg 		    ((UDItype) in.fraction.ll) << F_D_BITOFF);
14931debfc3dSmrg }
14941debfc3dSmrg #endif /* L_sf_to_df */
14951debfc3dSmrg 
14961debfc3dSmrg #if defined(L_sf_to_tf) && defined(TMODES)
14971debfc3dSmrg TFtype
14981debfc3dSmrg sf_to_tf (SFtype arg_a)
14991debfc3dSmrg {
15001debfc3dSmrg   fp_number_type in;
15011debfc3dSmrg   FLO_union_type au;
15021debfc3dSmrg 
15031debfc3dSmrg   au.value = arg_a;
15041debfc3dSmrg   unpack_d (&au, &in);
15051debfc3dSmrg 
15061debfc3dSmrg   return __make_tp (in.class, in.sign, in.normal_exp,
15071debfc3dSmrg 		    ((UTItype) in.fraction.ll) << F_T_BITOFF);
15081debfc3dSmrg }
15091debfc3dSmrg #endif /* L_sf_to_df */
15101debfc3dSmrg 
15111debfc3dSmrg #endif /* ! FLOAT_ONLY */
15121debfc3dSmrg #endif /* FLOAT */
15131debfc3dSmrg 
15141debfc3dSmrg #ifndef FLOAT
15151debfc3dSmrg 
15161debfc3dSmrg extern SFtype __make_fp (fp_class_type, unsigned int, int, USItype);
15171debfc3dSmrg 
15181debfc3dSmrg #if defined(L_make_df)
15191debfc3dSmrg DFtype
15201debfc3dSmrg __make_dp (fp_class_type class, unsigned int sign, int exp, UDItype frac)
15211debfc3dSmrg {
15221debfc3dSmrg   fp_number_type in;
15231debfc3dSmrg 
15241debfc3dSmrg   in.class = class;
15251debfc3dSmrg   in.sign = sign;
15261debfc3dSmrg   in.normal_exp = exp;
15271debfc3dSmrg   in.fraction.ll = frac;
15281debfc3dSmrg   return pack_d (&in);
15291debfc3dSmrg }
15301debfc3dSmrg #endif /* L_make_df */
15311debfc3dSmrg 
15321debfc3dSmrg #if defined(L_df_to_sf)
15331debfc3dSmrg SFtype
15341debfc3dSmrg df_to_sf (DFtype arg_a)
15351debfc3dSmrg {
15361debfc3dSmrg   fp_number_type in;
15371debfc3dSmrg   USItype sffrac;
15381debfc3dSmrg   FLO_union_type au;
15391debfc3dSmrg 
15401debfc3dSmrg   au.value = arg_a;
15411debfc3dSmrg   unpack_d (&au, &in);
15421debfc3dSmrg 
15431debfc3dSmrg   sffrac = in.fraction.ll >> F_D_BITOFF;
15441debfc3dSmrg 
15451debfc3dSmrg   /* We set the lowest guard bit in SFFRAC if we discarded any non
15461debfc3dSmrg      zero bits.  */
15471debfc3dSmrg   if ((in.fraction.ll & (((USItype) 1 << F_D_BITOFF) - 1)) != 0)
15481debfc3dSmrg     sffrac |= 1;
15491debfc3dSmrg 
15501debfc3dSmrg   return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
15511debfc3dSmrg }
15521debfc3dSmrg #endif /* L_df_to_sf */
15531debfc3dSmrg 
15541debfc3dSmrg #if defined(L_df_to_tf) && defined(TMODES) \
15551debfc3dSmrg     && !defined(FLOAT) && !defined(TFLOAT)
15561debfc3dSmrg TFtype
15571debfc3dSmrg df_to_tf (DFtype arg_a)
15581debfc3dSmrg {
15591debfc3dSmrg   fp_number_type in;
15601debfc3dSmrg   FLO_union_type au;
15611debfc3dSmrg 
15621debfc3dSmrg   au.value = arg_a;
15631debfc3dSmrg   unpack_d (&au, &in);
15641debfc3dSmrg 
15651debfc3dSmrg   return __make_tp (in.class, in.sign, in.normal_exp,
15661debfc3dSmrg 		    ((UTItype) in.fraction.ll) << D_T_BITOFF);
15671debfc3dSmrg }
15681debfc3dSmrg #endif /* L_sf_to_df */
15691debfc3dSmrg 
15701debfc3dSmrg #ifdef TFLOAT
15711debfc3dSmrg #if defined(L_make_tf)
15721debfc3dSmrg TFtype
15731debfc3dSmrg __make_tp(fp_class_type class,
15741debfc3dSmrg 	     unsigned int sign,
15751debfc3dSmrg 	     int exp,
15761debfc3dSmrg 	     UTItype frac)
15771debfc3dSmrg {
15781debfc3dSmrg   fp_number_type in;
15791debfc3dSmrg 
15801debfc3dSmrg   in.class = class;
15811debfc3dSmrg   in.sign = sign;
15821debfc3dSmrg   in.normal_exp = exp;
15831debfc3dSmrg   in.fraction.ll = frac;
15841debfc3dSmrg   return pack_d (&in);
15851debfc3dSmrg }
15861debfc3dSmrg #endif /* L_make_tf */
15871debfc3dSmrg 
15881debfc3dSmrg #if defined(L_tf_to_df)
15891debfc3dSmrg DFtype
15901debfc3dSmrg tf_to_df (TFtype arg_a)
15911debfc3dSmrg {
15921debfc3dSmrg   fp_number_type in;
15931debfc3dSmrg   UDItype sffrac;
15941debfc3dSmrg   FLO_union_type au;
15951debfc3dSmrg 
15961debfc3dSmrg   au.value = arg_a;
15971debfc3dSmrg   unpack_d (&au, &in);
15981debfc3dSmrg 
15991debfc3dSmrg   sffrac = in.fraction.ll >> D_T_BITOFF;
16001debfc3dSmrg 
16011debfc3dSmrg   /* We set the lowest guard bit in SFFRAC if we discarded any non
16021debfc3dSmrg      zero bits.  */
16031debfc3dSmrg   if ((in.fraction.ll & (((UTItype) 1 << D_T_BITOFF) - 1)) != 0)
16041debfc3dSmrg     sffrac |= 1;
16051debfc3dSmrg 
16061debfc3dSmrg   return __make_dp (in.class, in.sign, in.normal_exp, sffrac);
16071debfc3dSmrg }
16081debfc3dSmrg #endif /* L_tf_to_df */
16091debfc3dSmrg 
16101debfc3dSmrg #if defined(L_tf_to_sf)
16111debfc3dSmrg SFtype
16121debfc3dSmrg tf_to_sf (TFtype arg_a)
16131debfc3dSmrg {
16141debfc3dSmrg   fp_number_type in;
16151debfc3dSmrg   USItype sffrac;
16161debfc3dSmrg   FLO_union_type au;
16171debfc3dSmrg 
16181debfc3dSmrg   au.value = arg_a;
16191debfc3dSmrg   unpack_d (&au, &in);
16201debfc3dSmrg 
16211debfc3dSmrg   sffrac = in.fraction.ll >> F_T_BITOFF;
16221debfc3dSmrg 
16231debfc3dSmrg   /* We set the lowest guard bit in SFFRAC if we discarded any non
16241debfc3dSmrg      zero bits.  */
16251debfc3dSmrg   if ((in.fraction.ll & (((UTItype) 1 << F_T_BITOFF) - 1)) != 0)
16261debfc3dSmrg     sffrac |= 1;
16271debfc3dSmrg 
16281debfc3dSmrg   return __make_fp (in.class, in.sign, in.normal_exp, sffrac);
16291debfc3dSmrg }
16301debfc3dSmrg #endif /* L_tf_to_sf */
16311debfc3dSmrg #endif /* TFLOAT */
16321debfc3dSmrg 
16331debfc3dSmrg #endif /* ! FLOAT */
16341debfc3dSmrg #endif /* !EXTENDED_FLOAT_STUBS */
1635