xref: /minix3/lib/libc/softfloat/bits32/softfloat.c (revision 84d9c625bfea59e274550651111ae9edfdc40fbd)
1*84d9c625SLionel Sambuc /* $NetBSD: softfloat.c,v 1.3 2013/01/10 08:16:11 matt Exp $ */
22fe8fb19SBen Gras 
32fe8fb19SBen Gras /*
42fe8fb19SBen Gras  * This version hacked for use with gcc -msoft-float by bjh21.
52fe8fb19SBen Gras  * (Mostly a case of #ifdefing out things GCC doesn't need or provides
62fe8fb19SBen Gras  *  itself).
72fe8fb19SBen Gras  */
82fe8fb19SBen Gras 
92fe8fb19SBen Gras /*
102fe8fb19SBen Gras  * Things you may want to define:
112fe8fb19SBen Gras  *
122fe8fb19SBen Gras  * SOFTFLOAT_FOR_GCC - build only those functions necessary for GCC (with
132fe8fb19SBen Gras  *   -msoft-float) to work.  Include "softfloat-for-gcc.h" to get them
142fe8fb19SBen Gras  *   properly renamed.
152fe8fb19SBen Gras  */
162fe8fb19SBen Gras 
172fe8fb19SBen Gras /*
182fe8fb19SBen Gras  * This differs from the standard bits32/softfloat.c in that float64
192fe8fb19SBen Gras  * is defined to be a 64-bit integer rather than a structure.  The
202fe8fb19SBen Gras  * structure is float64s, with translation between the two going via
212fe8fb19SBen Gras  * float64u.
222fe8fb19SBen Gras  */
232fe8fb19SBen Gras 
242fe8fb19SBen Gras /*
252fe8fb19SBen Gras ===============================================================================
262fe8fb19SBen Gras 
272fe8fb19SBen Gras This C source file is part of the SoftFloat IEC/IEEE Floating-Point
282fe8fb19SBen Gras Arithmetic Package, Release 2a.
292fe8fb19SBen Gras 
302fe8fb19SBen Gras Written by John R. Hauser.  This work was made possible in part by the
312fe8fb19SBen Gras International Computer Science Institute, located at Suite 600, 1947 Center
322fe8fb19SBen Gras Street, Berkeley, California 94704.  Funding was partially provided by the
332fe8fb19SBen Gras National Science Foundation under grant MIP-9311980.  The original version
342fe8fb19SBen Gras of this code was written as part of a project to build a fixed-point vector
352fe8fb19SBen Gras processor in collaboration with the University of California at Berkeley,
362fe8fb19SBen Gras overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
372fe8fb19SBen Gras is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
382fe8fb19SBen Gras arithmetic/SoftFloat.html'.
392fe8fb19SBen Gras 
402fe8fb19SBen Gras THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
412fe8fb19SBen Gras has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
422fe8fb19SBen Gras TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
432fe8fb19SBen Gras PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
442fe8fb19SBen Gras AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
452fe8fb19SBen Gras 
462fe8fb19SBen Gras Derivative works are acceptable, even for commercial purposes, so long as
472fe8fb19SBen Gras (1) they include prominent notice that the work is derivative, and (2) they
482fe8fb19SBen Gras include prominent notice akin to these four paragraphs for those parts of
492fe8fb19SBen Gras this code that are retained.
502fe8fb19SBen Gras 
512fe8fb19SBen Gras ===============================================================================
522fe8fb19SBen Gras */
532fe8fb19SBen Gras 
542fe8fb19SBen Gras #include <sys/cdefs.h>
552fe8fb19SBen Gras #if defined(LIBC_SCCS) && !defined(lint)
56*84d9c625SLionel Sambuc __RCSID("$NetBSD: softfloat.c,v 1.3 2013/01/10 08:16:11 matt Exp $");
572fe8fb19SBen Gras #endif /* LIBC_SCCS and not lint */
582fe8fb19SBen Gras 
592fe8fb19SBen Gras #ifdef SOFTFLOAT_FOR_GCC
602fe8fb19SBen Gras #include "softfloat-for-gcc.h"
612fe8fb19SBen Gras #endif
622fe8fb19SBen Gras 
632fe8fb19SBen Gras #include "milieu.h"
642fe8fb19SBen Gras #include "softfloat.h"
652fe8fb19SBen Gras 
662fe8fb19SBen Gras /*
672fe8fb19SBen Gras  * Conversions between floats as stored in memory and floats as
682fe8fb19SBen Gras  * SoftFloat uses them
692fe8fb19SBen Gras  */
702fe8fb19SBen Gras #ifndef FLOAT64_DEMANGLE
712fe8fb19SBen Gras #define FLOAT64_DEMANGLE(a)	(a)
722fe8fb19SBen Gras #endif
732fe8fb19SBen Gras #ifndef FLOAT64_MANGLE
742fe8fb19SBen Gras #define FLOAT64_MANGLE(a)	(a)
752fe8fb19SBen Gras #endif
762fe8fb19SBen Gras 
772fe8fb19SBen Gras /*
782fe8fb19SBen Gras -------------------------------------------------------------------------------
792fe8fb19SBen Gras Floating-point rounding mode and exception flags.
802fe8fb19SBen Gras -------------------------------------------------------------------------------
812fe8fb19SBen Gras */
82*84d9c625SLionel Sambuc #ifndef set_float_rounding_mode
832fe8fb19SBen Gras fp_rnd float_rounding_mode = float_round_nearest_even;
842fe8fb19SBen Gras fp_except float_exception_flags = 0;
85*84d9c625SLionel Sambuc #endif
86*84d9c625SLionel Sambuc #ifndef set_float_exception_inexact_flag
87*84d9c625SLionel Sambuc #define set_float_exception_inexact_flag() \
88*84d9c625SLionel Sambuc 	((void)(float_exception_flags |= float_flag_inexact))
89*84d9c625SLionel Sambuc #endif
902fe8fb19SBen Gras 
912fe8fb19SBen Gras /*
922fe8fb19SBen Gras -------------------------------------------------------------------------------
932fe8fb19SBen Gras Primitive arithmetic functions, including multi-word arithmetic, and
942fe8fb19SBen Gras division and square root approximations.  (Can be specialized to target if
952fe8fb19SBen Gras desired.)
962fe8fb19SBen Gras -------------------------------------------------------------------------------
972fe8fb19SBen Gras */
982fe8fb19SBen Gras #include "softfloat-macros"
992fe8fb19SBen Gras 
1002fe8fb19SBen Gras /*
1012fe8fb19SBen Gras -------------------------------------------------------------------------------
1022fe8fb19SBen Gras Functions and definitions to determine:  (1) whether tininess for underflow
1032fe8fb19SBen Gras is detected before or after rounding by default, (2) what (if anything)
1042fe8fb19SBen Gras happens when exceptions are raised, (3) how signaling NaNs are distinguished
1052fe8fb19SBen Gras from quiet NaNs, (4) the default generated quiet NaNs, and (4) how NaNs
1062fe8fb19SBen Gras are propagated from function inputs to output.  These details are target-
1072fe8fb19SBen Gras specific.
1082fe8fb19SBen Gras -------------------------------------------------------------------------------
1092fe8fb19SBen Gras */
1102fe8fb19SBen Gras #include "softfloat-specialize"
1112fe8fb19SBen Gras 
1122fe8fb19SBen Gras /*
1132fe8fb19SBen Gras -------------------------------------------------------------------------------
1142fe8fb19SBen Gras Returns the fraction bits of the single-precision floating-point value `a'.
1152fe8fb19SBen Gras -------------------------------------------------------------------------------
1162fe8fb19SBen Gras */
extractFloat32Frac(float32 a)1172fe8fb19SBen Gras INLINE bits32 extractFloat32Frac( float32 a )
1182fe8fb19SBen Gras {
1192fe8fb19SBen Gras 
1202fe8fb19SBen Gras     return a & 0x007FFFFF;
1212fe8fb19SBen Gras 
1222fe8fb19SBen Gras }
1232fe8fb19SBen Gras 
1242fe8fb19SBen Gras /*
1252fe8fb19SBen Gras -------------------------------------------------------------------------------
1262fe8fb19SBen Gras Returns the exponent bits of the single-precision floating-point value `a'.
1272fe8fb19SBen Gras -------------------------------------------------------------------------------
1282fe8fb19SBen Gras */
extractFloat32Exp(float32 a)1292fe8fb19SBen Gras INLINE int16 extractFloat32Exp( float32 a )
1302fe8fb19SBen Gras {
1312fe8fb19SBen Gras 
1322fe8fb19SBen Gras     return ( a>>23 ) & 0xFF;
1332fe8fb19SBen Gras 
1342fe8fb19SBen Gras }
1352fe8fb19SBen Gras 
1362fe8fb19SBen Gras /*
1372fe8fb19SBen Gras -------------------------------------------------------------------------------
1382fe8fb19SBen Gras Returns the sign bit of the single-precision floating-point value `a'.
1392fe8fb19SBen Gras -------------------------------------------------------------------------------
1402fe8fb19SBen Gras */
extractFloat32Sign(float32 a)1412fe8fb19SBen Gras INLINE flag extractFloat32Sign( float32 a )
1422fe8fb19SBen Gras {
1432fe8fb19SBen Gras 
1442fe8fb19SBen Gras     return a>>31;
1452fe8fb19SBen Gras 
1462fe8fb19SBen Gras }
1472fe8fb19SBen Gras 
1482fe8fb19SBen Gras /*
1492fe8fb19SBen Gras -------------------------------------------------------------------------------
1502fe8fb19SBen Gras Normalizes the subnormal single-precision floating-point value represented
1512fe8fb19SBen Gras by the denormalized significand `aSig'.  The normalized exponent and
1522fe8fb19SBen Gras significand are stored at the locations pointed to by `zExpPtr' and
1532fe8fb19SBen Gras `zSigPtr', respectively.
1542fe8fb19SBen Gras -------------------------------------------------------------------------------
1552fe8fb19SBen Gras */
1562fe8fb19SBen Gras static void
normalizeFloat32Subnormal(bits32 aSig,int16 * zExpPtr,bits32 * zSigPtr)1572fe8fb19SBen Gras  normalizeFloat32Subnormal( bits32 aSig, int16 *zExpPtr, bits32 *zSigPtr )
1582fe8fb19SBen Gras {
1592fe8fb19SBen Gras     int8 shiftCount;
1602fe8fb19SBen Gras 
1612fe8fb19SBen Gras     shiftCount = countLeadingZeros32( aSig ) - 8;
1622fe8fb19SBen Gras     *zSigPtr = aSig<<shiftCount;
1632fe8fb19SBen Gras     *zExpPtr = 1 - shiftCount;
1642fe8fb19SBen Gras 
1652fe8fb19SBen Gras }
1662fe8fb19SBen Gras 
1672fe8fb19SBen Gras /*
1682fe8fb19SBen Gras -------------------------------------------------------------------------------
1692fe8fb19SBen Gras Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
1702fe8fb19SBen Gras single-precision floating-point value, returning the result.  After being
1712fe8fb19SBen Gras shifted into the proper positions, the three fields are simply added
1722fe8fb19SBen Gras together to form the result.  This means that any integer portion of `zSig'
1732fe8fb19SBen Gras will be added into the exponent.  Since a properly normalized significand
1742fe8fb19SBen Gras will have an integer portion equal to 1, the `zExp' input should be 1 less
1752fe8fb19SBen Gras than the desired result exponent whenever `zSig' is a complete, normalized
1762fe8fb19SBen Gras significand.
1772fe8fb19SBen Gras -------------------------------------------------------------------------------
1782fe8fb19SBen Gras */
packFloat32(flag zSign,int16 zExp,bits32 zSig)1792fe8fb19SBen Gras INLINE float32 packFloat32( flag zSign, int16 zExp, bits32 zSig )
1802fe8fb19SBen Gras {
1812fe8fb19SBen Gras 
1822fe8fb19SBen Gras     return ( ( (bits32) zSign )<<31 ) + ( ( (bits32) zExp )<<23 ) + zSig;
1832fe8fb19SBen Gras 
1842fe8fb19SBen Gras }
1852fe8fb19SBen Gras 
1862fe8fb19SBen Gras /*
1872fe8fb19SBen Gras -------------------------------------------------------------------------------
1882fe8fb19SBen Gras Takes an abstract floating-point value having sign `zSign', exponent `zExp',
1892fe8fb19SBen Gras and significand `zSig', and returns the proper single-precision floating-
1902fe8fb19SBen Gras point value corresponding to the abstract input.  Ordinarily, the abstract
1912fe8fb19SBen Gras value is simply rounded and packed into the single-precision format, with
1922fe8fb19SBen Gras the inexact exception raised if the abstract input cannot be represented
1932fe8fb19SBen Gras exactly.  However, if the abstract value is too large, the overflow and
1942fe8fb19SBen Gras inexact exceptions are raised and an infinity or maximal finite value is
1952fe8fb19SBen Gras returned.  If the abstract value is too small, the input value is rounded to
1962fe8fb19SBen Gras a subnormal number, and the underflow and inexact exceptions are raised if
1972fe8fb19SBen Gras the abstract input cannot be represented exactly as a subnormal single-
1982fe8fb19SBen Gras precision floating-point number.
1992fe8fb19SBen Gras     The input significand `zSig' has its binary point between bits 30
2002fe8fb19SBen Gras and 29, which is 7 bits to the left of the usual location.  This shifted
2012fe8fb19SBen Gras significand must be normalized or smaller.  If `zSig' is not normalized,
2022fe8fb19SBen Gras `zExp' must be 0; in that case, the result returned is a subnormal number,
2032fe8fb19SBen Gras and it must not require rounding.  In the usual case that `zSig' is
2042fe8fb19SBen Gras normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
2052fe8fb19SBen Gras The handling of underflow and overflow follows the IEC/IEEE Standard for
2062fe8fb19SBen Gras Binary Floating-Point Arithmetic.
2072fe8fb19SBen Gras -------------------------------------------------------------------------------
2082fe8fb19SBen Gras */
roundAndPackFloat32(flag zSign,int16 zExp,bits32 zSig)2092fe8fb19SBen Gras static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig )
2102fe8fb19SBen Gras {
2112fe8fb19SBen Gras     int8 roundingMode;
2122fe8fb19SBen Gras     flag roundNearestEven;
2132fe8fb19SBen Gras     int8 roundIncrement, roundBits;
2142fe8fb19SBen Gras     flag isTiny;
2152fe8fb19SBen Gras 
2162fe8fb19SBen Gras     roundingMode = float_rounding_mode;
2172fe8fb19SBen Gras     roundNearestEven = roundingMode == float_round_nearest_even;
2182fe8fb19SBen Gras     roundIncrement = 0x40;
2192fe8fb19SBen Gras     if ( ! roundNearestEven ) {
2202fe8fb19SBen Gras         if ( roundingMode == float_round_to_zero ) {
2212fe8fb19SBen Gras             roundIncrement = 0;
2222fe8fb19SBen Gras         }
2232fe8fb19SBen Gras         else {
2242fe8fb19SBen Gras             roundIncrement = 0x7F;
2252fe8fb19SBen Gras             if ( zSign ) {
2262fe8fb19SBen Gras                 if ( roundingMode == float_round_up ) roundIncrement = 0;
2272fe8fb19SBen Gras             }
2282fe8fb19SBen Gras             else {
2292fe8fb19SBen Gras                 if ( roundingMode == float_round_down ) roundIncrement = 0;
2302fe8fb19SBen Gras             }
2312fe8fb19SBen Gras         }
2322fe8fb19SBen Gras     }
2332fe8fb19SBen Gras     roundBits = zSig & 0x7F;
2342fe8fb19SBen Gras     if ( 0xFD <= (bits16) zExp ) {
2352fe8fb19SBen Gras         if (    ( 0xFD < zExp )
2362fe8fb19SBen Gras              || (    ( zExp == 0xFD )
2372fe8fb19SBen Gras                   && ( (sbits32) ( zSig + roundIncrement ) < 0 ) )
2382fe8fb19SBen Gras            ) {
2392fe8fb19SBen Gras             float_raise( float_flag_overflow | float_flag_inexact );
2402fe8fb19SBen Gras             return packFloat32( zSign, 0xFF, 0 ) - ( roundIncrement == 0 );
2412fe8fb19SBen Gras         }
2422fe8fb19SBen Gras         if ( zExp < 0 ) {
2432fe8fb19SBen Gras             isTiny =
2442fe8fb19SBen Gras                    ( float_detect_tininess == float_tininess_before_rounding )
2452fe8fb19SBen Gras                 || ( zExp < -1 )
246f14fb602SLionel Sambuc                 || ( zSig + roundIncrement < (uint32)0x80000000 );
2472fe8fb19SBen Gras             shift32RightJamming( zSig, - zExp, &zSig );
2482fe8fb19SBen Gras             zExp = 0;
2492fe8fb19SBen Gras             roundBits = zSig & 0x7F;
2502fe8fb19SBen Gras             if ( isTiny && roundBits ) float_raise( float_flag_underflow );
2512fe8fb19SBen Gras         }
2522fe8fb19SBen Gras     }
253*84d9c625SLionel Sambuc     if ( roundBits ) set_float_exception_inexact_flag();
2542fe8fb19SBen Gras     zSig = ( zSig + roundIncrement )>>7;
2552fe8fb19SBen Gras     zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
2562fe8fb19SBen Gras     if ( zSig == 0 ) zExp = 0;
2572fe8fb19SBen Gras     return packFloat32( zSign, zExp, zSig );
2582fe8fb19SBen Gras 
2592fe8fb19SBen Gras }
2602fe8fb19SBen Gras 
2612fe8fb19SBen Gras /*
2622fe8fb19SBen Gras -------------------------------------------------------------------------------
2632fe8fb19SBen Gras Takes an abstract floating-point value having sign `zSign', exponent `zExp',
2642fe8fb19SBen Gras and significand `zSig', and returns the proper single-precision floating-
2652fe8fb19SBen Gras point value corresponding to the abstract input.  This routine is just like
2662fe8fb19SBen Gras `roundAndPackFloat32' except that `zSig' does not have to be normalized.
2672fe8fb19SBen Gras Bit 31 of `zSig' must be zero, and `zExp' must be 1 less than the ``true''
2682fe8fb19SBen Gras floating-point exponent.
2692fe8fb19SBen Gras -------------------------------------------------------------------------------
2702fe8fb19SBen Gras */
2712fe8fb19SBen Gras static float32
normalizeRoundAndPackFloat32(flag zSign,int16 zExp,bits32 zSig)2722fe8fb19SBen Gras  normalizeRoundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig )
2732fe8fb19SBen Gras {
2742fe8fb19SBen Gras     int8 shiftCount;
2752fe8fb19SBen Gras 
2762fe8fb19SBen Gras     shiftCount = countLeadingZeros32( zSig ) - 1;
2772fe8fb19SBen Gras     return roundAndPackFloat32( zSign, zExp - shiftCount, zSig<<shiftCount );
2782fe8fb19SBen Gras 
2792fe8fb19SBen Gras }
2802fe8fb19SBen Gras 
2812fe8fb19SBen Gras /*
2822fe8fb19SBen Gras -------------------------------------------------------------------------------
2832fe8fb19SBen Gras Returns the least-significant 32 fraction bits of the double-precision
2842fe8fb19SBen Gras floating-point value `a'.
2852fe8fb19SBen Gras -------------------------------------------------------------------------------
2862fe8fb19SBen Gras */
extractFloat64Frac1(float64 a)2872fe8fb19SBen Gras INLINE bits32 extractFloat64Frac1( float64 a )
2882fe8fb19SBen Gras {
2892fe8fb19SBen Gras 
290f14fb602SLionel Sambuc     return (bits32)(FLOAT64_DEMANGLE(a) & LIT64(0x00000000FFFFFFFF));
2912fe8fb19SBen Gras 
2922fe8fb19SBen Gras }
2932fe8fb19SBen Gras 
2942fe8fb19SBen Gras /*
2952fe8fb19SBen Gras -------------------------------------------------------------------------------
2962fe8fb19SBen Gras Returns the most-significant 20 fraction bits of the double-precision
2972fe8fb19SBen Gras floating-point value `a'.
2982fe8fb19SBen Gras -------------------------------------------------------------------------------
2992fe8fb19SBen Gras */
extractFloat64Frac0(float64 a)3002fe8fb19SBen Gras INLINE bits32 extractFloat64Frac0( float64 a )
3012fe8fb19SBen Gras {
3022fe8fb19SBen Gras 
303f14fb602SLionel Sambuc     return (bits32)((FLOAT64_DEMANGLE(a) >> 32) & 0x000FFFFF);
3042fe8fb19SBen Gras 
3052fe8fb19SBen Gras }
3062fe8fb19SBen Gras 
3072fe8fb19SBen Gras /*
3082fe8fb19SBen Gras -------------------------------------------------------------------------------
3092fe8fb19SBen Gras Returns the exponent bits of the double-precision floating-point value `a'.
3102fe8fb19SBen Gras -------------------------------------------------------------------------------
3112fe8fb19SBen Gras */
extractFloat64Exp(float64 a)3122fe8fb19SBen Gras INLINE int16 extractFloat64Exp( float64 a )
3132fe8fb19SBen Gras {
3142fe8fb19SBen Gras 
315f14fb602SLionel Sambuc     return (int16)((FLOAT64_DEMANGLE(a) >> 52) & 0x7FF);
3162fe8fb19SBen Gras 
3172fe8fb19SBen Gras }
3182fe8fb19SBen Gras 
3192fe8fb19SBen Gras /*
3202fe8fb19SBen Gras -------------------------------------------------------------------------------
3212fe8fb19SBen Gras Returns the sign bit of the double-precision floating-point value `a'.
3222fe8fb19SBen Gras -------------------------------------------------------------------------------
3232fe8fb19SBen Gras */
extractFloat64Sign(float64 a)3242fe8fb19SBen Gras INLINE flag extractFloat64Sign( float64 a )
3252fe8fb19SBen Gras {
3262fe8fb19SBen Gras 
327f14fb602SLionel Sambuc     return (flag)(FLOAT64_DEMANGLE(a) >> 63);
3282fe8fb19SBen Gras 
3292fe8fb19SBen Gras }
3302fe8fb19SBen Gras 
3312fe8fb19SBen Gras /*
3322fe8fb19SBen Gras -------------------------------------------------------------------------------
3332fe8fb19SBen Gras Normalizes the subnormal double-precision floating-point value represented
3342fe8fb19SBen Gras by the denormalized significand formed by the concatenation of `aSig0' and
3352fe8fb19SBen Gras `aSig1'.  The normalized exponent is stored at the location pointed to by
3362fe8fb19SBen Gras `zExpPtr'.  The most significant 21 bits of the normalized significand are
3372fe8fb19SBen Gras stored at the location pointed to by `zSig0Ptr', and the least significant
3382fe8fb19SBen Gras 32 bits of the normalized significand are stored at the location pointed to
3392fe8fb19SBen Gras by `zSig1Ptr'.
3402fe8fb19SBen Gras -------------------------------------------------------------------------------
3412fe8fb19SBen Gras */
3422fe8fb19SBen Gras static void
normalizeFloat64Subnormal(bits32 aSig0,bits32 aSig1,int16 * zExpPtr,bits32 * zSig0Ptr,bits32 * zSig1Ptr)3432fe8fb19SBen Gras  normalizeFloat64Subnormal(
3442fe8fb19SBen Gras      bits32 aSig0,
3452fe8fb19SBen Gras      bits32 aSig1,
3462fe8fb19SBen Gras      int16 *zExpPtr,
3472fe8fb19SBen Gras      bits32 *zSig0Ptr,
3482fe8fb19SBen Gras      bits32 *zSig1Ptr
3492fe8fb19SBen Gras  )
3502fe8fb19SBen Gras {
3512fe8fb19SBen Gras     int8 shiftCount;
3522fe8fb19SBen Gras 
3532fe8fb19SBen Gras     if ( aSig0 == 0 ) {
3542fe8fb19SBen Gras         shiftCount = countLeadingZeros32( aSig1 ) - 11;
3552fe8fb19SBen Gras         if ( shiftCount < 0 ) {
3562fe8fb19SBen Gras             *zSig0Ptr = aSig1>>( - shiftCount );
3572fe8fb19SBen Gras             *zSig1Ptr = aSig1<<( shiftCount & 31 );
3582fe8fb19SBen Gras         }
3592fe8fb19SBen Gras         else {
3602fe8fb19SBen Gras             *zSig0Ptr = aSig1<<shiftCount;
3612fe8fb19SBen Gras             *zSig1Ptr = 0;
3622fe8fb19SBen Gras         }
3632fe8fb19SBen Gras         *zExpPtr = - shiftCount - 31;
3642fe8fb19SBen Gras     }
3652fe8fb19SBen Gras     else {
3662fe8fb19SBen Gras         shiftCount = countLeadingZeros32( aSig0 ) - 11;
3672fe8fb19SBen Gras         shortShift64Left( aSig0, aSig1, shiftCount, zSig0Ptr, zSig1Ptr );
3682fe8fb19SBen Gras         *zExpPtr = 1 - shiftCount;
3692fe8fb19SBen Gras     }
3702fe8fb19SBen Gras 
3712fe8fb19SBen Gras }
3722fe8fb19SBen Gras 
3732fe8fb19SBen Gras /*
3742fe8fb19SBen Gras -------------------------------------------------------------------------------
3752fe8fb19SBen Gras Packs the sign `zSign', the exponent `zExp', and the significand formed by
3762fe8fb19SBen Gras the concatenation of `zSig0' and `zSig1' into a double-precision floating-
3772fe8fb19SBen Gras point value, returning the result.  After being shifted into the proper
3782fe8fb19SBen Gras positions, the three fields `zSign', `zExp', and `zSig0' are simply added
3792fe8fb19SBen Gras together to form the most significant 32 bits of the result.  This means
3802fe8fb19SBen Gras that any integer portion of `zSig0' will be added into the exponent.  Since
3812fe8fb19SBen Gras a properly normalized significand will have an integer portion equal to 1,
3822fe8fb19SBen Gras the `zExp' input should be 1 less than the desired result exponent whenever
3832fe8fb19SBen Gras `zSig0' and `zSig1' concatenated form a complete, normalized significand.
3842fe8fb19SBen Gras -------------------------------------------------------------------------------
3852fe8fb19SBen Gras */
3862fe8fb19SBen Gras INLINE float64
packFloat64(flag zSign,int16 zExp,bits32 zSig0,bits32 zSig1)3872fe8fb19SBen Gras  packFloat64( flag zSign, int16 zExp, bits32 zSig0, bits32 zSig1 )
3882fe8fb19SBen Gras {
3892fe8fb19SBen Gras 
3902fe8fb19SBen Gras     return FLOAT64_MANGLE( ( ( (bits64) zSign )<<63 ) +
3912fe8fb19SBen Gras 			   ( ( (bits64) zExp )<<52 ) +
3922fe8fb19SBen Gras 			   ( ( (bits64) zSig0 )<<32 ) + zSig1 );
3932fe8fb19SBen Gras 
3942fe8fb19SBen Gras 
3952fe8fb19SBen Gras }
3962fe8fb19SBen Gras 
3972fe8fb19SBen Gras /*
3982fe8fb19SBen Gras -------------------------------------------------------------------------------
3992fe8fb19SBen Gras Takes an abstract floating-point value having sign `zSign', exponent `zExp',
4002fe8fb19SBen Gras and extended significand formed by the concatenation of `zSig0', `zSig1',
4012fe8fb19SBen Gras and `zSig2', and returns the proper double-precision floating-point value
4022fe8fb19SBen Gras corresponding to the abstract input.  Ordinarily, the abstract value is
4032fe8fb19SBen Gras simply rounded and packed into the double-precision format, with the inexact
4042fe8fb19SBen Gras exception raised if the abstract input cannot be represented exactly.
4052fe8fb19SBen Gras However, if the abstract value is too large, the overflow and inexact
4062fe8fb19SBen Gras exceptions are raised and an infinity or maximal finite value is returned.
4072fe8fb19SBen Gras If the abstract value is too small, the input value is rounded to a
4082fe8fb19SBen Gras subnormal number, and the underflow and inexact exceptions are raised if the
4092fe8fb19SBen Gras abstract input cannot be represented exactly as a subnormal double-precision
4102fe8fb19SBen Gras floating-point number.
4112fe8fb19SBen Gras     The input significand must be normalized or smaller.  If the input
4122fe8fb19SBen Gras significand is not normalized, `zExp' must be 0; in that case, the result
4132fe8fb19SBen Gras returned is a subnormal number, and it must not require rounding.  In the
4142fe8fb19SBen Gras usual case that the input significand is normalized, `zExp' must be 1 less
4152fe8fb19SBen Gras than the ``true'' floating-point exponent.  The handling of underflow and
4162fe8fb19SBen Gras overflow follows the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
4172fe8fb19SBen Gras -------------------------------------------------------------------------------
4182fe8fb19SBen Gras */
4192fe8fb19SBen Gras static float64
roundAndPackFloat64(flag zSign,int16 zExp,bits32 zSig0,bits32 zSig1,bits32 zSig2)4202fe8fb19SBen Gras  roundAndPackFloat64(
4212fe8fb19SBen Gras      flag zSign, int16 zExp, bits32 zSig0, bits32 zSig1, bits32 zSig2 )
4222fe8fb19SBen Gras {
4232fe8fb19SBen Gras     int8 roundingMode;
4242fe8fb19SBen Gras     flag roundNearestEven, increment, isTiny;
4252fe8fb19SBen Gras 
4262fe8fb19SBen Gras     roundingMode = float_rounding_mode;
4272fe8fb19SBen Gras     roundNearestEven = ( roundingMode == float_round_nearest_even );
4282fe8fb19SBen Gras     increment = ( (sbits32) zSig2 < 0 );
4292fe8fb19SBen Gras     if ( ! roundNearestEven ) {
4302fe8fb19SBen Gras         if ( roundingMode == float_round_to_zero ) {
4312fe8fb19SBen Gras             increment = 0;
4322fe8fb19SBen Gras         }
4332fe8fb19SBen Gras         else {
4342fe8fb19SBen Gras             if ( zSign ) {
4352fe8fb19SBen Gras                 increment = ( roundingMode == float_round_down ) && zSig2;
4362fe8fb19SBen Gras             }
4372fe8fb19SBen Gras             else {
4382fe8fb19SBen Gras                 increment = ( roundingMode == float_round_up ) && zSig2;
4392fe8fb19SBen Gras             }
4402fe8fb19SBen Gras         }
4412fe8fb19SBen Gras     }
4422fe8fb19SBen Gras     if ( 0x7FD <= (bits16) zExp ) {
4432fe8fb19SBen Gras         if (    ( 0x7FD < zExp )
4442fe8fb19SBen Gras              || (    ( zExp == 0x7FD )
4452fe8fb19SBen Gras                   && eq64( 0x001FFFFF, 0xFFFFFFFF, zSig0, zSig1 )
4462fe8fb19SBen Gras                   && increment
4472fe8fb19SBen Gras                 )
4482fe8fb19SBen Gras            ) {
4492fe8fb19SBen Gras             float_raise( float_flag_overflow | float_flag_inexact );
4502fe8fb19SBen Gras             if (    ( roundingMode == float_round_to_zero )
4512fe8fb19SBen Gras                  || ( zSign && ( roundingMode == float_round_up ) )
4522fe8fb19SBen Gras                  || ( ! zSign && ( roundingMode == float_round_down ) )
4532fe8fb19SBen Gras                ) {
4542fe8fb19SBen Gras                 return packFloat64( zSign, 0x7FE, 0x000FFFFF, 0xFFFFFFFF );
4552fe8fb19SBen Gras             }
4562fe8fb19SBen Gras             return packFloat64( zSign, 0x7FF, 0, 0 );
4572fe8fb19SBen Gras         }
4582fe8fb19SBen Gras         if ( zExp < 0 ) {
4592fe8fb19SBen Gras             isTiny =
4602fe8fb19SBen Gras                    ( float_detect_tininess == float_tininess_before_rounding )
4612fe8fb19SBen Gras                 || ( zExp < -1 )
4622fe8fb19SBen Gras                 || ! increment
4632fe8fb19SBen Gras                 || lt64( zSig0, zSig1, 0x001FFFFF, 0xFFFFFFFF );
4642fe8fb19SBen Gras             shift64ExtraRightJamming(
4652fe8fb19SBen Gras                 zSig0, zSig1, zSig2, - zExp, &zSig0, &zSig1, &zSig2 );
4662fe8fb19SBen Gras             zExp = 0;
4672fe8fb19SBen Gras             if ( isTiny && zSig2 ) float_raise( float_flag_underflow );
4682fe8fb19SBen Gras             if ( roundNearestEven ) {
4692fe8fb19SBen Gras                 increment = ( (sbits32) zSig2 < 0 );
4702fe8fb19SBen Gras             }
4712fe8fb19SBen Gras             else {
4722fe8fb19SBen Gras                 if ( zSign ) {
4732fe8fb19SBen Gras                     increment = ( roundingMode == float_round_down ) && zSig2;
4742fe8fb19SBen Gras                 }
4752fe8fb19SBen Gras                 else {
4762fe8fb19SBen Gras                     increment = ( roundingMode == float_round_up ) && zSig2;
4772fe8fb19SBen Gras                 }
4782fe8fb19SBen Gras             }
4792fe8fb19SBen Gras         }
4802fe8fb19SBen Gras     }
481*84d9c625SLionel Sambuc     if ( zSig2 ) set_float_exception_inexact_flag();
4822fe8fb19SBen Gras     if ( increment ) {
4832fe8fb19SBen Gras         add64( zSig0, zSig1, 0, 1, &zSig0, &zSig1 );
4842fe8fb19SBen Gras         zSig1 &= ~ ( ( zSig2 + zSig2 == 0 ) & roundNearestEven );
4852fe8fb19SBen Gras     }
4862fe8fb19SBen Gras     else {
4872fe8fb19SBen Gras         if ( ( zSig0 | zSig1 ) == 0 ) zExp = 0;
4882fe8fb19SBen Gras     }
4892fe8fb19SBen Gras     return packFloat64( zSign, zExp, zSig0, zSig1 );
4902fe8fb19SBen Gras 
4912fe8fb19SBen Gras }
4922fe8fb19SBen Gras 
4932fe8fb19SBen Gras /*
4942fe8fb19SBen Gras -------------------------------------------------------------------------------
4952fe8fb19SBen Gras Takes an abstract floating-point value having sign `zSign', exponent `zExp',
4962fe8fb19SBen Gras and significand formed by the concatenation of `zSig0' and `zSig1', and
4972fe8fb19SBen Gras returns the proper double-precision floating-point value corresponding
4982fe8fb19SBen Gras to the abstract input.  This routine is just like `roundAndPackFloat64'
4992fe8fb19SBen Gras except that the input significand has fewer bits and does not have to be
5002fe8fb19SBen Gras normalized.  In all cases, `zExp' must be 1 less than the ``true'' floating-
5012fe8fb19SBen Gras point exponent.
5022fe8fb19SBen Gras -------------------------------------------------------------------------------
5032fe8fb19SBen Gras */
5042fe8fb19SBen Gras static float64
normalizeRoundAndPackFloat64(flag zSign,int16 zExp,bits32 zSig0,bits32 zSig1)5052fe8fb19SBen Gras  normalizeRoundAndPackFloat64(
5062fe8fb19SBen Gras      flag zSign, int16 zExp, bits32 zSig0, bits32 zSig1 )
5072fe8fb19SBen Gras {
5082fe8fb19SBen Gras     int8 shiftCount;
5092fe8fb19SBen Gras     bits32 zSig2;
5102fe8fb19SBen Gras 
5112fe8fb19SBen Gras     if ( zSig0 == 0 ) {
5122fe8fb19SBen Gras         zSig0 = zSig1;
5132fe8fb19SBen Gras         zSig1 = 0;
5142fe8fb19SBen Gras         zExp -= 32;
5152fe8fb19SBen Gras     }
5162fe8fb19SBen Gras     shiftCount = countLeadingZeros32( zSig0 ) - 11;
5172fe8fb19SBen Gras     if ( 0 <= shiftCount ) {
5182fe8fb19SBen Gras         zSig2 = 0;
5192fe8fb19SBen Gras         shortShift64Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
5202fe8fb19SBen Gras     }
5212fe8fb19SBen Gras     else {
5222fe8fb19SBen Gras         shift64ExtraRightJamming(
5232fe8fb19SBen Gras             zSig0, zSig1, 0, - shiftCount, &zSig0, &zSig1, &zSig2 );
5242fe8fb19SBen Gras     }
5252fe8fb19SBen Gras     zExp -= shiftCount;
5262fe8fb19SBen Gras     return roundAndPackFloat64( zSign, zExp, zSig0, zSig1, zSig2 );
5272fe8fb19SBen Gras 
5282fe8fb19SBen Gras }
5292fe8fb19SBen Gras 
5302fe8fb19SBen Gras /*
5312fe8fb19SBen Gras -------------------------------------------------------------------------------
5322fe8fb19SBen Gras Returns the result of converting the 32-bit two's complement integer `a' to
5332fe8fb19SBen Gras the single-precision floating-point format.  The conversion is performed
5342fe8fb19SBen Gras according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
5352fe8fb19SBen Gras -------------------------------------------------------------------------------
5362fe8fb19SBen Gras */
int32_to_float32(int32 a)5372fe8fb19SBen Gras float32 int32_to_float32( int32 a )
5382fe8fb19SBen Gras {
5392fe8fb19SBen Gras     flag zSign;
5402fe8fb19SBen Gras 
5412fe8fb19SBen Gras     if ( a == 0 ) return 0;
5422fe8fb19SBen Gras     if ( a == (sbits32) 0x80000000 ) return packFloat32( 1, 0x9E, 0 );
5432fe8fb19SBen Gras     zSign = ( a < 0 );
544f14fb602SLionel Sambuc     return normalizeRoundAndPackFloat32(zSign, 0x9C, (uint32)(zSign ? - a : a));
5452fe8fb19SBen Gras 
5462fe8fb19SBen Gras }
5472fe8fb19SBen Gras 
5482fe8fb19SBen Gras /*
5492fe8fb19SBen Gras -------------------------------------------------------------------------------
5502fe8fb19SBen Gras Returns the result of converting the 32-bit two's complement integer `a' to
5512fe8fb19SBen Gras the double-precision floating-point format.  The conversion is performed
5522fe8fb19SBen Gras according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
5532fe8fb19SBen Gras -------------------------------------------------------------------------------
5542fe8fb19SBen Gras */
int32_to_float64(int32 a)5552fe8fb19SBen Gras float64 int32_to_float64( int32 a )
5562fe8fb19SBen Gras {
5572fe8fb19SBen Gras     flag zSign;
5582fe8fb19SBen Gras     bits32 absA;
5592fe8fb19SBen Gras     int8 shiftCount;
5602fe8fb19SBen Gras     bits32 zSig0, zSig1;
5612fe8fb19SBen Gras 
5622fe8fb19SBen Gras     if ( a == 0 ) return packFloat64( 0, 0, 0, 0 );
5632fe8fb19SBen Gras     zSign = ( a < 0 );
5642fe8fb19SBen Gras     absA = zSign ? - a : a;
5652fe8fb19SBen Gras     shiftCount = countLeadingZeros32( absA ) - 11;
5662fe8fb19SBen Gras     if ( 0 <= shiftCount ) {
5672fe8fb19SBen Gras         zSig0 = absA<<shiftCount;
5682fe8fb19SBen Gras         zSig1 = 0;
5692fe8fb19SBen Gras     }
5702fe8fb19SBen Gras     else {
5712fe8fb19SBen Gras         shift64Right( absA, 0, - shiftCount, &zSig0, &zSig1 );
5722fe8fb19SBen Gras     }
5732fe8fb19SBen Gras     return packFloat64( zSign, 0x412 - shiftCount, zSig0, zSig1 );
5742fe8fb19SBen Gras 
5752fe8fb19SBen Gras }
5762fe8fb19SBen Gras 
5772fe8fb19SBen Gras #ifndef SOFTFLOAT_FOR_GCC
5782fe8fb19SBen Gras /*
5792fe8fb19SBen Gras -------------------------------------------------------------------------------
5802fe8fb19SBen Gras Returns the result of converting the single-precision floating-point value
5812fe8fb19SBen Gras `a' to the 32-bit two's complement integer format.  The conversion is
5822fe8fb19SBen Gras performed according to the IEC/IEEE Standard for Binary Floating-Point
5832fe8fb19SBen Gras Arithmetic---which means in particular that the conversion is rounded
5842fe8fb19SBen Gras according to the current rounding mode.  If `a' is a NaN, the largest
5852fe8fb19SBen Gras positive integer is returned.  Otherwise, if the conversion overflows, the
5862fe8fb19SBen Gras largest integer with the same sign as `a' is returned.
5872fe8fb19SBen Gras -------------------------------------------------------------------------------
5882fe8fb19SBen Gras */
float32_to_int32(float32 a)5892fe8fb19SBen Gras int32 float32_to_int32( float32 a )
5902fe8fb19SBen Gras {
5912fe8fb19SBen Gras     flag aSign;
5922fe8fb19SBen Gras     int16 aExp, shiftCount;
5932fe8fb19SBen Gras     bits32 aSig, aSigExtra;
5942fe8fb19SBen Gras     int32 z;
5952fe8fb19SBen Gras     int8 roundingMode;
5962fe8fb19SBen Gras 
5972fe8fb19SBen Gras     aSig = extractFloat32Frac( a );
5982fe8fb19SBen Gras     aExp = extractFloat32Exp( a );
5992fe8fb19SBen Gras     aSign = extractFloat32Sign( a );
6002fe8fb19SBen Gras     shiftCount = aExp - 0x96;
6012fe8fb19SBen Gras     if ( 0 <= shiftCount ) {
6022fe8fb19SBen Gras         if ( 0x9E <= aExp ) {
6032fe8fb19SBen Gras             if ( a != 0xCF000000 ) {
6042fe8fb19SBen Gras                 float_raise( float_flag_invalid );
6052fe8fb19SBen Gras                 if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) {
6062fe8fb19SBen Gras                     return 0x7FFFFFFF;
6072fe8fb19SBen Gras                 }
6082fe8fb19SBen Gras             }
6092fe8fb19SBen Gras             return (sbits32) 0x80000000;
6102fe8fb19SBen Gras         }
6112fe8fb19SBen Gras         z = ( aSig | 0x00800000 )<<shiftCount;
6122fe8fb19SBen Gras         if ( aSign ) z = - z;
6132fe8fb19SBen Gras     }
6142fe8fb19SBen Gras     else {
6152fe8fb19SBen Gras         if ( aExp < 0x7E ) {
6162fe8fb19SBen Gras             aSigExtra = aExp | aSig;
6172fe8fb19SBen Gras             z = 0;
6182fe8fb19SBen Gras         }
6192fe8fb19SBen Gras         else {
6202fe8fb19SBen Gras             aSig |= 0x00800000;
6212fe8fb19SBen Gras             aSigExtra = aSig<<( shiftCount & 31 );
6222fe8fb19SBen Gras             z = aSig>>( - shiftCount );
6232fe8fb19SBen Gras         }
624*84d9c625SLionel Sambuc         if ( aSigExtra ) set_float_exception_inexact_flag();
6252fe8fb19SBen Gras         roundingMode = float_rounding_mode;
6262fe8fb19SBen Gras         if ( roundingMode == float_round_nearest_even ) {
6272fe8fb19SBen Gras             if ( (sbits32) aSigExtra < 0 ) {
6282fe8fb19SBen Gras                 ++z;
6292fe8fb19SBen Gras                 if ( (bits32) ( aSigExtra<<1 ) == 0 ) z &= ~1;
6302fe8fb19SBen Gras             }
6312fe8fb19SBen Gras             if ( aSign ) z = - z;
6322fe8fb19SBen Gras         }
6332fe8fb19SBen Gras         else {
6342fe8fb19SBen Gras             aSigExtra = ( aSigExtra != 0 );
6352fe8fb19SBen Gras             if ( aSign ) {
6362fe8fb19SBen Gras                 z += ( roundingMode == float_round_down ) & aSigExtra;
6372fe8fb19SBen Gras                 z = - z;
6382fe8fb19SBen Gras             }
6392fe8fb19SBen Gras             else {
6402fe8fb19SBen Gras                 z += ( roundingMode == float_round_up ) & aSigExtra;
6412fe8fb19SBen Gras             }
6422fe8fb19SBen Gras         }
6432fe8fb19SBen Gras     }
6442fe8fb19SBen Gras     return z;
6452fe8fb19SBen Gras 
6462fe8fb19SBen Gras }
6472fe8fb19SBen Gras #endif
6482fe8fb19SBen Gras 
6492fe8fb19SBen Gras /*
6502fe8fb19SBen Gras -------------------------------------------------------------------------------
6512fe8fb19SBen Gras Returns the result of converting the single-precision floating-point value
6522fe8fb19SBen Gras `a' to the 32-bit two's complement integer format.  The conversion is
6532fe8fb19SBen Gras performed according to the IEC/IEEE Standard for Binary Floating-Point
6542fe8fb19SBen Gras Arithmetic, except that the conversion is always rounded toward zero.
6552fe8fb19SBen Gras If `a' is a NaN, the largest positive integer is returned.  Otherwise, if
6562fe8fb19SBen Gras the conversion overflows, the largest integer with the same sign as `a' is
6572fe8fb19SBen Gras returned.
6582fe8fb19SBen Gras -------------------------------------------------------------------------------
6592fe8fb19SBen Gras */
float32_to_int32_round_to_zero(float32 a)6602fe8fb19SBen Gras int32 float32_to_int32_round_to_zero( float32 a )
6612fe8fb19SBen Gras {
6622fe8fb19SBen Gras     flag aSign;
6632fe8fb19SBen Gras     int16 aExp, shiftCount;
6642fe8fb19SBen Gras     bits32 aSig;
6652fe8fb19SBen Gras     int32 z;
6662fe8fb19SBen Gras 
6672fe8fb19SBen Gras     aSig = extractFloat32Frac( a );
6682fe8fb19SBen Gras     aExp = extractFloat32Exp( a );
6692fe8fb19SBen Gras     aSign = extractFloat32Sign( a );
6702fe8fb19SBen Gras     shiftCount = aExp - 0x9E;
6712fe8fb19SBen Gras     if ( 0 <= shiftCount ) {
6722fe8fb19SBen Gras         if ( a != 0xCF000000 ) {
6732fe8fb19SBen Gras             float_raise( float_flag_invalid );
6742fe8fb19SBen Gras             if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) return 0x7FFFFFFF;
6752fe8fb19SBen Gras         }
6762fe8fb19SBen Gras         return (sbits32) 0x80000000;
6772fe8fb19SBen Gras     }
6782fe8fb19SBen Gras     else if ( aExp <= 0x7E ) {
679*84d9c625SLionel Sambuc         if ( aExp | aSig ) set_float_exception_inexact_flag();
6802fe8fb19SBen Gras         return 0;
6812fe8fb19SBen Gras     }
6822fe8fb19SBen Gras     aSig = ( aSig | 0x00800000 )<<8;
6832fe8fb19SBen Gras     z = aSig>>( - shiftCount );
6842fe8fb19SBen Gras     if ( (bits32) ( aSig<<( shiftCount & 31 ) ) ) {
685*84d9c625SLionel Sambuc         set_float_exception_inexact_flag();
6862fe8fb19SBen Gras     }
6872fe8fb19SBen Gras     if ( aSign ) z = - z;
6882fe8fb19SBen Gras     return z;
6892fe8fb19SBen Gras 
6902fe8fb19SBen Gras }
6912fe8fb19SBen Gras 
6922fe8fb19SBen Gras /*
6932fe8fb19SBen Gras -------------------------------------------------------------------------------
6942fe8fb19SBen Gras Returns the result of converting the single-precision floating-point value
6952fe8fb19SBen Gras `a' to the double-precision floating-point format.  The conversion is
6962fe8fb19SBen Gras performed according to the IEC/IEEE Standard for Binary Floating-Point
6972fe8fb19SBen Gras Arithmetic.
6982fe8fb19SBen Gras -------------------------------------------------------------------------------
6992fe8fb19SBen Gras */
float32_to_float64(float32 a)7002fe8fb19SBen Gras float64 float32_to_float64( float32 a )
7012fe8fb19SBen Gras {
7022fe8fb19SBen Gras     flag aSign;
7032fe8fb19SBen Gras     int16 aExp;
7042fe8fb19SBen Gras     bits32 aSig, zSig0, zSig1;
7052fe8fb19SBen Gras 
7062fe8fb19SBen Gras     aSig = extractFloat32Frac( a );
7072fe8fb19SBen Gras     aExp = extractFloat32Exp( a );
7082fe8fb19SBen Gras     aSign = extractFloat32Sign( a );
7092fe8fb19SBen Gras     if ( aExp == 0xFF ) {
7102fe8fb19SBen Gras         if ( aSig ) return commonNaNToFloat64( float32ToCommonNaN( a ) );
7112fe8fb19SBen Gras         return packFloat64( aSign, 0x7FF, 0, 0 );
7122fe8fb19SBen Gras     }
7132fe8fb19SBen Gras     if ( aExp == 0 ) {
7142fe8fb19SBen Gras         if ( aSig == 0 ) return packFloat64( aSign, 0, 0, 0 );
7152fe8fb19SBen Gras         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
7162fe8fb19SBen Gras         --aExp;
7172fe8fb19SBen Gras     }
7182fe8fb19SBen Gras     shift64Right( aSig, 0, 3, &zSig0, &zSig1 );
7192fe8fb19SBen Gras     return packFloat64( aSign, aExp + 0x380, zSig0, zSig1 );
7202fe8fb19SBen Gras 
7212fe8fb19SBen Gras }
7222fe8fb19SBen Gras 
7232fe8fb19SBen Gras #ifndef SOFTFLOAT_FOR_GCC
7242fe8fb19SBen Gras /*
7252fe8fb19SBen Gras -------------------------------------------------------------------------------
7262fe8fb19SBen Gras Rounds the single-precision floating-point value `a' to an integer,
7272fe8fb19SBen Gras and returns the result as a single-precision floating-point value.  The
7282fe8fb19SBen Gras operation is performed according to the IEC/IEEE Standard for Binary
7292fe8fb19SBen Gras Floating-Point Arithmetic.
7302fe8fb19SBen Gras -------------------------------------------------------------------------------
7312fe8fb19SBen Gras */
float32_round_to_int(float32 a)7322fe8fb19SBen Gras float32 float32_round_to_int( float32 a )
7332fe8fb19SBen Gras {
7342fe8fb19SBen Gras     flag aSign;
7352fe8fb19SBen Gras     int16 aExp;
7362fe8fb19SBen Gras     bits32 lastBitMask, roundBitsMask;
7372fe8fb19SBen Gras     int8 roundingMode;
7382fe8fb19SBen Gras     float32 z;
7392fe8fb19SBen Gras 
7402fe8fb19SBen Gras     aExp = extractFloat32Exp( a );
7412fe8fb19SBen Gras     if ( 0x96 <= aExp ) {
7422fe8fb19SBen Gras         if ( ( aExp == 0xFF ) && extractFloat32Frac( a ) ) {
7432fe8fb19SBen Gras             return propagateFloat32NaN( a, a );
7442fe8fb19SBen Gras         }
7452fe8fb19SBen Gras         return a;
7462fe8fb19SBen Gras     }
7472fe8fb19SBen Gras     if ( aExp <= 0x7E ) {
7482fe8fb19SBen Gras         if ( (bits32) ( a<<1 ) == 0 ) return a;
749*84d9c625SLionel Sambuc         set_float_exception_inexact_flag();
7502fe8fb19SBen Gras         aSign = extractFloat32Sign( a );
7512fe8fb19SBen Gras         switch ( float_rounding_mode ) {
7522fe8fb19SBen Gras          case float_round_nearest_even:
7532fe8fb19SBen Gras             if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) {
7542fe8fb19SBen Gras                 return packFloat32( aSign, 0x7F, 0 );
7552fe8fb19SBen Gras             }
7562fe8fb19SBen Gras             break;
7572fe8fb19SBen Gras 	 case float_round_to_zero:
7582fe8fb19SBen Gras 	    break;
7592fe8fb19SBen Gras          case float_round_down:
7602fe8fb19SBen Gras             return aSign ? 0xBF800000 : 0;
7612fe8fb19SBen Gras          case float_round_up:
7622fe8fb19SBen Gras             return aSign ? 0x80000000 : 0x3F800000;
7632fe8fb19SBen Gras         }
7642fe8fb19SBen Gras         return packFloat32( aSign, 0, 0 );
7652fe8fb19SBen Gras     }
7662fe8fb19SBen Gras     lastBitMask = 1;
7672fe8fb19SBen Gras     lastBitMask <<= 0x96 - aExp;
7682fe8fb19SBen Gras     roundBitsMask = lastBitMask - 1;
7692fe8fb19SBen Gras     z = a;
7702fe8fb19SBen Gras     roundingMode = float_rounding_mode;
7712fe8fb19SBen Gras     if ( roundingMode == float_round_nearest_even ) {
7722fe8fb19SBen Gras         z += lastBitMask>>1;
7732fe8fb19SBen Gras         if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
7742fe8fb19SBen Gras     }
7752fe8fb19SBen Gras     else if ( roundingMode != float_round_to_zero ) {
7762fe8fb19SBen Gras         if ( extractFloat32Sign( z ) ^ ( roundingMode == float_round_up ) ) {
7772fe8fb19SBen Gras             z += roundBitsMask;
7782fe8fb19SBen Gras         }
7792fe8fb19SBen Gras     }
7802fe8fb19SBen Gras     z &= ~ roundBitsMask;
781*84d9c625SLionel Sambuc     if ( z != a ) set_float_exception_inexact_flag();
7822fe8fb19SBen Gras     return z;
7832fe8fb19SBen Gras 
7842fe8fb19SBen Gras }
7852fe8fb19SBen Gras #endif
7862fe8fb19SBen Gras 
7872fe8fb19SBen Gras /*
7882fe8fb19SBen Gras -------------------------------------------------------------------------------
7892fe8fb19SBen Gras Returns the result of adding the absolute values of the single-precision
7902fe8fb19SBen Gras floating-point values `a' and `b'.  If `zSign' is 1, the sum is negated
7912fe8fb19SBen Gras before being returned.  `zSign' is ignored if the result is a NaN.
7922fe8fb19SBen Gras The addition is performed according to the IEC/IEEE Standard for Binary
7932fe8fb19SBen Gras Floating-Point Arithmetic.
7942fe8fb19SBen Gras -------------------------------------------------------------------------------
7952fe8fb19SBen Gras */
addFloat32Sigs(float32 a,float32 b,flag zSign)7962fe8fb19SBen Gras static float32 addFloat32Sigs( float32 a, float32 b, flag zSign )
7972fe8fb19SBen Gras {
7982fe8fb19SBen Gras     int16 aExp, bExp, zExp;
7992fe8fb19SBen Gras     bits32 aSig, bSig, zSig;
8002fe8fb19SBen Gras     int16 expDiff;
8012fe8fb19SBen Gras 
8022fe8fb19SBen Gras     aSig = extractFloat32Frac( a );
8032fe8fb19SBen Gras     aExp = extractFloat32Exp( a );
8042fe8fb19SBen Gras     bSig = extractFloat32Frac( b );
8052fe8fb19SBen Gras     bExp = extractFloat32Exp( b );
8062fe8fb19SBen Gras     expDiff = aExp - bExp;
8072fe8fb19SBen Gras     aSig <<= 6;
8082fe8fb19SBen Gras     bSig <<= 6;
8092fe8fb19SBen Gras     if ( 0 < expDiff ) {
8102fe8fb19SBen Gras         if ( aExp == 0xFF ) {
8112fe8fb19SBen Gras             if ( aSig ) return propagateFloat32NaN( a, b );
8122fe8fb19SBen Gras             return a;
8132fe8fb19SBen Gras         }
8142fe8fb19SBen Gras         if ( bExp == 0 ) {
8152fe8fb19SBen Gras             --expDiff;
8162fe8fb19SBen Gras         }
8172fe8fb19SBen Gras         else {
8182fe8fb19SBen Gras             bSig |= 0x20000000;
8192fe8fb19SBen Gras         }
8202fe8fb19SBen Gras         shift32RightJamming( bSig, expDiff, &bSig );
8212fe8fb19SBen Gras         zExp = aExp;
8222fe8fb19SBen Gras     }
8232fe8fb19SBen Gras     else if ( expDiff < 0 ) {
8242fe8fb19SBen Gras         if ( bExp == 0xFF ) {
8252fe8fb19SBen Gras             if ( bSig ) return propagateFloat32NaN( a, b );
8262fe8fb19SBen Gras             return packFloat32( zSign, 0xFF, 0 );
8272fe8fb19SBen Gras         }
8282fe8fb19SBen Gras         if ( aExp == 0 ) {
8292fe8fb19SBen Gras             ++expDiff;
8302fe8fb19SBen Gras         }
8312fe8fb19SBen Gras         else {
8322fe8fb19SBen Gras             aSig |= 0x20000000;
8332fe8fb19SBen Gras         }
8342fe8fb19SBen Gras         shift32RightJamming( aSig, - expDiff, &aSig );
8352fe8fb19SBen Gras         zExp = bExp;
8362fe8fb19SBen Gras     }
8372fe8fb19SBen Gras     else {
8382fe8fb19SBen Gras         if ( aExp == 0xFF ) {
8392fe8fb19SBen Gras             if ( aSig | bSig ) return propagateFloat32NaN( a, b );
8402fe8fb19SBen Gras             return a;
8412fe8fb19SBen Gras         }
8422fe8fb19SBen Gras         if ( aExp == 0 ) return packFloat32( zSign, 0, ( aSig + bSig )>>6 );
8432fe8fb19SBen Gras         zSig = 0x40000000 + aSig + bSig;
8442fe8fb19SBen Gras         zExp = aExp;
8452fe8fb19SBen Gras         goto roundAndPack;
8462fe8fb19SBen Gras     }
8472fe8fb19SBen Gras     aSig |= 0x20000000;
8482fe8fb19SBen Gras     zSig = ( aSig + bSig )<<1;
8492fe8fb19SBen Gras     --zExp;
8502fe8fb19SBen Gras     if ( (sbits32) zSig < 0 ) {
8512fe8fb19SBen Gras         zSig = aSig + bSig;
8522fe8fb19SBen Gras         ++zExp;
8532fe8fb19SBen Gras     }
8542fe8fb19SBen Gras  roundAndPack:
8552fe8fb19SBen Gras     return roundAndPackFloat32( zSign, zExp, zSig );
8562fe8fb19SBen Gras 
8572fe8fb19SBen Gras }
8582fe8fb19SBen Gras 
8592fe8fb19SBen Gras /*
8602fe8fb19SBen Gras -------------------------------------------------------------------------------
8612fe8fb19SBen Gras Returns the result of subtracting the absolute values of the single-
8622fe8fb19SBen Gras precision floating-point values `a' and `b'.  If `zSign' is 1, the
8632fe8fb19SBen Gras difference is negated before being returned.  `zSign' is ignored if the
8642fe8fb19SBen Gras result is a NaN.  The subtraction is performed according to the IEC/IEEE
8652fe8fb19SBen Gras Standard for Binary Floating-Point Arithmetic.
8662fe8fb19SBen Gras -------------------------------------------------------------------------------
8672fe8fb19SBen Gras */
subFloat32Sigs(float32 a,float32 b,flag zSign)8682fe8fb19SBen Gras static float32 subFloat32Sigs( float32 a, float32 b, flag zSign )
8692fe8fb19SBen Gras {
8702fe8fb19SBen Gras     int16 aExp, bExp, zExp;
8712fe8fb19SBen Gras     bits32 aSig, bSig, zSig;
8722fe8fb19SBen Gras     int16 expDiff;
8732fe8fb19SBen Gras 
8742fe8fb19SBen Gras     aSig = extractFloat32Frac( a );
8752fe8fb19SBen Gras     aExp = extractFloat32Exp( a );
8762fe8fb19SBen Gras     bSig = extractFloat32Frac( b );
8772fe8fb19SBen Gras     bExp = extractFloat32Exp( b );
8782fe8fb19SBen Gras     expDiff = aExp - bExp;
8792fe8fb19SBen Gras     aSig <<= 7;
8802fe8fb19SBen Gras     bSig <<= 7;
8812fe8fb19SBen Gras     if ( 0 < expDiff ) goto aExpBigger;
8822fe8fb19SBen Gras     if ( expDiff < 0 ) goto bExpBigger;
8832fe8fb19SBen Gras     if ( aExp == 0xFF ) {
8842fe8fb19SBen Gras         if ( aSig | bSig ) return propagateFloat32NaN( a, b );
8852fe8fb19SBen Gras         float_raise( float_flag_invalid );
8862fe8fb19SBen Gras         return float32_default_nan;
8872fe8fb19SBen Gras     }
8882fe8fb19SBen Gras     if ( aExp == 0 ) {
8892fe8fb19SBen Gras         aExp = 1;
8902fe8fb19SBen Gras         bExp = 1;
8912fe8fb19SBen Gras     }
8922fe8fb19SBen Gras     if ( bSig < aSig ) goto aBigger;
8932fe8fb19SBen Gras     if ( aSig < bSig ) goto bBigger;
8942fe8fb19SBen Gras     return packFloat32( float_rounding_mode == float_round_down, 0, 0 );
8952fe8fb19SBen Gras  bExpBigger:
8962fe8fb19SBen Gras     if ( bExp == 0xFF ) {
8972fe8fb19SBen Gras         if ( bSig ) return propagateFloat32NaN( a, b );
8982fe8fb19SBen Gras         return packFloat32( zSign ^ 1, 0xFF, 0 );
8992fe8fb19SBen Gras     }
9002fe8fb19SBen Gras     if ( aExp == 0 ) {
9012fe8fb19SBen Gras         ++expDiff;
9022fe8fb19SBen Gras     }
9032fe8fb19SBen Gras     else {
9042fe8fb19SBen Gras         aSig |= 0x40000000;
9052fe8fb19SBen Gras     }
9062fe8fb19SBen Gras     shift32RightJamming( aSig, - expDiff, &aSig );
9072fe8fb19SBen Gras     bSig |= 0x40000000;
9082fe8fb19SBen Gras  bBigger:
9092fe8fb19SBen Gras     zSig = bSig - aSig;
9102fe8fb19SBen Gras     zExp = bExp;
9112fe8fb19SBen Gras     zSign ^= 1;
9122fe8fb19SBen Gras     goto normalizeRoundAndPack;
9132fe8fb19SBen Gras  aExpBigger:
9142fe8fb19SBen Gras     if ( aExp == 0xFF ) {
9152fe8fb19SBen Gras         if ( aSig ) return propagateFloat32NaN( a, b );
9162fe8fb19SBen Gras         return a;
9172fe8fb19SBen Gras     }
9182fe8fb19SBen Gras     if ( bExp == 0 ) {
9192fe8fb19SBen Gras         --expDiff;
9202fe8fb19SBen Gras     }
9212fe8fb19SBen Gras     else {
9222fe8fb19SBen Gras         bSig |= 0x40000000;
9232fe8fb19SBen Gras     }
9242fe8fb19SBen Gras     shift32RightJamming( bSig, expDiff, &bSig );
9252fe8fb19SBen Gras     aSig |= 0x40000000;
9262fe8fb19SBen Gras  aBigger:
9272fe8fb19SBen Gras     zSig = aSig - bSig;
9282fe8fb19SBen Gras     zExp = aExp;
9292fe8fb19SBen Gras  normalizeRoundAndPack:
9302fe8fb19SBen Gras     --zExp;
9312fe8fb19SBen Gras     return normalizeRoundAndPackFloat32( zSign, zExp, zSig );
9322fe8fb19SBen Gras 
9332fe8fb19SBen Gras }
9342fe8fb19SBen Gras 
9352fe8fb19SBen Gras /*
9362fe8fb19SBen Gras -------------------------------------------------------------------------------
9372fe8fb19SBen Gras Returns the result of adding the single-precision floating-point values `a'
9382fe8fb19SBen Gras and `b'.  The operation is performed according to the IEC/IEEE Standard for
9392fe8fb19SBen Gras Binary Floating-Point Arithmetic.
9402fe8fb19SBen Gras -------------------------------------------------------------------------------
9412fe8fb19SBen Gras */
float32_add(float32 a,float32 b)9422fe8fb19SBen Gras float32 float32_add( float32 a, float32 b )
9432fe8fb19SBen Gras {
9442fe8fb19SBen Gras     flag aSign, bSign;
9452fe8fb19SBen Gras 
9462fe8fb19SBen Gras     aSign = extractFloat32Sign( a );
9472fe8fb19SBen Gras     bSign = extractFloat32Sign( b );
9482fe8fb19SBen Gras     if ( aSign == bSign ) {
9492fe8fb19SBen Gras         return addFloat32Sigs( a, b, aSign );
9502fe8fb19SBen Gras     }
9512fe8fb19SBen Gras     else {
9522fe8fb19SBen Gras         return subFloat32Sigs( a, b, aSign );
9532fe8fb19SBen Gras     }
9542fe8fb19SBen Gras 
9552fe8fb19SBen Gras }
9562fe8fb19SBen Gras 
9572fe8fb19SBen Gras /*
9582fe8fb19SBen Gras -------------------------------------------------------------------------------
9592fe8fb19SBen Gras Returns the result of subtracting the single-precision floating-point values
9602fe8fb19SBen Gras `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
9612fe8fb19SBen Gras for Binary Floating-Point Arithmetic.
9622fe8fb19SBen Gras -------------------------------------------------------------------------------
9632fe8fb19SBen Gras */
float32_sub(float32 a,float32 b)9642fe8fb19SBen Gras float32 float32_sub( float32 a, float32 b )
9652fe8fb19SBen Gras {
9662fe8fb19SBen Gras     flag aSign, bSign;
9672fe8fb19SBen Gras 
9682fe8fb19SBen Gras     aSign = extractFloat32Sign( a );
9692fe8fb19SBen Gras     bSign = extractFloat32Sign( b );
9702fe8fb19SBen Gras     if ( aSign == bSign ) {
9712fe8fb19SBen Gras         return subFloat32Sigs( a, b, aSign );
9722fe8fb19SBen Gras     }
9732fe8fb19SBen Gras     else {
9742fe8fb19SBen Gras         return addFloat32Sigs( a, b, aSign );
9752fe8fb19SBen Gras     }
9762fe8fb19SBen Gras 
9772fe8fb19SBen Gras }
9782fe8fb19SBen Gras 
9792fe8fb19SBen Gras /*
9802fe8fb19SBen Gras -------------------------------------------------------------------------------
9812fe8fb19SBen Gras Returns the result of multiplying the single-precision floating-point values
9822fe8fb19SBen Gras `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
9832fe8fb19SBen Gras for Binary Floating-Point Arithmetic.
9842fe8fb19SBen Gras -------------------------------------------------------------------------------
9852fe8fb19SBen Gras */
float32_mul(float32 a,float32 b)9862fe8fb19SBen Gras float32 float32_mul( float32 a, float32 b )
9872fe8fb19SBen Gras {
9882fe8fb19SBen Gras     flag aSign, bSign, zSign;
9892fe8fb19SBen Gras     int16 aExp, bExp, zExp;
9902fe8fb19SBen Gras     bits32 aSig, bSig, zSig0, zSig1;
9912fe8fb19SBen Gras 
9922fe8fb19SBen Gras     aSig = extractFloat32Frac( a );
9932fe8fb19SBen Gras     aExp = extractFloat32Exp( a );
9942fe8fb19SBen Gras     aSign = extractFloat32Sign( a );
9952fe8fb19SBen Gras     bSig = extractFloat32Frac( b );
9962fe8fb19SBen Gras     bExp = extractFloat32Exp( b );
9972fe8fb19SBen Gras     bSign = extractFloat32Sign( b );
9982fe8fb19SBen Gras     zSign = aSign ^ bSign;
9992fe8fb19SBen Gras     if ( aExp == 0xFF ) {
10002fe8fb19SBen Gras         if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
10012fe8fb19SBen Gras             return propagateFloat32NaN( a, b );
10022fe8fb19SBen Gras         }
10032fe8fb19SBen Gras         if ( ( bExp | bSig ) == 0 ) {
10042fe8fb19SBen Gras             float_raise( float_flag_invalid );
10052fe8fb19SBen Gras             return float32_default_nan;
10062fe8fb19SBen Gras         }
10072fe8fb19SBen Gras         return packFloat32( zSign, 0xFF, 0 );
10082fe8fb19SBen Gras     }
10092fe8fb19SBen Gras     if ( bExp == 0xFF ) {
10102fe8fb19SBen Gras         if ( bSig ) return propagateFloat32NaN( a, b );
10112fe8fb19SBen Gras         if ( ( aExp | aSig ) == 0 ) {
10122fe8fb19SBen Gras             float_raise( float_flag_invalid );
10132fe8fb19SBen Gras             return float32_default_nan;
10142fe8fb19SBen Gras         }
10152fe8fb19SBen Gras         return packFloat32( zSign, 0xFF, 0 );
10162fe8fb19SBen Gras     }
10172fe8fb19SBen Gras     if ( aExp == 0 ) {
10182fe8fb19SBen Gras         if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
10192fe8fb19SBen Gras         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
10202fe8fb19SBen Gras     }
10212fe8fb19SBen Gras     if ( bExp == 0 ) {
10222fe8fb19SBen Gras         if ( bSig == 0 ) return packFloat32( zSign, 0, 0 );
10232fe8fb19SBen Gras         normalizeFloat32Subnormal( bSig, &bExp, &bSig );
10242fe8fb19SBen Gras     }
10252fe8fb19SBen Gras     zExp = aExp + bExp - 0x7F;
10262fe8fb19SBen Gras     aSig = ( aSig | 0x00800000 )<<7;
10272fe8fb19SBen Gras     bSig = ( bSig | 0x00800000 )<<8;
10282fe8fb19SBen Gras     mul32To64( aSig, bSig, &zSig0, &zSig1 );
10292fe8fb19SBen Gras     zSig0 |= ( zSig1 != 0 );
10302fe8fb19SBen Gras     if ( 0 <= (sbits32) ( zSig0<<1 ) ) {
10312fe8fb19SBen Gras         zSig0 <<= 1;
10322fe8fb19SBen Gras         --zExp;
10332fe8fb19SBen Gras     }
10342fe8fb19SBen Gras     return roundAndPackFloat32( zSign, zExp, zSig0 );
10352fe8fb19SBen Gras 
10362fe8fb19SBen Gras }
10372fe8fb19SBen Gras 
10382fe8fb19SBen Gras /*
10392fe8fb19SBen Gras -------------------------------------------------------------------------------
10402fe8fb19SBen Gras Returns the result of dividing the single-precision floating-point value `a'
10412fe8fb19SBen Gras by the corresponding value `b'.  The operation is performed according to the
10422fe8fb19SBen Gras IEC/IEEE Standard for Binary Floating-Point Arithmetic.
10432fe8fb19SBen Gras -------------------------------------------------------------------------------
10442fe8fb19SBen Gras */
float32_div(float32 a,float32 b)10452fe8fb19SBen Gras float32 float32_div( float32 a, float32 b )
10462fe8fb19SBen Gras {
10472fe8fb19SBen Gras     flag aSign, bSign, zSign;
10482fe8fb19SBen Gras     int16 aExp, bExp, zExp;
10492fe8fb19SBen Gras     bits32 aSig, bSig, zSig, rem0, rem1, term0, term1;
10502fe8fb19SBen Gras 
10512fe8fb19SBen Gras     aSig = extractFloat32Frac( a );
10522fe8fb19SBen Gras     aExp = extractFloat32Exp( a );
10532fe8fb19SBen Gras     aSign = extractFloat32Sign( a );
10542fe8fb19SBen Gras     bSig = extractFloat32Frac( b );
10552fe8fb19SBen Gras     bExp = extractFloat32Exp( b );
10562fe8fb19SBen Gras     bSign = extractFloat32Sign( b );
10572fe8fb19SBen Gras     zSign = aSign ^ bSign;
10582fe8fb19SBen Gras     if ( aExp == 0xFF ) {
10592fe8fb19SBen Gras         if ( aSig ) return propagateFloat32NaN( a, b );
10602fe8fb19SBen Gras         if ( bExp == 0xFF ) {
10612fe8fb19SBen Gras             if ( bSig ) return propagateFloat32NaN( a, b );
10622fe8fb19SBen Gras             float_raise( float_flag_invalid );
10632fe8fb19SBen Gras             return float32_default_nan;
10642fe8fb19SBen Gras         }
10652fe8fb19SBen Gras         return packFloat32( zSign, 0xFF, 0 );
10662fe8fb19SBen Gras     }
10672fe8fb19SBen Gras     if ( bExp == 0xFF ) {
10682fe8fb19SBen Gras         if ( bSig ) return propagateFloat32NaN( a, b );
10692fe8fb19SBen Gras         return packFloat32( zSign, 0, 0 );
10702fe8fb19SBen Gras     }
10712fe8fb19SBen Gras     if ( bExp == 0 ) {
10722fe8fb19SBen Gras         if ( bSig == 0 ) {
10732fe8fb19SBen Gras             if ( ( aExp | aSig ) == 0 ) {
10742fe8fb19SBen Gras                 float_raise( float_flag_invalid );
10752fe8fb19SBen Gras                 return float32_default_nan;
10762fe8fb19SBen Gras             }
10772fe8fb19SBen Gras             float_raise( float_flag_divbyzero );
10782fe8fb19SBen Gras             return packFloat32( zSign, 0xFF, 0 );
10792fe8fb19SBen Gras         }
10802fe8fb19SBen Gras         normalizeFloat32Subnormal( bSig, &bExp, &bSig );
10812fe8fb19SBen Gras     }
10822fe8fb19SBen Gras     if ( aExp == 0 ) {
10832fe8fb19SBen Gras         if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
10842fe8fb19SBen Gras         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
10852fe8fb19SBen Gras     }
10862fe8fb19SBen Gras     zExp = aExp - bExp + 0x7D;
10872fe8fb19SBen Gras     aSig = ( aSig | 0x00800000 )<<7;
10882fe8fb19SBen Gras     bSig = ( bSig | 0x00800000 )<<8;
10892fe8fb19SBen Gras     if ( bSig <= ( aSig + aSig ) ) {
10902fe8fb19SBen Gras         aSig >>= 1;
10912fe8fb19SBen Gras         ++zExp;
10922fe8fb19SBen Gras     }
10932fe8fb19SBen Gras     zSig = estimateDiv64To32( aSig, 0, bSig );
10942fe8fb19SBen Gras     if ( ( zSig & 0x3F ) <= 2 ) {
10952fe8fb19SBen Gras         mul32To64( bSig, zSig, &term0, &term1 );
10962fe8fb19SBen Gras         sub64( aSig, 0, term0, term1, &rem0, &rem1 );
10972fe8fb19SBen Gras         while ( (sbits32) rem0 < 0 ) {
10982fe8fb19SBen Gras             --zSig;
10992fe8fb19SBen Gras             add64( rem0, rem1, 0, bSig, &rem0, &rem1 );
11002fe8fb19SBen Gras         }
11012fe8fb19SBen Gras         zSig |= ( rem1 != 0 );
11022fe8fb19SBen Gras     }
11032fe8fb19SBen Gras     return roundAndPackFloat32( zSign, zExp, zSig );
11042fe8fb19SBen Gras 
11052fe8fb19SBen Gras }
11062fe8fb19SBen Gras 
11072fe8fb19SBen Gras #ifndef SOFTFLOAT_FOR_GCC
11082fe8fb19SBen Gras /*
11092fe8fb19SBen Gras -------------------------------------------------------------------------------
11102fe8fb19SBen Gras Returns the remainder of the single-precision floating-point value `a'
11112fe8fb19SBen Gras with respect to the corresponding value `b'.  The operation is performed
11122fe8fb19SBen Gras according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
11132fe8fb19SBen Gras -------------------------------------------------------------------------------
11142fe8fb19SBen Gras */
float32_rem(float32 a,float32 b)11152fe8fb19SBen Gras float32 float32_rem( float32 a, float32 b )
11162fe8fb19SBen Gras {
11172fe8fb19SBen Gras     flag aSign, bSign, zSign;
11182fe8fb19SBen Gras     int16 aExp, bExp, expDiff;
11192fe8fb19SBen Gras     bits32 aSig, bSig, q, allZero, alternateASig;
11202fe8fb19SBen Gras     sbits32 sigMean;
11212fe8fb19SBen Gras 
11222fe8fb19SBen Gras     aSig = extractFloat32Frac( a );
11232fe8fb19SBen Gras     aExp = extractFloat32Exp( a );
11242fe8fb19SBen Gras     aSign = extractFloat32Sign( a );
11252fe8fb19SBen Gras     bSig = extractFloat32Frac( b );
11262fe8fb19SBen Gras     bExp = extractFloat32Exp( b );
11272fe8fb19SBen Gras     bSign = extractFloat32Sign( b );
11282fe8fb19SBen Gras     if ( aExp == 0xFF ) {
11292fe8fb19SBen Gras         if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
11302fe8fb19SBen Gras             return propagateFloat32NaN( a, b );
11312fe8fb19SBen Gras         }
11322fe8fb19SBen Gras         float_raise( float_flag_invalid );
11332fe8fb19SBen Gras         return float32_default_nan;
11342fe8fb19SBen Gras     }
11352fe8fb19SBen Gras     if ( bExp == 0xFF ) {
11362fe8fb19SBen Gras         if ( bSig ) return propagateFloat32NaN( a, b );
11372fe8fb19SBen Gras         return a;
11382fe8fb19SBen Gras     }
11392fe8fb19SBen Gras     if ( bExp == 0 ) {
11402fe8fb19SBen Gras         if ( bSig == 0 ) {
11412fe8fb19SBen Gras             float_raise( float_flag_invalid );
11422fe8fb19SBen Gras             return float32_default_nan;
11432fe8fb19SBen Gras         }
11442fe8fb19SBen Gras         normalizeFloat32Subnormal( bSig, &bExp, &bSig );
11452fe8fb19SBen Gras     }
11462fe8fb19SBen Gras     if ( aExp == 0 ) {
11472fe8fb19SBen Gras         if ( aSig == 0 ) return a;
11482fe8fb19SBen Gras         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
11492fe8fb19SBen Gras     }
11502fe8fb19SBen Gras     expDiff = aExp - bExp;
11512fe8fb19SBen Gras     aSig = ( aSig | 0x00800000 )<<8;
11522fe8fb19SBen Gras     bSig = ( bSig | 0x00800000 )<<8;
11532fe8fb19SBen Gras     if ( expDiff < 0 ) {
11542fe8fb19SBen Gras         if ( expDiff < -1 ) return a;
11552fe8fb19SBen Gras         aSig >>= 1;
11562fe8fb19SBen Gras     }
11572fe8fb19SBen Gras     q = ( bSig <= aSig );
11582fe8fb19SBen Gras     if ( q ) aSig -= bSig;
11592fe8fb19SBen Gras     expDiff -= 32;
11602fe8fb19SBen Gras     while ( 0 < expDiff ) {
11612fe8fb19SBen Gras         q = estimateDiv64To32( aSig, 0, bSig );
11622fe8fb19SBen Gras         q = ( 2 < q ) ? q - 2 : 0;
11632fe8fb19SBen Gras         aSig = - ( ( bSig>>2 ) * q );
11642fe8fb19SBen Gras         expDiff -= 30;
11652fe8fb19SBen Gras     }
11662fe8fb19SBen Gras     expDiff += 32;
11672fe8fb19SBen Gras     if ( 0 < expDiff ) {
11682fe8fb19SBen Gras         q = estimateDiv64To32( aSig, 0, bSig );
11692fe8fb19SBen Gras         q = ( 2 < q ) ? q - 2 : 0;
11702fe8fb19SBen Gras         q >>= 32 - expDiff;
11712fe8fb19SBen Gras         bSig >>= 2;
11722fe8fb19SBen Gras         aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
11732fe8fb19SBen Gras     }
11742fe8fb19SBen Gras     else {
11752fe8fb19SBen Gras         aSig >>= 2;
11762fe8fb19SBen Gras         bSig >>= 2;
11772fe8fb19SBen Gras     }
11782fe8fb19SBen Gras     do {
11792fe8fb19SBen Gras         alternateASig = aSig;
11802fe8fb19SBen Gras         ++q;
11812fe8fb19SBen Gras         aSig -= bSig;
11822fe8fb19SBen Gras     } while ( 0 <= (sbits32) aSig );
11832fe8fb19SBen Gras     sigMean = aSig + alternateASig;
11842fe8fb19SBen Gras     if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {
11852fe8fb19SBen Gras         aSig = alternateASig;
11862fe8fb19SBen Gras     }
11872fe8fb19SBen Gras     zSign = ( (sbits32) aSig < 0 );
11882fe8fb19SBen Gras     if ( zSign ) aSig = - aSig;
11892fe8fb19SBen Gras     return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig );
11902fe8fb19SBen Gras 
11912fe8fb19SBen Gras }
11922fe8fb19SBen Gras #endif
11932fe8fb19SBen Gras 
11942fe8fb19SBen Gras #ifndef SOFTFLOAT_FOR_GCC
11952fe8fb19SBen Gras /*
11962fe8fb19SBen Gras -------------------------------------------------------------------------------
11972fe8fb19SBen Gras Returns the square root of the single-precision floating-point value `a'.
11982fe8fb19SBen Gras The operation is performed according to the IEC/IEEE Standard for Binary
11992fe8fb19SBen Gras Floating-Point Arithmetic.
12002fe8fb19SBen Gras -------------------------------------------------------------------------------
12012fe8fb19SBen Gras */
float32_sqrt(float32 a)12022fe8fb19SBen Gras float32 float32_sqrt( float32 a )
12032fe8fb19SBen Gras {
12042fe8fb19SBen Gras     flag aSign;
12052fe8fb19SBen Gras     int16 aExp, zExp;
12062fe8fb19SBen Gras     bits32 aSig, zSig, rem0, rem1, term0, term1;
12072fe8fb19SBen Gras 
12082fe8fb19SBen Gras     aSig = extractFloat32Frac( a );
12092fe8fb19SBen Gras     aExp = extractFloat32Exp( a );
12102fe8fb19SBen Gras     aSign = extractFloat32Sign( a );
12112fe8fb19SBen Gras     if ( aExp == 0xFF ) {
12122fe8fb19SBen Gras         if ( aSig ) return propagateFloat32NaN( a, 0 );
12132fe8fb19SBen Gras         if ( ! aSign ) return a;
12142fe8fb19SBen Gras         float_raise( float_flag_invalid );
12152fe8fb19SBen Gras         return float32_default_nan;
12162fe8fb19SBen Gras     }
12172fe8fb19SBen Gras     if ( aSign ) {
12182fe8fb19SBen Gras         if ( ( aExp | aSig ) == 0 ) return a;
12192fe8fb19SBen Gras         float_raise( float_flag_invalid );
12202fe8fb19SBen Gras         return float32_default_nan;
12212fe8fb19SBen Gras     }
12222fe8fb19SBen Gras     if ( aExp == 0 ) {
12232fe8fb19SBen Gras         if ( aSig == 0 ) return 0;
12242fe8fb19SBen Gras         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
12252fe8fb19SBen Gras     }
12262fe8fb19SBen Gras     zExp = ( ( aExp - 0x7F )>>1 ) + 0x7E;
12272fe8fb19SBen Gras     aSig = ( aSig | 0x00800000 )<<8;
12282fe8fb19SBen Gras     zSig = estimateSqrt32( aExp, aSig ) + 2;
12292fe8fb19SBen Gras     if ( ( zSig & 0x7F ) <= 5 ) {
12302fe8fb19SBen Gras         if ( zSig < 2 ) {
12312fe8fb19SBen Gras             zSig = 0x7FFFFFFF;
12322fe8fb19SBen Gras             goto roundAndPack;
12332fe8fb19SBen Gras         }
12342fe8fb19SBen Gras         else {
12352fe8fb19SBen Gras             aSig >>= aExp & 1;
12362fe8fb19SBen Gras             mul32To64( zSig, zSig, &term0, &term1 );
12372fe8fb19SBen Gras             sub64( aSig, 0, term0, term1, &rem0, &rem1 );
12382fe8fb19SBen Gras             while ( (sbits32) rem0 < 0 ) {
12392fe8fb19SBen Gras                 --zSig;
12402fe8fb19SBen Gras                 shortShift64Left( 0, zSig, 1, &term0, &term1 );
12412fe8fb19SBen Gras                 term1 |= 1;
12422fe8fb19SBen Gras                 add64( rem0, rem1, term0, term1, &rem0, &rem1 );
12432fe8fb19SBen Gras             }
12442fe8fb19SBen Gras             zSig |= ( ( rem0 | rem1 ) != 0 );
12452fe8fb19SBen Gras         }
12462fe8fb19SBen Gras     }
12472fe8fb19SBen Gras     shift32RightJamming( zSig, 1, &zSig );
12482fe8fb19SBen Gras  roundAndPack:
12492fe8fb19SBen Gras     return roundAndPackFloat32( 0, zExp, zSig );
12502fe8fb19SBen Gras 
12512fe8fb19SBen Gras }
12522fe8fb19SBen Gras #endif
12532fe8fb19SBen Gras 
12542fe8fb19SBen Gras /*
12552fe8fb19SBen Gras -------------------------------------------------------------------------------
12562fe8fb19SBen Gras Returns 1 if the single-precision floating-point value `a' is equal to
12572fe8fb19SBen Gras the corresponding value `b', and 0 otherwise.  The comparison is performed
12582fe8fb19SBen Gras according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
12592fe8fb19SBen Gras -------------------------------------------------------------------------------
12602fe8fb19SBen Gras */
float32_eq(float32 a,float32 b)12612fe8fb19SBen Gras flag float32_eq( float32 a, float32 b )
12622fe8fb19SBen Gras {
12632fe8fb19SBen Gras 
12642fe8fb19SBen Gras     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
12652fe8fb19SBen Gras          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
12662fe8fb19SBen Gras        ) {
12672fe8fb19SBen Gras         if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
12682fe8fb19SBen Gras             float_raise( float_flag_invalid );
12692fe8fb19SBen Gras         }
12702fe8fb19SBen Gras         return 0;
12712fe8fb19SBen Gras     }
12722fe8fb19SBen Gras     return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 );
12732fe8fb19SBen Gras 
12742fe8fb19SBen Gras }
12752fe8fb19SBen Gras 
12762fe8fb19SBen Gras /*
12772fe8fb19SBen Gras -------------------------------------------------------------------------------
12782fe8fb19SBen Gras Returns 1 if the single-precision floating-point value `a' is less than
12792fe8fb19SBen Gras or equal to the corresponding value `b', and 0 otherwise.  The comparison
12802fe8fb19SBen Gras is performed according to the IEC/IEEE Standard for Binary Floating-Point
12812fe8fb19SBen Gras Arithmetic.
12822fe8fb19SBen Gras -------------------------------------------------------------------------------
12832fe8fb19SBen Gras */
float32_le(float32 a,float32 b)12842fe8fb19SBen Gras flag float32_le( float32 a, float32 b )
12852fe8fb19SBen Gras {
12862fe8fb19SBen Gras     flag aSign, bSign;
12872fe8fb19SBen Gras 
12882fe8fb19SBen Gras     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
12892fe8fb19SBen Gras          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
12902fe8fb19SBen Gras        ) {
12912fe8fb19SBen Gras         float_raise( float_flag_invalid );
12922fe8fb19SBen Gras         return 0;
12932fe8fb19SBen Gras     }
12942fe8fb19SBen Gras     aSign = extractFloat32Sign( a );
12952fe8fb19SBen Gras     bSign = extractFloat32Sign( b );
12962fe8fb19SBen Gras     if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 );
12972fe8fb19SBen Gras     return ( a == b ) || ( aSign ^ ( a < b ) );
12982fe8fb19SBen Gras 
12992fe8fb19SBen Gras }
13002fe8fb19SBen Gras 
13012fe8fb19SBen Gras /*
13022fe8fb19SBen Gras -------------------------------------------------------------------------------
13032fe8fb19SBen Gras Returns 1 if the single-precision floating-point value `a' is less than
13042fe8fb19SBen Gras the corresponding value `b', and 0 otherwise.  The comparison is performed
13052fe8fb19SBen Gras according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
13062fe8fb19SBen Gras -------------------------------------------------------------------------------
13072fe8fb19SBen Gras */
float32_lt(float32 a,float32 b)13082fe8fb19SBen Gras flag float32_lt( float32 a, float32 b )
13092fe8fb19SBen Gras {
13102fe8fb19SBen Gras     flag aSign, bSign;
13112fe8fb19SBen Gras 
13122fe8fb19SBen Gras     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
13132fe8fb19SBen Gras          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
13142fe8fb19SBen Gras        ) {
13152fe8fb19SBen Gras         float_raise( float_flag_invalid );
13162fe8fb19SBen Gras         return 0;
13172fe8fb19SBen Gras     }
13182fe8fb19SBen Gras     aSign = extractFloat32Sign( a );
13192fe8fb19SBen Gras     bSign = extractFloat32Sign( b );
13202fe8fb19SBen Gras     if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 );
13212fe8fb19SBen Gras     return ( a != b ) && ( aSign ^ ( a < b ) );
13222fe8fb19SBen Gras 
13232fe8fb19SBen Gras }
13242fe8fb19SBen Gras 
13252fe8fb19SBen Gras #ifndef SOFTFLOAT_FOR_GCC /* Not needed */
13262fe8fb19SBen Gras /*
13272fe8fb19SBen Gras -------------------------------------------------------------------------------
13282fe8fb19SBen Gras Returns 1 if the single-precision floating-point value `a' is equal to
13292fe8fb19SBen Gras the corresponding value `b', and 0 otherwise.  The invalid exception is
13302fe8fb19SBen Gras raised if either operand is a NaN.  Otherwise, the comparison is performed
13312fe8fb19SBen Gras according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
13322fe8fb19SBen Gras -------------------------------------------------------------------------------
13332fe8fb19SBen Gras */
float32_eq_signaling(float32 a,float32 b)13342fe8fb19SBen Gras flag float32_eq_signaling( float32 a, float32 b )
13352fe8fb19SBen Gras {
13362fe8fb19SBen Gras 
13372fe8fb19SBen Gras     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
13382fe8fb19SBen Gras          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
13392fe8fb19SBen Gras        ) {
13402fe8fb19SBen Gras         float_raise( float_flag_invalid );
13412fe8fb19SBen Gras         return 0;
13422fe8fb19SBen Gras     }
13432fe8fb19SBen Gras     return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 );
13442fe8fb19SBen Gras 
13452fe8fb19SBen Gras }
13462fe8fb19SBen Gras 
13472fe8fb19SBen Gras /*
13482fe8fb19SBen Gras -------------------------------------------------------------------------------
13492fe8fb19SBen Gras Returns 1 if the single-precision floating-point value `a' is less than or
13502fe8fb19SBen Gras equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs do not
13512fe8fb19SBen Gras cause an exception.  Otherwise, the comparison is performed according to the
13522fe8fb19SBen Gras IEC/IEEE Standard for Binary Floating-Point Arithmetic.
13532fe8fb19SBen Gras -------------------------------------------------------------------------------
13542fe8fb19SBen Gras */
float32_le_quiet(float32 a,float32 b)13552fe8fb19SBen Gras flag float32_le_quiet( float32 a, float32 b )
13562fe8fb19SBen Gras {
13572fe8fb19SBen Gras     flag aSign, bSign;
13582fe8fb19SBen Gras     int16 aExp, bExp;
13592fe8fb19SBen Gras 
13602fe8fb19SBen Gras     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
13612fe8fb19SBen Gras          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
13622fe8fb19SBen Gras        ) {
13632fe8fb19SBen Gras         if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
13642fe8fb19SBen Gras             float_raise( float_flag_invalid );
13652fe8fb19SBen Gras         }
13662fe8fb19SBen Gras         return 0;
13672fe8fb19SBen Gras     }
13682fe8fb19SBen Gras     aSign = extractFloat32Sign( a );
13692fe8fb19SBen Gras     bSign = extractFloat32Sign( b );
13702fe8fb19SBen Gras     if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 );
13712fe8fb19SBen Gras     return ( a == b ) || ( aSign ^ ( a < b ) );
13722fe8fb19SBen Gras 
13732fe8fb19SBen Gras }
13742fe8fb19SBen Gras 
13752fe8fb19SBen Gras /*
13762fe8fb19SBen Gras -------------------------------------------------------------------------------
13772fe8fb19SBen Gras Returns 1 if the single-precision floating-point value `a' is less than
13782fe8fb19SBen Gras the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
13792fe8fb19SBen Gras exception.  Otherwise, the comparison is performed according to the IEC/IEEE
13802fe8fb19SBen Gras Standard for Binary Floating-Point Arithmetic.
13812fe8fb19SBen Gras -------------------------------------------------------------------------------
13822fe8fb19SBen Gras */
float32_lt_quiet(float32 a,float32 b)13832fe8fb19SBen Gras flag float32_lt_quiet( float32 a, float32 b )
13842fe8fb19SBen Gras {
13852fe8fb19SBen Gras     flag aSign, bSign;
13862fe8fb19SBen Gras 
13872fe8fb19SBen Gras     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
13882fe8fb19SBen Gras          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
13892fe8fb19SBen Gras        ) {
13902fe8fb19SBen Gras         if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
13912fe8fb19SBen Gras             float_raise( float_flag_invalid );
13922fe8fb19SBen Gras         }
13932fe8fb19SBen Gras         return 0;
13942fe8fb19SBen Gras     }
13952fe8fb19SBen Gras     aSign = extractFloat32Sign( a );
13962fe8fb19SBen Gras     bSign = extractFloat32Sign( b );
13972fe8fb19SBen Gras     if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 );
13982fe8fb19SBen Gras     return ( a != b ) && ( aSign ^ ( a < b ) );
13992fe8fb19SBen Gras 
14002fe8fb19SBen Gras }
14012fe8fb19SBen Gras #endif /* !SOFTFLOAT_FOR_GCC */
14022fe8fb19SBen Gras 
14032fe8fb19SBen Gras #ifndef SOFTFLOAT_FOR_GCC /* Not needed */
14042fe8fb19SBen Gras /*
14052fe8fb19SBen Gras -------------------------------------------------------------------------------
14062fe8fb19SBen Gras Returns the result of converting the double-precision floating-point value
14072fe8fb19SBen Gras `a' to the 32-bit two's complement integer format.  The conversion is
14082fe8fb19SBen Gras performed according to the IEC/IEEE Standard for Binary Floating-Point
14092fe8fb19SBen Gras Arithmetic---which means in particular that the conversion is rounded
14102fe8fb19SBen Gras according to the current rounding mode.  If `a' is a NaN, the largest
14112fe8fb19SBen Gras positive integer is returned.  Otherwise, if the conversion overflows, the
14122fe8fb19SBen Gras largest integer with the same sign as `a' is returned.
14132fe8fb19SBen Gras -------------------------------------------------------------------------------
14142fe8fb19SBen Gras */
float64_to_int32(float64 a)14152fe8fb19SBen Gras int32 float64_to_int32( float64 a )
14162fe8fb19SBen Gras {
14172fe8fb19SBen Gras     flag aSign;
14182fe8fb19SBen Gras     int16 aExp, shiftCount;
14192fe8fb19SBen Gras     bits32 aSig0, aSig1, absZ, aSigExtra;
14202fe8fb19SBen Gras     int32 z;
14212fe8fb19SBen Gras     int8 roundingMode;
14222fe8fb19SBen Gras 
14232fe8fb19SBen Gras     aSig1 = extractFloat64Frac1( a );
14242fe8fb19SBen Gras     aSig0 = extractFloat64Frac0( a );
14252fe8fb19SBen Gras     aExp = extractFloat64Exp( a );
14262fe8fb19SBen Gras     aSign = extractFloat64Sign( a );
14272fe8fb19SBen Gras     shiftCount = aExp - 0x413;
14282fe8fb19SBen Gras     if ( 0 <= shiftCount ) {
14292fe8fb19SBen Gras         if ( 0x41E < aExp ) {
14302fe8fb19SBen Gras             if ( ( aExp == 0x7FF ) && ( aSig0 | aSig1 ) ) aSign = 0;
14312fe8fb19SBen Gras             goto invalid;
14322fe8fb19SBen Gras         }
14332fe8fb19SBen Gras         shortShift64Left(
14342fe8fb19SBen Gras             aSig0 | 0x00100000, aSig1, shiftCount, &absZ, &aSigExtra );
14352fe8fb19SBen Gras         if ( 0x80000000 < absZ ) goto invalid;
14362fe8fb19SBen Gras     }
14372fe8fb19SBen Gras     else {
14382fe8fb19SBen Gras         aSig1 = ( aSig1 != 0 );
14392fe8fb19SBen Gras         if ( aExp < 0x3FE ) {
14402fe8fb19SBen Gras             aSigExtra = aExp | aSig0 | aSig1;
14412fe8fb19SBen Gras             absZ = 0;
14422fe8fb19SBen Gras         }
14432fe8fb19SBen Gras         else {
14442fe8fb19SBen Gras             aSig0 |= 0x00100000;
14452fe8fb19SBen Gras             aSigExtra = ( aSig0<<( shiftCount & 31 ) ) | aSig1;
14462fe8fb19SBen Gras             absZ = aSig0>>( - shiftCount );
14472fe8fb19SBen Gras         }
14482fe8fb19SBen Gras     }
14492fe8fb19SBen Gras     roundingMode = float_rounding_mode;
14502fe8fb19SBen Gras     if ( roundingMode == float_round_nearest_even ) {
14512fe8fb19SBen Gras         if ( (sbits32) aSigExtra < 0 ) {
14522fe8fb19SBen Gras             ++absZ;
14532fe8fb19SBen Gras             if ( (bits32) ( aSigExtra<<1 ) == 0 ) absZ &= ~1;
14542fe8fb19SBen Gras         }
14552fe8fb19SBen Gras         z = aSign ? - absZ : absZ;
14562fe8fb19SBen Gras     }
14572fe8fb19SBen Gras     else {
14582fe8fb19SBen Gras         aSigExtra = ( aSigExtra != 0 );
14592fe8fb19SBen Gras         if ( aSign ) {
14602fe8fb19SBen Gras             z = - (   absZ
14612fe8fb19SBen Gras                     + ( ( roundingMode == float_round_down ) & aSigExtra ) );
14622fe8fb19SBen Gras         }
14632fe8fb19SBen Gras         else {
14642fe8fb19SBen Gras             z = absZ + ( ( roundingMode == float_round_up ) & aSigExtra );
14652fe8fb19SBen Gras         }
14662fe8fb19SBen Gras     }
14672fe8fb19SBen Gras     if ( ( aSign ^ ( z < 0 ) ) && z ) {
14682fe8fb19SBen Gras  invalid:
14692fe8fb19SBen Gras         float_raise( float_flag_invalid );
14702fe8fb19SBen Gras         return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF;
14712fe8fb19SBen Gras     }
1472*84d9c625SLionel Sambuc     if ( aSigExtra ) set_float_exception_inexact_flag();
14732fe8fb19SBen Gras     return z;
14742fe8fb19SBen Gras 
14752fe8fb19SBen Gras }
14762fe8fb19SBen Gras #endif /* !SOFTFLOAT_FOR_GCC */
14772fe8fb19SBen Gras 
14782fe8fb19SBen Gras /*
14792fe8fb19SBen Gras -------------------------------------------------------------------------------
14802fe8fb19SBen Gras Returns the result of converting the double-precision floating-point value
14812fe8fb19SBen Gras `a' to the 32-bit two's complement integer format.  The conversion is
14822fe8fb19SBen Gras performed according to the IEC/IEEE Standard for Binary Floating-Point
14832fe8fb19SBen Gras Arithmetic, except that the conversion is always rounded toward zero.
14842fe8fb19SBen Gras If `a' is a NaN, the largest positive integer is returned.  Otherwise, if
14852fe8fb19SBen Gras the conversion overflows, the largest integer with the same sign as `a' is
14862fe8fb19SBen Gras returned.
14872fe8fb19SBen Gras -------------------------------------------------------------------------------
14882fe8fb19SBen Gras */
float64_to_int32_round_to_zero(float64 a)14892fe8fb19SBen Gras int32 float64_to_int32_round_to_zero( float64 a )
14902fe8fb19SBen Gras {
14912fe8fb19SBen Gras     flag aSign;
14922fe8fb19SBen Gras     int16 aExp, shiftCount;
14932fe8fb19SBen Gras     bits32 aSig0, aSig1, absZ, aSigExtra;
14942fe8fb19SBen Gras     int32 z;
14952fe8fb19SBen Gras 
14962fe8fb19SBen Gras     aSig1 = extractFloat64Frac1( a );
14972fe8fb19SBen Gras     aSig0 = extractFloat64Frac0( a );
14982fe8fb19SBen Gras     aExp = extractFloat64Exp( a );
14992fe8fb19SBen Gras     aSign = extractFloat64Sign( a );
15002fe8fb19SBen Gras     shiftCount = aExp - 0x413;
15012fe8fb19SBen Gras     if ( 0 <= shiftCount ) {
15022fe8fb19SBen Gras         if ( 0x41E < aExp ) {
15032fe8fb19SBen Gras             if ( ( aExp == 0x7FF ) && ( aSig0 | aSig1 ) ) aSign = 0;
15042fe8fb19SBen Gras             goto invalid;
15052fe8fb19SBen Gras         }
15062fe8fb19SBen Gras         shortShift64Left(
15072fe8fb19SBen Gras             aSig0 | 0x00100000, aSig1, shiftCount, &absZ, &aSigExtra );
15082fe8fb19SBen Gras     }
15092fe8fb19SBen Gras     else {
15102fe8fb19SBen Gras         if ( aExp < 0x3FF ) {
15112fe8fb19SBen Gras             if ( aExp | aSig0 | aSig1 ) {
1512*84d9c625SLionel Sambuc                 set_float_exception_inexact_flag();
15132fe8fb19SBen Gras             }
15142fe8fb19SBen Gras             return 0;
15152fe8fb19SBen Gras         }
15162fe8fb19SBen Gras         aSig0 |= 0x00100000;
15172fe8fb19SBen Gras         aSigExtra = ( aSig0<<( shiftCount & 31 ) ) | aSig1;
15182fe8fb19SBen Gras         absZ = aSig0>>( - shiftCount );
15192fe8fb19SBen Gras     }
15202fe8fb19SBen Gras     z = aSign ? - absZ : absZ;
15212fe8fb19SBen Gras     if ( ( aSign ^ ( z < 0 ) ) && z ) {
15222fe8fb19SBen Gras  invalid:
15232fe8fb19SBen Gras         float_raise( float_flag_invalid );
15242fe8fb19SBen Gras         return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF;
15252fe8fb19SBen Gras     }
1526*84d9c625SLionel Sambuc     if ( aSigExtra ) set_float_exception_inexact_flag();
15272fe8fb19SBen Gras     return z;
15282fe8fb19SBen Gras 
15292fe8fb19SBen Gras }
15302fe8fb19SBen Gras 
15312fe8fb19SBen Gras /*
15322fe8fb19SBen Gras -------------------------------------------------------------------------------
15332fe8fb19SBen Gras Returns the result of converting the double-precision floating-point value
15342fe8fb19SBen Gras `a' to the single-precision floating-point format.  The conversion is
15352fe8fb19SBen Gras performed according to the IEC/IEEE Standard for Binary Floating-Point
15362fe8fb19SBen Gras Arithmetic.
15372fe8fb19SBen Gras -------------------------------------------------------------------------------
15382fe8fb19SBen Gras */
float64_to_float32(float64 a)15392fe8fb19SBen Gras float32 float64_to_float32( float64 a )
15402fe8fb19SBen Gras {
15412fe8fb19SBen Gras     flag aSign;
15422fe8fb19SBen Gras     int16 aExp;
15432fe8fb19SBen Gras     bits32 aSig0, aSig1, zSig;
15442fe8fb19SBen Gras     bits32 allZero;
15452fe8fb19SBen Gras 
15462fe8fb19SBen Gras     aSig1 = extractFloat64Frac1( a );
15472fe8fb19SBen Gras     aSig0 = extractFloat64Frac0( a );
15482fe8fb19SBen Gras     aExp = extractFloat64Exp( a );
15492fe8fb19SBen Gras     aSign = extractFloat64Sign( a );
15502fe8fb19SBen Gras     if ( aExp == 0x7FF ) {
15512fe8fb19SBen Gras         if ( aSig0 | aSig1 ) {
15522fe8fb19SBen Gras             return commonNaNToFloat32( float64ToCommonNaN( a ) );
15532fe8fb19SBen Gras         }
15542fe8fb19SBen Gras         return packFloat32( aSign, 0xFF, 0 );
15552fe8fb19SBen Gras     }
15562fe8fb19SBen Gras     shift64RightJamming( aSig0, aSig1, 22, &allZero, &zSig );
15572fe8fb19SBen Gras     if ( aExp ) zSig |= 0x40000000;
15582fe8fb19SBen Gras     return roundAndPackFloat32( aSign, aExp - 0x381, zSig );
15592fe8fb19SBen Gras 
15602fe8fb19SBen Gras }
15612fe8fb19SBen Gras 
15622fe8fb19SBen Gras #ifndef SOFTFLOAT_FOR_GCC
15632fe8fb19SBen Gras /*
15642fe8fb19SBen Gras -------------------------------------------------------------------------------
15652fe8fb19SBen Gras Rounds the double-precision floating-point value `a' to an integer,
15662fe8fb19SBen Gras and returns the result as a double-precision floating-point value.  The
15672fe8fb19SBen Gras operation is performed according to the IEC/IEEE Standard for Binary
15682fe8fb19SBen Gras Floating-Point Arithmetic.
15692fe8fb19SBen Gras -------------------------------------------------------------------------------
15702fe8fb19SBen Gras */
float64_round_to_int(float64 a)15712fe8fb19SBen Gras float64 float64_round_to_int( float64 a )
15722fe8fb19SBen Gras {
15732fe8fb19SBen Gras     flag aSign;
15742fe8fb19SBen Gras     int16 aExp;
15752fe8fb19SBen Gras     bits32 lastBitMask, roundBitsMask;
15762fe8fb19SBen Gras     int8 roundingMode;
15772fe8fb19SBen Gras     float64 z;
15782fe8fb19SBen Gras 
15792fe8fb19SBen Gras     aExp = extractFloat64Exp( a );
15802fe8fb19SBen Gras     if ( 0x413 <= aExp ) {
15812fe8fb19SBen Gras         if ( 0x433 <= aExp ) {
15822fe8fb19SBen Gras             if (    ( aExp == 0x7FF )
15832fe8fb19SBen Gras                  && ( extractFloat64Frac0( a ) | extractFloat64Frac1( a ) ) ) {
15842fe8fb19SBen Gras                 return propagateFloat64NaN( a, a );
15852fe8fb19SBen Gras             }
15862fe8fb19SBen Gras             return a;
15872fe8fb19SBen Gras         }
15882fe8fb19SBen Gras         lastBitMask = 1;
15892fe8fb19SBen Gras         lastBitMask = ( lastBitMask<<( 0x432 - aExp ) )<<1;
15902fe8fb19SBen Gras         roundBitsMask = lastBitMask - 1;
15912fe8fb19SBen Gras         z = a;
15922fe8fb19SBen Gras         roundingMode = float_rounding_mode;
15932fe8fb19SBen Gras         if ( roundingMode == float_round_nearest_even ) {
15942fe8fb19SBen Gras             if ( lastBitMask ) {
15952fe8fb19SBen Gras                 add64( z.high, z.low, 0, lastBitMask>>1, &z.high, &z.low );
15962fe8fb19SBen Gras                 if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;
15972fe8fb19SBen Gras             }
15982fe8fb19SBen Gras             else {
15992fe8fb19SBen Gras                 if ( (sbits32) z.low < 0 ) {
16002fe8fb19SBen Gras                     ++z.high;
16012fe8fb19SBen Gras                     if ( (bits32) ( z.low<<1 ) == 0 ) z.high &= ~1;
16022fe8fb19SBen Gras                 }
16032fe8fb19SBen Gras             }
16042fe8fb19SBen Gras         }
16052fe8fb19SBen Gras         else if ( roundingMode != float_round_to_zero ) {
16062fe8fb19SBen Gras             if (   extractFloat64Sign( z )
16072fe8fb19SBen Gras                  ^ ( roundingMode == float_round_up ) ) {
16082fe8fb19SBen Gras                 add64( z.high, z.low, 0, roundBitsMask, &z.high, &z.low );
16092fe8fb19SBen Gras             }
16102fe8fb19SBen Gras         }
16112fe8fb19SBen Gras         z.low &= ~ roundBitsMask;
16122fe8fb19SBen Gras     }
16132fe8fb19SBen Gras     else {
16142fe8fb19SBen Gras         if ( aExp <= 0x3FE ) {
16152fe8fb19SBen Gras             if ( ( ( (bits32) ( a.high<<1 ) ) | a.low ) == 0 ) return a;
1616*84d9c625SLionel Sambuc             set_float_exception_inexact_flag();
16172fe8fb19SBen Gras             aSign = extractFloat64Sign( a );
16182fe8fb19SBen Gras             switch ( float_rounding_mode ) {
16192fe8fb19SBen Gras              case float_round_nearest_even:
16202fe8fb19SBen Gras                 if (    ( aExp == 0x3FE )
16212fe8fb19SBen Gras                      && ( extractFloat64Frac0( a ) | extractFloat64Frac1( a ) )
16222fe8fb19SBen Gras                    ) {
16232fe8fb19SBen Gras                     return packFloat64( aSign, 0x3FF, 0, 0 );
16242fe8fb19SBen Gras                 }
16252fe8fb19SBen Gras                 break;
16262fe8fb19SBen Gras              case float_round_down:
16272fe8fb19SBen Gras                 return
16282fe8fb19SBen Gras                       aSign ? packFloat64( 1, 0x3FF, 0, 0 )
16292fe8fb19SBen Gras                     : packFloat64( 0, 0, 0, 0 );
16302fe8fb19SBen Gras              case float_round_up:
16312fe8fb19SBen Gras                 return
16322fe8fb19SBen Gras                       aSign ? packFloat64( 1, 0, 0, 0 )
16332fe8fb19SBen Gras                     : packFloat64( 0, 0x3FF, 0, 0 );
16342fe8fb19SBen Gras             }
16352fe8fb19SBen Gras             return packFloat64( aSign, 0, 0, 0 );
16362fe8fb19SBen Gras         }
16372fe8fb19SBen Gras         lastBitMask = 1;
16382fe8fb19SBen Gras         lastBitMask <<= 0x413 - aExp;
16392fe8fb19SBen Gras         roundBitsMask = lastBitMask - 1;
16402fe8fb19SBen Gras         z.low = 0;
16412fe8fb19SBen Gras         z.high = a.high;
16422fe8fb19SBen Gras         roundingMode = float_rounding_mode;
16432fe8fb19SBen Gras         if ( roundingMode == float_round_nearest_even ) {
16442fe8fb19SBen Gras             z.high += lastBitMask>>1;
16452fe8fb19SBen Gras             if ( ( ( z.high & roundBitsMask ) | a.low ) == 0 ) {
16462fe8fb19SBen Gras                 z.high &= ~ lastBitMask;
16472fe8fb19SBen Gras             }
16482fe8fb19SBen Gras         }
16492fe8fb19SBen Gras         else if ( roundingMode != float_round_to_zero ) {
16502fe8fb19SBen Gras             if (   extractFloat64Sign( z )
16512fe8fb19SBen Gras                  ^ ( roundingMode == float_round_up ) ) {
16522fe8fb19SBen Gras                 z.high |= ( a.low != 0 );
16532fe8fb19SBen Gras                 z.high += roundBitsMask;
16542fe8fb19SBen Gras             }
16552fe8fb19SBen Gras         }
16562fe8fb19SBen Gras         z.high &= ~ roundBitsMask;
16572fe8fb19SBen Gras     }
16582fe8fb19SBen Gras     if ( ( z.low != a.low ) || ( z.high != a.high ) ) {
1659*84d9c625SLionel Sambuc         set_float_exception_inexact_flag();
16602fe8fb19SBen Gras     }
16612fe8fb19SBen Gras     return z;
16622fe8fb19SBen Gras 
16632fe8fb19SBen Gras }
16642fe8fb19SBen Gras #endif
16652fe8fb19SBen Gras 
16662fe8fb19SBen Gras /*
16672fe8fb19SBen Gras -------------------------------------------------------------------------------
16682fe8fb19SBen Gras Returns the result of adding the absolute values of the double-precision
16692fe8fb19SBen Gras floating-point values `a' and `b'.  If `zSign' is 1, the sum is negated
16702fe8fb19SBen Gras before being returned.  `zSign' is ignored if the result is a NaN.
16712fe8fb19SBen Gras The addition is performed according to the IEC/IEEE Standard for Binary
16722fe8fb19SBen Gras Floating-Point Arithmetic.
16732fe8fb19SBen Gras -------------------------------------------------------------------------------
16742fe8fb19SBen Gras */
addFloat64Sigs(float64 a,float64 b,flag zSign)16752fe8fb19SBen Gras static float64 addFloat64Sigs( float64 a, float64 b, flag zSign )
16762fe8fb19SBen Gras {
16772fe8fb19SBen Gras     int16 aExp, bExp, zExp;
16782fe8fb19SBen Gras     bits32 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
16792fe8fb19SBen Gras     int16 expDiff;
16802fe8fb19SBen Gras 
16812fe8fb19SBen Gras     aSig1 = extractFloat64Frac1( a );
16822fe8fb19SBen Gras     aSig0 = extractFloat64Frac0( a );
16832fe8fb19SBen Gras     aExp = extractFloat64Exp( a );
16842fe8fb19SBen Gras     bSig1 = extractFloat64Frac1( b );
16852fe8fb19SBen Gras     bSig0 = extractFloat64Frac0( b );
16862fe8fb19SBen Gras     bExp = extractFloat64Exp( b );
16872fe8fb19SBen Gras     expDiff = aExp - bExp;
16882fe8fb19SBen Gras     if ( 0 < expDiff ) {
16892fe8fb19SBen Gras         if ( aExp == 0x7FF ) {
16902fe8fb19SBen Gras             if ( aSig0 | aSig1 ) return propagateFloat64NaN( a, b );
16912fe8fb19SBen Gras             return a;
16922fe8fb19SBen Gras         }
16932fe8fb19SBen Gras         if ( bExp == 0 ) {
16942fe8fb19SBen Gras             --expDiff;
16952fe8fb19SBen Gras         }
16962fe8fb19SBen Gras         else {
16972fe8fb19SBen Gras             bSig0 |= 0x00100000;
16982fe8fb19SBen Gras         }
16992fe8fb19SBen Gras         shift64ExtraRightJamming(
17002fe8fb19SBen Gras             bSig0, bSig1, 0, expDiff, &bSig0, &bSig1, &zSig2 );
17012fe8fb19SBen Gras         zExp = aExp;
17022fe8fb19SBen Gras     }
17032fe8fb19SBen Gras     else if ( expDiff < 0 ) {
17042fe8fb19SBen Gras         if ( bExp == 0x7FF ) {
17052fe8fb19SBen Gras             if ( bSig0 | bSig1 ) return propagateFloat64NaN( a, b );
17062fe8fb19SBen Gras             return packFloat64( zSign, 0x7FF, 0, 0 );
17072fe8fb19SBen Gras         }
17082fe8fb19SBen Gras         if ( aExp == 0 ) {
17092fe8fb19SBen Gras             ++expDiff;
17102fe8fb19SBen Gras         }
17112fe8fb19SBen Gras         else {
17122fe8fb19SBen Gras             aSig0 |= 0x00100000;
17132fe8fb19SBen Gras         }
17142fe8fb19SBen Gras         shift64ExtraRightJamming(
17152fe8fb19SBen Gras             aSig0, aSig1, 0, - expDiff, &aSig0, &aSig1, &zSig2 );
17162fe8fb19SBen Gras         zExp = bExp;
17172fe8fb19SBen Gras     }
17182fe8fb19SBen Gras     else {
17192fe8fb19SBen Gras         if ( aExp == 0x7FF ) {
17202fe8fb19SBen Gras             if ( aSig0 | aSig1 | bSig0 | bSig1 ) {
17212fe8fb19SBen Gras                 return propagateFloat64NaN( a, b );
17222fe8fb19SBen Gras             }
17232fe8fb19SBen Gras             return a;
17242fe8fb19SBen Gras         }
17252fe8fb19SBen Gras         add64( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
17262fe8fb19SBen Gras         if ( aExp == 0 ) return packFloat64( zSign, 0, zSig0, zSig1 );
17272fe8fb19SBen Gras         zSig2 = 0;
17282fe8fb19SBen Gras         zSig0 |= 0x00200000;
17292fe8fb19SBen Gras         zExp = aExp;
17302fe8fb19SBen Gras         goto shiftRight1;
17312fe8fb19SBen Gras     }
17322fe8fb19SBen Gras     aSig0 |= 0x00100000;
17332fe8fb19SBen Gras     add64( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
17342fe8fb19SBen Gras     --zExp;
17352fe8fb19SBen Gras     if ( zSig0 < 0x00200000 ) goto roundAndPack;
17362fe8fb19SBen Gras     ++zExp;
17372fe8fb19SBen Gras  shiftRight1:
17382fe8fb19SBen Gras     shift64ExtraRightJamming( zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 );
17392fe8fb19SBen Gras  roundAndPack:
17402fe8fb19SBen Gras     return roundAndPackFloat64( zSign, zExp, zSig0, zSig1, zSig2 );
17412fe8fb19SBen Gras 
17422fe8fb19SBen Gras }
17432fe8fb19SBen Gras 
17442fe8fb19SBen Gras /*
17452fe8fb19SBen Gras -------------------------------------------------------------------------------
17462fe8fb19SBen Gras Returns the result of subtracting the absolute values of the double-
17472fe8fb19SBen Gras precision floating-point values `a' and `b'.  If `zSign' is 1, the
17482fe8fb19SBen Gras difference is negated before being returned.  `zSign' is ignored if the
17492fe8fb19SBen Gras result is a NaN.  The subtraction is performed according to the IEC/IEEE
17502fe8fb19SBen Gras Standard for Binary Floating-Point Arithmetic.
17512fe8fb19SBen Gras -------------------------------------------------------------------------------
17522fe8fb19SBen Gras */
subFloat64Sigs(float64 a,float64 b,flag zSign)17532fe8fb19SBen Gras static float64 subFloat64Sigs( float64 a, float64 b, flag zSign )
17542fe8fb19SBen Gras {
17552fe8fb19SBen Gras     int16 aExp, bExp, zExp;
17562fe8fb19SBen Gras     bits32 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1;
17572fe8fb19SBen Gras     int16 expDiff;
17582fe8fb19SBen Gras 
17592fe8fb19SBen Gras     aSig1 = extractFloat64Frac1( a );
17602fe8fb19SBen Gras     aSig0 = extractFloat64Frac0( a );
17612fe8fb19SBen Gras     aExp = extractFloat64Exp( a );
17622fe8fb19SBen Gras     bSig1 = extractFloat64Frac1( b );
17632fe8fb19SBen Gras     bSig0 = extractFloat64Frac0( b );
17642fe8fb19SBen Gras     bExp = extractFloat64Exp( b );
17652fe8fb19SBen Gras     expDiff = aExp - bExp;
17662fe8fb19SBen Gras     shortShift64Left( aSig0, aSig1, 10, &aSig0, &aSig1 );
17672fe8fb19SBen Gras     shortShift64Left( bSig0, bSig1, 10, &bSig0, &bSig1 );
17682fe8fb19SBen Gras     if ( 0 < expDiff ) goto aExpBigger;
17692fe8fb19SBen Gras     if ( expDiff < 0 ) goto bExpBigger;
17702fe8fb19SBen Gras     if ( aExp == 0x7FF ) {
17712fe8fb19SBen Gras         if ( aSig0 | aSig1 | bSig0 | bSig1 ) {
17722fe8fb19SBen Gras             return propagateFloat64NaN( a, b );
17732fe8fb19SBen Gras         }
17742fe8fb19SBen Gras         float_raise( float_flag_invalid );
17752fe8fb19SBen Gras         return float64_default_nan;
17762fe8fb19SBen Gras     }
17772fe8fb19SBen Gras     if ( aExp == 0 ) {
17782fe8fb19SBen Gras         aExp = 1;
17792fe8fb19SBen Gras         bExp = 1;
17802fe8fb19SBen Gras     }
17812fe8fb19SBen Gras     if ( bSig0 < aSig0 ) goto aBigger;
17822fe8fb19SBen Gras     if ( aSig0 < bSig0 ) goto bBigger;
17832fe8fb19SBen Gras     if ( bSig1 < aSig1 ) goto aBigger;
17842fe8fb19SBen Gras     if ( aSig1 < bSig1 ) goto bBigger;
17852fe8fb19SBen Gras     return packFloat64( float_rounding_mode == float_round_down, 0, 0, 0 );
17862fe8fb19SBen Gras  bExpBigger:
17872fe8fb19SBen Gras     if ( bExp == 0x7FF ) {
17882fe8fb19SBen Gras         if ( bSig0 | bSig1 ) return propagateFloat64NaN( a, b );
17892fe8fb19SBen Gras         return packFloat64( zSign ^ 1, 0x7FF, 0, 0 );
17902fe8fb19SBen Gras     }
17912fe8fb19SBen Gras     if ( aExp == 0 ) {
17922fe8fb19SBen Gras         ++expDiff;
17932fe8fb19SBen Gras     }
17942fe8fb19SBen Gras     else {
17952fe8fb19SBen Gras         aSig0 |= 0x40000000;
17962fe8fb19SBen Gras     }
17972fe8fb19SBen Gras     shift64RightJamming( aSig0, aSig1, - expDiff, &aSig0, &aSig1 );
17982fe8fb19SBen Gras     bSig0 |= 0x40000000;
17992fe8fb19SBen Gras  bBigger:
18002fe8fb19SBen Gras     sub64( bSig0, bSig1, aSig0, aSig1, &zSig0, &zSig1 );
18012fe8fb19SBen Gras     zExp = bExp;
18022fe8fb19SBen Gras     zSign ^= 1;
18032fe8fb19SBen Gras     goto normalizeRoundAndPack;
18042fe8fb19SBen Gras  aExpBigger:
18052fe8fb19SBen Gras     if ( aExp == 0x7FF ) {
18062fe8fb19SBen Gras         if ( aSig0 | aSig1 ) return propagateFloat64NaN( a, b );
18072fe8fb19SBen Gras         return a;
18082fe8fb19SBen Gras     }
18092fe8fb19SBen Gras     if ( bExp == 0 ) {
18102fe8fb19SBen Gras         --expDiff;
18112fe8fb19SBen Gras     }
18122fe8fb19SBen Gras     else {
18132fe8fb19SBen Gras         bSig0 |= 0x40000000;
18142fe8fb19SBen Gras     }
18152fe8fb19SBen Gras     shift64RightJamming( bSig0, bSig1, expDiff, &bSig0, &bSig1 );
18162fe8fb19SBen Gras     aSig0 |= 0x40000000;
18172fe8fb19SBen Gras  aBigger:
18182fe8fb19SBen Gras     sub64( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
18192fe8fb19SBen Gras     zExp = aExp;
18202fe8fb19SBen Gras  normalizeRoundAndPack:
18212fe8fb19SBen Gras     --zExp;
18222fe8fb19SBen Gras     return normalizeRoundAndPackFloat64( zSign, zExp - 10, zSig0, zSig1 );
18232fe8fb19SBen Gras 
18242fe8fb19SBen Gras }
18252fe8fb19SBen Gras 
18262fe8fb19SBen Gras /*
18272fe8fb19SBen Gras -------------------------------------------------------------------------------
18282fe8fb19SBen Gras Returns the result of adding the double-precision floating-point values `a'
18292fe8fb19SBen Gras and `b'.  The operation is performed according to the IEC/IEEE Standard for
18302fe8fb19SBen Gras Binary Floating-Point Arithmetic.
18312fe8fb19SBen Gras -------------------------------------------------------------------------------
18322fe8fb19SBen Gras */
float64_add(float64 a,float64 b)18332fe8fb19SBen Gras float64 float64_add( float64 a, float64 b )
18342fe8fb19SBen Gras {
18352fe8fb19SBen Gras     flag aSign, bSign;
18362fe8fb19SBen Gras 
18372fe8fb19SBen Gras     aSign = extractFloat64Sign( a );
18382fe8fb19SBen Gras     bSign = extractFloat64Sign( b );
18392fe8fb19SBen Gras     if ( aSign == bSign ) {
18402fe8fb19SBen Gras         return addFloat64Sigs( a, b, aSign );
18412fe8fb19SBen Gras     }
18422fe8fb19SBen Gras     else {
18432fe8fb19SBen Gras         return subFloat64Sigs( a, b, aSign );
18442fe8fb19SBen Gras     }
18452fe8fb19SBen Gras 
18462fe8fb19SBen Gras }
18472fe8fb19SBen Gras 
18482fe8fb19SBen Gras /*
18492fe8fb19SBen Gras -------------------------------------------------------------------------------
18502fe8fb19SBen Gras Returns the result of subtracting the double-precision floating-point values
18512fe8fb19SBen Gras `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
18522fe8fb19SBen Gras for Binary Floating-Point Arithmetic.
18532fe8fb19SBen Gras -------------------------------------------------------------------------------
18542fe8fb19SBen Gras */
float64_sub(float64 a,float64 b)18552fe8fb19SBen Gras float64 float64_sub( float64 a, float64 b )
18562fe8fb19SBen Gras {
18572fe8fb19SBen Gras     flag aSign, bSign;
18582fe8fb19SBen Gras 
18592fe8fb19SBen Gras     aSign = extractFloat64Sign( a );
18602fe8fb19SBen Gras     bSign = extractFloat64Sign( b );
18612fe8fb19SBen Gras     if ( aSign == bSign ) {
18622fe8fb19SBen Gras         return subFloat64Sigs( a, b, aSign );
18632fe8fb19SBen Gras     }
18642fe8fb19SBen Gras     else {
18652fe8fb19SBen Gras         return addFloat64Sigs( a, b, aSign );
18662fe8fb19SBen Gras     }
18672fe8fb19SBen Gras 
18682fe8fb19SBen Gras }
18692fe8fb19SBen Gras 
18702fe8fb19SBen Gras /*
18712fe8fb19SBen Gras -------------------------------------------------------------------------------
18722fe8fb19SBen Gras Returns the result of multiplying the double-precision floating-point values
18732fe8fb19SBen Gras `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
18742fe8fb19SBen Gras for Binary Floating-Point Arithmetic.
18752fe8fb19SBen Gras -------------------------------------------------------------------------------
18762fe8fb19SBen Gras */
float64_mul(float64 a,float64 b)18772fe8fb19SBen Gras float64 float64_mul( float64 a, float64 b )
18782fe8fb19SBen Gras {
18792fe8fb19SBen Gras     flag aSign, bSign, zSign;
18802fe8fb19SBen Gras     int16 aExp, bExp, zExp;
18812fe8fb19SBen Gras     bits32 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2, zSig3;
18822fe8fb19SBen Gras 
18832fe8fb19SBen Gras     aSig1 = extractFloat64Frac1( a );
18842fe8fb19SBen Gras     aSig0 = extractFloat64Frac0( a );
18852fe8fb19SBen Gras     aExp = extractFloat64Exp( a );
18862fe8fb19SBen Gras     aSign = extractFloat64Sign( a );
18872fe8fb19SBen Gras     bSig1 = extractFloat64Frac1( b );
18882fe8fb19SBen Gras     bSig0 = extractFloat64Frac0( b );
18892fe8fb19SBen Gras     bExp = extractFloat64Exp( b );
18902fe8fb19SBen Gras     bSign = extractFloat64Sign( b );
18912fe8fb19SBen Gras     zSign = aSign ^ bSign;
18922fe8fb19SBen Gras     if ( aExp == 0x7FF ) {
18932fe8fb19SBen Gras         if (    ( aSig0 | aSig1 )
18942fe8fb19SBen Gras              || ( ( bExp == 0x7FF ) && ( bSig0 | bSig1 ) ) ) {
18952fe8fb19SBen Gras             return propagateFloat64NaN( a, b );
18962fe8fb19SBen Gras         }
18972fe8fb19SBen Gras         if ( ( bExp | bSig0 | bSig1 ) == 0 ) goto invalid;
18982fe8fb19SBen Gras         return packFloat64( zSign, 0x7FF, 0, 0 );
18992fe8fb19SBen Gras     }
19002fe8fb19SBen Gras     if ( bExp == 0x7FF ) {
19012fe8fb19SBen Gras         if ( bSig0 | bSig1 ) return propagateFloat64NaN( a, b );
19022fe8fb19SBen Gras         if ( ( aExp | aSig0 | aSig1 ) == 0 ) {
19032fe8fb19SBen Gras  invalid:
19042fe8fb19SBen Gras             float_raise( float_flag_invalid );
19052fe8fb19SBen Gras             return float64_default_nan;
19062fe8fb19SBen Gras         }
19072fe8fb19SBen Gras         return packFloat64( zSign, 0x7FF, 0, 0 );
19082fe8fb19SBen Gras     }
19092fe8fb19SBen Gras     if ( aExp == 0 ) {
19102fe8fb19SBen Gras         if ( ( aSig0 | aSig1 ) == 0 ) return packFloat64( zSign, 0, 0, 0 );
19112fe8fb19SBen Gras         normalizeFloat64Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
19122fe8fb19SBen Gras     }
19132fe8fb19SBen Gras     if ( bExp == 0 ) {
19142fe8fb19SBen Gras         if ( ( bSig0 | bSig1 ) == 0 ) return packFloat64( zSign, 0, 0, 0 );
19152fe8fb19SBen Gras         normalizeFloat64Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
19162fe8fb19SBen Gras     }
19172fe8fb19SBen Gras     zExp = aExp + bExp - 0x400;
19182fe8fb19SBen Gras     aSig0 |= 0x00100000;
19192fe8fb19SBen Gras     shortShift64Left( bSig0, bSig1, 12, &bSig0, &bSig1 );
19202fe8fb19SBen Gras     mul64To128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1, &zSig2, &zSig3 );
19212fe8fb19SBen Gras     add64( zSig0, zSig1, aSig0, aSig1, &zSig0, &zSig1 );
19222fe8fb19SBen Gras     zSig2 |= ( zSig3 != 0 );
19232fe8fb19SBen Gras     if ( 0x00200000 <= zSig0 ) {
19242fe8fb19SBen Gras         shift64ExtraRightJamming(
19252fe8fb19SBen Gras             zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 );
19262fe8fb19SBen Gras         ++zExp;
19272fe8fb19SBen Gras     }
19282fe8fb19SBen Gras     return roundAndPackFloat64( zSign, zExp, zSig0, zSig1, zSig2 );
19292fe8fb19SBen Gras 
19302fe8fb19SBen Gras }
19312fe8fb19SBen Gras 
19322fe8fb19SBen Gras /*
19332fe8fb19SBen Gras -------------------------------------------------------------------------------
19342fe8fb19SBen Gras Returns the result of dividing the double-precision floating-point value `a'
19352fe8fb19SBen Gras by the corresponding value `b'.  The operation is performed according to the
19362fe8fb19SBen Gras IEC/IEEE Standard for Binary Floating-Point Arithmetic.
19372fe8fb19SBen Gras -------------------------------------------------------------------------------
19382fe8fb19SBen Gras */
float64_div(float64 a,float64 b)19392fe8fb19SBen Gras float64 float64_div( float64 a, float64 b )
19402fe8fb19SBen Gras {
19412fe8fb19SBen Gras     flag aSign, bSign, zSign;
19422fe8fb19SBen Gras     int16 aExp, bExp, zExp;
19432fe8fb19SBen Gras     bits32 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
19442fe8fb19SBen Gras     bits32 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
19452fe8fb19SBen Gras 
19462fe8fb19SBen Gras     aSig1 = extractFloat64Frac1( a );
19472fe8fb19SBen Gras     aSig0 = extractFloat64Frac0( a );
19482fe8fb19SBen Gras     aExp = extractFloat64Exp( a );
19492fe8fb19SBen Gras     aSign = extractFloat64Sign( a );
19502fe8fb19SBen Gras     bSig1 = extractFloat64Frac1( b );
19512fe8fb19SBen Gras     bSig0 = extractFloat64Frac0( b );
19522fe8fb19SBen Gras     bExp = extractFloat64Exp( b );
19532fe8fb19SBen Gras     bSign = extractFloat64Sign( b );
19542fe8fb19SBen Gras     zSign = aSign ^ bSign;
19552fe8fb19SBen Gras     if ( aExp == 0x7FF ) {
19562fe8fb19SBen Gras         if ( aSig0 | aSig1 ) return propagateFloat64NaN( a, b );
19572fe8fb19SBen Gras         if ( bExp == 0x7FF ) {
19582fe8fb19SBen Gras             if ( bSig0 | bSig1 ) return propagateFloat64NaN( a, b );
19592fe8fb19SBen Gras             goto invalid;
19602fe8fb19SBen Gras         }
19612fe8fb19SBen Gras         return packFloat64( zSign, 0x7FF, 0, 0 );
19622fe8fb19SBen Gras     }
19632fe8fb19SBen Gras     if ( bExp == 0x7FF ) {
19642fe8fb19SBen Gras         if ( bSig0 | bSig1 ) return propagateFloat64NaN( a, b );
19652fe8fb19SBen Gras         return packFloat64( zSign, 0, 0, 0 );
19662fe8fb19SBen Gras     }
19672fe8fb19SBen Gras     if ( bExp == 0 ) {
19682fe8fb19SBen Gras         if ( ( bSig0 | bSig1 ) == 0 ) {
19692fe8fb19SBen Gras             if ( ( aExp | aSig0 | aSig1 ) == 0 ) {
19702fe8fb19SBen Gras  invalid:
19712fe8fb19SBen Gras                 float_raise( float_flag_invalid );
19722fe8fb19SBen Gras                 return float64_default_nan;
19732fe8fb19SBen Gras             }
19742fe8fb19SBen Gras             float_raise( float_flag_divbyzero );
19752fe8fb19SBen Gras             return packFloat64( zSign, 0x7FF, 0, 0 );
19762fe8fb19SBen Gras         }
19772fe8fb19SBen Gras         normalizeFloat64Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
19782fe8fb19SBen Gras     }
19792fe8fb19SBen Gras     if ( aExp == 0 ) {
19802fe8fb19SBen Gras         if ( ( aSig0 | aSig1 ) == 0 ) return packFloat64( zSign, 0, 0, 0 );
19812fe8fb19SBen Gras         normalizeFloat64Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
19822fe8fb19SBen Gras     }
19832fe8fb19SBen Gras     zExp = aExp - bExp + 0x3FD;
19842fe8fb19SBen Gras     shortShift64Left( aSig0 | 0x00100000, aSig1, 11, &aSig0, &aSig1 );
19852fe8fb19SBen Gras     shortShift64Left( bSig0 | 0x00100000, bSig1, 11, &bSig0, &bSig1 );
19862fe8fb19SBen Gras     if ( le64( bSig0, bSig1, aSig0, aSig1 ) ) {
19872fe8fb19SBen Gras         shift64Right( aSig0, aSig1, 1, &aSig0, &aSig1 );
19882fe8fb19SBen Gras         ++zExp;
19892fe8fb19SBen Gras     }
19902fe8fb19SBen Gras     zSig0 = estimateDiv64To32( aSig0, aSig1, bSig0 );
19912fe8fb19SBen Gras     mul64By32To96( bSig0, bSig1, zSig0, &term0, &term1, &term2 );
19922fe8fb19SBen Gras     sub96( aSig0, aSig1, 0, term0, term1, term2, &rem0, &rem1, &rem2 );
19932fe8fb19SBen Gras     while ( (sbits32) rem0 < 0 ) {
19942fe8fb19SBen Gras         --zSig0;
19952fe8fb19SBen Gras         add96( rem0, rem1, rem2, 0, bSig0, bSig1, &rem0, &rem1, &rem2 );
19962fe8fb19SBen Gras     }
19972fe8fb19SBen Gras     zSig1 = estimateDiv64To32( rem1, rem2, bSig0 );
19982fe8fb19SBen Gras     if ( ( zSig1 & 0x3FF ) <= 4 ) {
19992fe8fb19SBen Gras         mul64By32To96( bSig0, bSig1, zSig1, &term1, &term2, &term3 );
20002fe8fb19SBen Gras         sub96( rem1, rem2, 0, term1, term2, term3, &rem1, &rem2, &rem3 );
20012fe8fb19SBen Gras         while ( (sbits32) rem1 < 0 ) {
20022fe8fb19SBen Gras             --zSig1;
20032fe8fb19SBen Gras             add96( rem1, rem2, rem3, 0, bSig0, bSig1, &rem1, &rem2, &rem3 );
20042fe8fb19SBen Gras         }
20052fe8fb19SBen Gras         zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
20062fe8fb19SBen Gras     }
20072fe8fb19SBen Gras     shift64ExtraRightJamming( zSig0, zSig1, 0, 11, &zSig0, &zSig1, &zSig2 );
20082fe8fb19SBen Gras     return roundAndPackFloat64( zSign, zExp, zSig0, zSig1, zSig2 );
20092fe8fb19SBen Gras 
20102fe8fb19SBen Gras }
20112fe8fb19SBen Gras 
20122fe8fb19SBen Gras #ifndef SOFTFLOAT_FOR_GCC
20132fe8fb19SBen Gras /*
20142fe8fb19SBen Gras -------------------------------------------------------------------------------
20152fe8fb19SBen Gras Returns the remainder of the double-precision floating-point value `a'
20162fe8fb19SBen Gras with respect to the corresponding value `b'.  The operation is performed
20172fe8fb19SBen Gras according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
20182fe8fb19SBen Gras -------------------------------------------------------------------------------
20192fe8fb19SBen Gras */
float64_rem(float64 a,float64 b)20202fe8fb19SBen Gras float64 float64_rem( float64 a, float64 b )
20212fe8fb19SBen Gras {
20222fe8fb19SBen Gras     flag aSign, bSign, zSign;
20232fe8fb19SBen Gras     int16 aExp, bExp, expDiff;
20242fe8fb19SBen Gras     bits32 aSig0, aSig1, bSig0, bSig1, q, term0, term1, term2;
20252fe8fb19SBen Gras     bits32 allZero, alternateASig0, alternateASig1, sigMean1;
20262fe8fb19SBen Gras     sbits32 sigMean0;
20272fe8fb19SBen Gras     float64 z;
20282fe8fb19SBen Gras 
20292fe8fb19SBen Gras     aSig1 = extractFloat64Frac1( a );
20302fe8fb19SBen Gras     aSig0 = extractFloat64Frac0( a );
20312fe8fb19SBen Gras     aExp = extractFloat64Exp( a );
20322fe8fb19SBen Gras     aSign = extractFloat64Sign( a );
20332fe8fb19SBen Gras     bSig1 = extractFloat64Frac1( b );
20342fe8fb19SBen Gras     bSig0 = extractFloat64Frac0( b );
20352fe8fb19SBen Gras     bExp = extractFloat64Exp( b );
20362fe8fb19SBen Gras     bSign = extractFloat64Sign( b );
20372fe8fb19SBen Gras     if ( aExp == 0x7FF ) {
20382fe8fb19SBen Gras         if (    ( aSig0 | aSig1 )
20392fe8fb19SBen Gras              || ( ( bExp == 0x7FF ) && ( bSig0 | bSig1 ) ) ) {
20402fe8fb19SBen Gras             return propagateFloat64NaN( a, b );
20412fe8fb19SBen Gras         }
20422fe8fb19SBen Gras         goto invalid;
20432fe8fb19SBen Gras     }
20442fe8fb19SBen Gras     if ( bExp == 0x7FF ) {
20452fe8fb19SBen Gras         if ( bSig0 | bSig1 ) return propagateFloat64NaN( a, b );
20462fe8fb19SBen Gras         return a;
20472fe8fb19SBen Gras     }
20482fe8fb19SBen Gras     if ( bExp == 0 ) {
20492fe8fb19SBen Gras         if ( ( bSig0 | bSig1 ) == 0 ) {
20502fe8fb19SBen Gras  invalid:
20512fe8fb19SBen Gras             float_raise( float_flag_invalid );
20522fe8fb19SBen Gras             return float64_default_nan;
20532fe8fb19SBen Gras         }
20542fe8fb19SBen Gras         normalizeFloat64Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
20552fe8fb19SBen Gras     }
20562fe8fb19SBen Gras     if ( aExp == 0 ) {
20572fe8fb19SBen Gras         if ( ( aSig0 | aSig1 ) == 0 ) return a;
20582fe8fb19SBen Gras         normalizeFloat64Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
20592fe8fb19SBen Gras     }
20602fe8fb19SBen Gras     expDiff = aExp - bExp;
20612fe8fb19SBen Gras     if ( expDiff < -1 ) return a;
20622fe8fb19SBen Gras     shortShift64Left(
20632fe8fb19SBen Gras         aSig0 | 0x00100000, aSig1, 11 - ( expDiff < 0 ), &aSig0, &aSig1 );
20642fe8fb19SBen Gras     shortShift64Left( bSig0 | 0x00100000, bSig1, 11, &bSig0, &bSig1 );
20652fe8fb19SBen Gras     q = le64( bSig0, bSig1, aSig0, aSig1 );
20662fe8fb19SBen Gras     if ( q ) sub64( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 );
20672fe8fb19SBen Gras     expDiff -= 32;
20682fe8fb19SBen Gras     while ( 0 < expDiff ) {
20692fe8fb19SBen Gras         q = estimateDiv64To32( aSig0, aSig1, bSig0 );
20702fe8fb19SBen Gras         q = ( 4 < q ) ? q - 4 : 0;
20712fe8fb19SBen Gras         mul64By32To96( bSig0, bSig1, q, &term0, &term1, &term2 );
20722fe8fb19SBen Gras         shortShift96Left( term0, term1, term2, 29, &term1, &term2, &allZero );
20732fe8fb19SBen Gras         shortShift64Left( aSig0, aSig1, 29, &aSig0, &allZero );
20742fe8fb19SBen Gras         sub64( aSig0, 0, term1, term2, &aSig0, &aSig1 );
20752fe8fb19SBen Gras         expDiff -= 29;
20762fe8fb19SBen Gras     }
20772fe8fb19SBen Gras     if ( -32 < expDiff ) {
20782fe8fb19SBen Gras         q = estimateDiv64To32( aSig0, aSig1, bSig0 );
20792fe8fb19SBen Gras         q = ( 4 < q ) ? q - 4 : 0;
20802fe8fb19SBen Gras         q >>= - expDiff;
20812fe8fb19SBen Gras         shift64Right( bSig0, bSig1, 8, &bSig0, &bSig1 );
20822fe8fb19SBen Gras         expDiff += 24;
20832fe8fb19SBen Gras         if ( expDiff < 0 ) {
20842fe8fb19SBen Gras             shift64Right( aSig0, aSig1, - expDiff, &aSig0, &aSig1 );
20852fe8fb19SBen Gras         }
20862fe8fb19SBen Gras         else {
20872fe8fb19SBen Gras             shortShift64Left( aSig0, aSig1, expDiff, &aSig0, &aSig1 );
20882fe8fb19SBen Gras         }
20892fe8fb19SBen Gras         mul64By32To96( bSig0, bSig1, q, &term0, &term1, &term2 );
20902fe8fb19SBen Gras         sub64( aSig0, aSig1, term1, term2, &aSig0, &aSig1 );
20912fe8fb19SBen Gras     }
20922fe8fb19SBen Gras     else {
20932fe8fb19SBen Gras         shift64Right( aSig0, aSig1, 8, &aSig0, &aSig1 );
20942fe8fb19SBen Gras         shift64Right( bSig0, bSig1, 8, &bSig0, &bSig1 );
20952fe8fb19SBen Gras     }
20962fe8fb19SBen Gras     do {
20972fe8fb19SBen Gras         alternateASig0 = aSig0;
20982fe8fb19SBen Gras         alternateASig1 = aSig1;
20992fe8fb19SBen Gras         ++q;
21002fe8fb19SBen Gras         sub64( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 );
21012fe8fb19SBen Gras     } while ( 0 <= (sbits32) aSig0 );
21022fe8fb19SBen Gras     add64(
21032fe8fb19SBen Gras         aSig0, aSig1, alternateASig0, alternateASig1, &sigMean0, &sigMean1 );
21042fe8fb19SBen Gras     if (    ( sigMean0 < 0 )
21052fe8fb19SBen Gras          || ( ( ( sigMean0 | sigMean1 ) == 0 ) && ( q & 1 ) ) ) {
21062fe8fb19SBen Gras         aSig0 = alternateASig0;
21072fe8fb19SBen Gras         aSig1 = alternateASig1;
21082fe8fb19SBen Gras     }
21092fe8fb19SBen Gras     zSign = ( (sbits32) aSig0 < 0 );
21102fe8fb19SBen Gras     if ( zSign ) sub64( 0, 0, aSig0, aSig1, &aSig0, &aSig1 );
21112fe8fb19SBen Gras     return
21122fe8fb19SBen Gras         normalizeRoundAndPackFloat64( aSign ^ zSign, bExp - 4, aSig0, aSig1 );
21132fe8fb19SBen Gras 
21142fe8fb19SBen Gras }
21152fe8fb19SBen Gras #endif
21162fe8fb19SBen Gras 
21172fe8fb19SBen Gras #ifndef SOFTFLOAT_FOR_GCC
21182fe8fb19SBen Gras /*
21192fe8fb19SBen Gras -------------------------------------------------------------------------------
21202fe8fb19SBen Gras Returns the square root of the double-precision floating-point value `a'.
21212fe8fb19SBen Gras The operation is performed according to the IEC/IEEE Standard for Binary
21222fe8fb19SBen Gras Floating-Point Arithmetic.
21232fe8fb19SBen Gras -------------------------------------------------------------------------------
21242fe8fb19SBen Gras */
float64_sqrt(float64 a)21252fe8fb19SBen Gras float64 float64_sqrt( float64 a )
21262fe8fb19SBen Gras {
21272fe8fb19SBen Gras     flag aSign;
21282fe8fb19SBen Gras     int16 aExp, zExp;
21292fe8fb19SBen Gras     bits32 aSig0, aSig1, zSig0, zSig1, zSig2, doubleZSig0;
21302fe8fb19SBen Gras     bits32 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
21312fe8fb19SBen Gras     float64 z;
21322fe8fb19SBen Gras 
21332fe8fb19SBen Gras     aSig1 = extractFloat64Frac1( a );
21342fe8fb19SBen Gras     aSig0 = extractFloat64Frac0( a );
21352fe8fb19SBen Gras     aExp = extractFloat64Exp( a );
21362fe8fb19SBen Gras     aSign = extractFloat64Sign( a );
21372fe8fb19SBen Gras     if ( aExp == 0x7FF ) {
21382fe8fb19SBen Gras         if ( aSig0 | aSig1 ) return propagateFloat64NaN( a, a );
21392fe8fb19SBen Gras         if ( ! aSign ) return a;
21402fe8fb19SBen Gras         goto invalid;
21412fe8fb19SBen Gras     }
21422fe8fb19SBen Gras     if ( aSign ) {
21432fe8fb19SBen Gras         if ( ( aExp | aSig0 | aSig1 ) == 0 ) return a;
21442fe8fb19SBen Gras  invalid:
21452fe8fb19SBen Gras         float_raise( float_flag_invalid );
21462fe8fb19SBen Gras         return float64_default_nan;
21472fe8fb19SBen Gras     }
21482fe8fb19SBen Gras     if ( aExp == 0 ) {
21492fe8fb19SBen Gras         if ( ( aSig0 | aSig1 ) == 0 ) return packFloat64( 0, 0, 0, 0 );
21502fe8fb19SBen Gras         normalizeFloat64Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
21512fe8fb19SBen Gras     }
21522fe8fb19SBen Gras     zExp = ( ( aExp - 0x3FF )>>1 ) + 0x3FE;
21532fe8fb19SBen Gras     aSig0 |= 0x00100000;
21542fe8fb19SBen Gras     shortShift64Left( aSig0, aSig1, 11, &term0, &term1 );
21552fe8fb19SBen Gras     zSig0 = ( estimateSqrt32( aExp, term0 )>>1 ) + 1;
21562fe8fb19SBen Gras     if ( zSig0 == 0 ) zSig0 = 0x7FFFFFFF;
21572fe8fb19SBen Gras     doubleZSig0 = zSig0 + zSig0;
21582fe8fb19SBen Gras     shortShift64Left( aSig0, aSig1, 9 - ( aExp & 1 ), &aSig0, &aSig1 );
21592fe8fb19SBen Gras     mul32To64( zSig0, zSig0, &term0, &term1 );
21602fe8fb19SBen Gras     sub64( aSig0, aSig1, term0, term1, &rem0, &rem1 );
21612fe8fb19SBen Gras     while ( (sbits32) rem0 < 0 ) {
21622fe8fb19SBen Gras         --zSig0;
21632fe8fb19SBen Gras         doubleZSig0 -= 2;
21642fe8fb19SBen Gras         add64( rem0, rem1, 0, doubleZSig0 | 1, &rem0, &rem1 );
21652fe8fb19SBen Gras     }
21662fe8fb19SBen Gras     zSig1 = estimateDiv64To32( rem1, 0, doubleZSig0 );
21672fe8fb19SBen Gras     if ( ( zSig1 & 0x1FF ) <= 5 ) {
21682fe8fb19SBen Gras         if ( zSig1 == 0 ) zSig1 = 1;
21692fe8fb19SBen Gras         mul32To64( doubleZSig0, zSig1, &term1, &term2 );
21702fe8fb19SBen Gras         sub64( rem1, 0, term1, term2, &rem1, &rem2 );
21712fe8fb19SBen Gras         mul32To64( zSig1, zSig1, &term2, &term3 );
21722fe8fb19SBen Gras         sub96( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 );
21732fe8fb19SBen Gras         while ( (sbits32) rem1 < 0 ) {
21742fe8fb19SBen Gras             --zSig1;
21752fe8fb19SBen Gras             shortShift64Left( 0, zSig1, 1, &term2, &term3 );
21762fe8fb19SBen Gras             term3 |= 1;
21772fe8fb19SBen Gras             term2 |= doubleZSig0;
21782fe8fb19SBen Gras             add96( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 );
21792fe8fb19SBen Gras         }
21802fe8fb19SBen Gras         zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
21812fe8fb19SBen Gras     }
21822fe8fb19SBen Gras     shift64ExtraRightJamming( zSig0, zSig1, 0, 10, &zSig0, &zSig1, &zSig2 );
21832fe8fb19SBen Gras     return roundAndPackFloat64( 0, zExp, zSig0, zSig1, zSig2 );
21842fe8fb19SBen Gras 
21852fe8fb19SBen Gras }
21862fe8fb19SBen Gras #endif
21872fe8fb19SBen Gras 
21882fe8fb19SBen Gras /*
21892fe8fb19SBen Gras -------------------------------------------------------------------------------
21902fe8fb19SBen Gras Returns 1 if the double-precision floating-point value `a' is equal to
21912fe8fb19SBen Gras the corresponding value `b', and 0 otherwise.  The comparison is performed
21922fe8fb19SBen Gras according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
21932fe8fb19SBen Gras -------------------------------------------------------------------------------
21942fe8fb19SBen Gras */
float64_eq(float64 a,float64 b)21952fe8fb19SBen Gras flag float64_eq( float64 a, float64 b )
21962fe8fb19SBen Gras {
21972fe8fb19SBen Gras 
21982fe8fb19SBen Gras     if (    (    ( extractFloat64Exp( a ) == 0x7FF )
21992fe8fb19SBen Gras               && ( extractFloat64Frac0( a ) | extractFloat64Frac1( a ) ) )
22002fe8fb19SBen Gras          || (    ( extractFloat64Exp( b ) == 0x7FF )
22012fe8fb19SBen Gras               && ( extractFloat64Frac0( b ) | extractFloat64Frac1( b ) ) )
22022fe8fb19SBen Gras        ) {
22032fe8fb19SBen Gras         if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
22042fe8fb19SBen Gras             float_raise( float_flag_invalid );
22052fe8fb19SBen Gras         }
22062fe8fb19SBen Gras         return 0;
22072fe8fb19SBen Gras     }
22082fe8fb19SBen Gras     return ( a == b ) ||
22092fe8fb19SBen Gras 	( (bits64) ( ( FLOAT64_DEMANGLE(a) | FLOAT64_DEMANGLE(b) )<<1 ) == 0 );
22102fe8fb19SBen Gras 
22112fe8fb19SBen Gras }
22122fe8fb19SBen Gras 
22132fe8fb19SBen Gras /*
22142fe8fb19SBen Gras -------------------------------------------------------------------------------
22152fe8fb19SBen Gras Returns 1 if the double-precision floating-point value `a' is less than
22162fe8fb19SBen Gras or equal to the corresponding value `b', and 0 otherwise.  The comparison
22172fe8fb19SBen Gras is performed according to the IEC/IEEE Standard for Binary Floating-Point
22182fe8fb19SBen Gras Arithmetic.
22192fe8fb19SBen Gras -------------------------------------------------------------------------------
22202fe8fb19SBen Gras */
float64_le(float64 a,float64 b)22212fe8fb19SBen Gras flag float64_le( float64 a, float64 b )
22222fe8fb19SBen Gras {
22232fe8fb19SBen Gras     flag aSign, bSign;
22242fe8fb19SBen Gras 
22252fe8fb19SBen Gras     if (    (    ( extractFloat64Exp( a ) == 0x7FF )
22262fe8fb19SBen Gras               && ( extractFloat64Frac0( a ) | extractFloat64Frac1( a ) ) )
22272fe8fb19SBen Gras          || (    ( extractFloat64Exp( b ) == 0x7FF )
22282fe8fb19SBen Gras               && ( extractFloat64Frac0( b ) | extractFloat64Frac1( b ) ) )
22292fe8fb19SBen Gras        ) {
22302fe8fb19SBen Gras         float_raise( float_flag_invalid );
22312fe8fb19SBen Gras         return 0;
22322fe8fb19SBen Gras     }
22332fe8fb19SBen Gras     aSign = extractFloat64Sign( a );
22342fe8fb19SBen Gras     bSign = extractFloat64Sign( b );
22352fe8fb19SBen Gras     if ( aSign != bSign )
22362fe8fb19SBen Gras 	return aSign ||
22372fe8fb19SBen Gras 	    ( (bits64) ( ( FLOAT64_DEMANGLE(a) | FLOAT64_DEMANGLE(b) )<<1 ) ==
22382fe8fb19SBen Gras 	      0 );
22392fe8fb19SBen Gras     return ( a == b ) ||
22402fe8fb19SBen Gras 	( aSign ^ ( FLOAT64_DEMANGLE(a) < FLOAT64_DEMANGLE(b) ) );
22412fe8fb19SBen Gras }
22422fe8fb19SBen Gras 
22432fe8fb19SBen Gras /*
22442fe8fb19SBen Gras -------------------------------------------------------------------------------
22452fe8fb19SBen Gras Returns 1 if the double-precision floating-point value `a' is less than
22462fe8fb19SBen Gras the corresponding value `b', and 0 otherwise.  The comparison is performed
22472fe8fb19SBen Gras according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
22482fe8fb19SBen Gras -------------------------------------------------------------------------------
22492fe8fb19SBen Gras */
float64_lt(float64 a,float64 b)22502fe8fb19SBen Gras flag float64_lt( float64 a, float64 b )
22512fe8fb19SBen Gras {
22522fe8fb19SBen Gras     flag aSign, bSign;
22532fe8fb19SBen Gras 
22542fe8fb19SBen Gras     if (    (    ( extractFloat64Exp( a ) == 0x7FF )
22552fe8fb19SBen Gras               && ( extractFloat64Frac0( a ) | extractFloat64Frac1( a ) ) )
22562fe8fb19SBen Gras          || (    ( extractFloat64Exp( b ) == 0x7FF )
22572fe8fb19SBen Gras               && ( extractFloat64Frac0( b ) | extractFloat64Frac1( b ) ) )
22582fe8fb19SBen Gras        ) {
22592fe8fb19SBen Gras         float_raise( float_flag_invalid );
22602fe8fb19SBen Gras         return 0;
22612fe8fb19SBen Gras     }
22622fe8fb19SBen Gras     aSign = extractFloat64Sign( a );
22632fe8fb19SBen Gras     bSign = extractFloat64Sign( b );
22642fe8fb19SBen Gras     if ( aSign != bSign )
22652fe8fb19SBen Gras 	return aSign &&
22662fe8fb19SBen Gras 	    ( (bits64) ( ( FLOAT64_DEMANGLE(a) | FLOAT64_DEMANGLE(b) )<<1 ) !=
22672fe8fb19SBen Gras 	      0 );
22682fe8fb19SBen Gras     return ( a != b ) &&
22692fe8fb19SBen Gras 	( aSign ^ ( FLOAT64_DEMANGLE(a) < FLOAT64_DEMANGLE(b) ) );
22702fe8fb19SBen Gras 
22712fe8fb19SBen Gras }
22722fe8fb19SBen Gras 
22732fe8fb19SBen Gras #ifndef SOFTFLOAT_FOR_GCC
22742fe8fb19SBen Gras /*
22752fe8fb19SBen Gras -------------------------------------------------------------------------------
22762fe8fb19SBen Gras Returns 1 if the double-precision floating-point value `a' is equal to
22772fe8fb19SBen Gras the corresponding value `b', and 0 otherwise.  The invalid exception is
22782fe8fb19SBen Gras raised if either operand is a NaN.  Otherwise, the comparison is performed
22792fe8fb19SBen Gras according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
22802fe8fb19SBen Gras -------------------------------------------------------------------------------
22812fe8fb19SBen Gras */
float64_eq_signaling(float64 a,float64 b)22822fe8fb19SBen Gras flag float64_eq_signaling( float64 a, float64 b )
22832fe8fb19SBen Gras {
22842fe8fb19SBen Gras 
22852fe8fb19SBen Gras     if (    (    ( extractFloat64Exp( a ) == 0x7FF )
22862fe8fb19SBen Gras               && ( extractFloat64Frac0( a ) | extractFloat64Frac1( a ) ) )
22872fe8fb19SBen Gras          || (    ( extractFloat64Exp( b ) == 0x7FF )
22882fe8fb19SBen Gras               && ( extractFloat64Frac0( b ) | extractFloat64Frac1( b ) ) )
22892fe8fb19SBen Gras        ) {
22902fe8fb19SBen Gras         float_raise( float_flag_invalid );
22912fe8fb19SBen Gras         return 0;
22922fe8fb19SBen Gras     }
22932fe8fb19SBen Gras     return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 );
22942fe8fb19SBen Gras 
22952fe8fb19SBen Gras }
22962fe8fb19SBen Gras 
22972fe8fb19SBen Gras /*
22982fe8fb19SBen Gras -------------------------------------------------------------------------------
22992fe8fb19SBen Gras Returns 1 if the double-precision floating-point value `a' is less than or
23002fe8fb19SBen Gras equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs do not
23012fe8fb19SBen Gras cause an exception.  Otherwise, the comparison is performed according to the
23022fe8fb19SBen Gras IEC/IEEE Standard for Binary Floating-Point Arithmetic.
23032fe8fb19SBen Gras -------------------------------------------------------------------------------
23042fe8fb19SBen Gras */
float64_le_quiet(float64 a,float64 b)23052fe8fb19SBen Gras flag float64_le_quiet( float64 a, float64 b )
23062fe8fb19SBen Gras {
23072fe8fb19SBen Gras     flag aSign, bSign;
23082fe8fb19SBen Gras 
23092fe8fb19SBen Gras     if (    (    ( extractFloat64Exp( a ) == 0x7FF )
23102fe8fb19SBen Gras               && ( extractFloat64Frac0( a ) | extractFloat64Frac1( a ) ) )
23112fe8fb19SBen Gras          || (    ( extractFloat64Exp( b ) == 0x7FF )
23122fe8fb19SBen Gras               && ( extractFloat64Frac0( b ) | extractFloat64Frac1( b ) ) )
23132fe8fb19SBen Gras        ) {
23142fe8fb19SBen Gras         if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
23152fe8fb19SBen Gras             float_raise( float_flag_invalid );
23162fe8fb19SBen Gras         }
23172fe8fb19SBen Gras         return 0;
23182fe8fb19SBen Gras     }
23192fe8fb19SBen Gras     aSign = extractFloat64Sign( a );
23202fe8fb19SBen Gras     bSign = extractFloat64Sign( b );
23212fe8fb19SBen Gras     if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 );
23222fe8fb19SBen Gras     return ( a == b ) || ( aSign ^ ( a < b ) );
23232fe8fb19SBen Gras 
23242fe8fb19SBen Gras }
23252fe8fb19SBen Gras 
23262fe8fb19SBen Gras /*
23272fe8fb19SBen Gras -------------------------------------------------------------------------------
23282fe8fb19SBen Gras Returns 1 if the double-precision floating-point value `a' is less than
23292fe8fb19SBen Gras the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
23302fe8fb19SBen Gras exception.  Otherwise, the comparison is performed according to the IEC/IEEE
23312fe8fb19SBen Gras Standard for Binary Floating-Point Arithmetic.
23322fe8fb19SBen Gras -------------------------------------------------------------------------------
23332fe8fb19SBen Gras */
float64_lt_quiet(float64 a,float64 b)23342fe8fb19SBen Gras flag float64_lt_quiet( float64 a, float64 b )
23352fe8fb19SBen Gras {
23362fe8fb19SBen Gras     flag aSign, bSign;
23372fe8fb19SBen Gras 
23382fe8fb19SBen Gras     if (    (    ( extractFloat64Exp( a ) == 0x7FF )
23392fe8fb19SBen Gras               && ( extractFloat64Frac0( a ) | extractFloat64Frac1( a ) ) )
23402fe8fb19SBen Gras          || (    ( extractFloat64Exp( b ) == 0x7FF )
23412fe8fb19SBen Gras               && ( extractFloat64Frac0( b ) | extractFloat64Frac1( b ) ) )
23422fe8fb19SBen Gras        ) {
23432fe8fb19SBen Gras         if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
23442fe8fb19SBen Gras             float_raise( float_flag_invalid );
23452fe8fb19SBen Gras         }
23462fe8fb19SBen Gras         return 0;
23472fe8fb19SBen Gras     }
23482fe8fb19SBen Gras     aSign = extractFloat64Sign( a );
23492fe8fb19SBen Gras     bSign = extractFloat64Sign( b );
23502fe8fb19SBen Gras     if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 );
23512fe8fb19SBen Gras     return ( a != b ) && ( aSign ^ ( a < b ) );
23522fe8fb19SBen Gras 
23532fe8fb19SBen Gras }
23542fe8fb19SBen Gras 
23552fe8fb19SBen Gras #endif
2356