Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) ===============================================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4) This C source file is part of the SoftFloat IEC/IEEE Floating-point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5) Arithmetic Package, Release 2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7) Written by John R. Hauser.  This work was made possible in part by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) International Computer Science Institute, located at Suite 600, 1947 Center
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) Street, Berkeley, California 94704.  Funding was partially provided by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) National Science Foundation under grant MIP-9311980.  The original version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) of this code was written as part of a project to build a fixed-point vector
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) processor in collaboration with the University of California at Berkeley,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) is available through the web page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) http://www.jhauser.us/arithmetic/SoftFloat-2b/SoftFloat-source.txt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) Derivative works are acceptable, even for commercial purposes, so long as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) (1) they include prominent notice that the work is derivative, and (2) they
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) include prominent notice akin to these three paragraphs for those parts of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) this code that are retained.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) ===============================================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include <asm/div64.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #include "fpa11.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) //#include "milieu.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) //#include "softfloat.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) Primitive arithmetic functions, including multi-word arithmetic, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) division and square root approximations.  (Can be specialized to target if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) desired.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) #include "softfloat-macros"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) Functions and definitions to determine:  (1) whether tininess for underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) is detected before or after rounding by default, (2) what (if anything)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) happens when exceptions are raised, (3) how signaling NaNs are distinguished
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) are propagated from function inputs to output.  These details are target-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) specific.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) #include "softfloat-specialize"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) Takes a 64-bit fixed-point value `absZ' with binary point between bits 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) and 7, and returns the properly rounded 32-bit integer corresponding to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) input.  If `zSign' is nonzero, the input is negated before being converted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) to an integer.  Bit 63 of `absZ' must be zero.  Ordinarily, the fixed-point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) input is simply rounded to an integer, with the inexact exception raised if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) the input cannot be represented exactly as an integer.  If the fixed-point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) input is too large, however, the invalid exception is raised and the largest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) positive or negative integer is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) static int32 roundAndPackInt32( struct roundingData *roundData, flag zSign, bits64 absZ )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72)     int8 roundingMode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73)     flag roundNearestEven;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74)     int8 roundIncrement, roundBits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75)     int32 z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77)     roundingMode = roundData->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78)     roundNearestEven = ( roundingMode == float_round_nearest_even );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79)     roundIncrement = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80)     if ( ! roundNearestEven ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81)         if ( roundingMode == float_round_to_zero ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82)             roundIncrement = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84)         else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85)             roundIncrement = 0x7F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86)             if ( zSign ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87)                 if ( roundingMode == float_round_up ) roundIncrement = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88)             }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89)             else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90)                 if ( roundingMode == float_round_down ) roundIncrement = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91)             }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94)     roundBits = absZ & 0x7F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95)     absZ = ( absZ + roundIncrement )>>7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96)     absZ &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97)     z = absZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98)     if ( zSign ) z = - z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99)     if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100)         roundData->exception |= float_flag_invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101)         return zSign ? 0x80000000 : 0x7FFFFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103)     if ( roundBits ) roundData->exception |= float_flag_inexact;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104)     return z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) Returns the fraction bits of the single-precision floating-point value `a'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) INLINE bits32 extractFloat32Frac( float32 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116)     return a & 0x007FFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) Returns the exponent bits of the single-precision floating-point value `a'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) INLINE int16 extractFloat32Exp( float32 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128)     return ( a>>23 ) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) Returns the sign bit of the single-precision floating-point value `a'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) #if 0	/* in softfloat.h */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) INLINE flag extractFloat32Sign( float32 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141)     return a>>31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) Normalizes the subnormal single-precision floating-point value represented
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) by the denormalized significand `aSig'.  The normalized exponent and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) significand are stored at the locations pointed to by `zExpPtr' and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) `zSigPtr', respectively.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155)  normalizeFloat32Subnormal( bits32 aSig, int16 *zExpPtr, bits32 *zSigPtr )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157)     int8 shiftCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159)     shiftCount = countLeadingZeros32( aSig ) - 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160)     *zSigPtr = aSig<<shiftCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161)     *zExpPtr = 1 - shiftCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) single-precision floating-point value, returning the result.  After being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) shifted into the proper positions, the three fields are simply added
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) together to form the result.  This means that any integer portion of `zSig'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) will be added into the exponent.  Since a properly normalized significand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) will have an integer portion equal to 1, the `zExp' input should be 1 less
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) than the desired result exponent whenever `zSig' is a complete, normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) significand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) INLINE float32 packFloat32( flag zSign, int16 zExp, bits32 zSig )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180)    float32 f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181)    __asm__("@ packFloat32				\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182)    	    mov %0, %1, asl #31				\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183)    	    orr %0, %2, asl #23				\n\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184)    	    orr %0, %3"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185)    	    : /* no outputs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186)    	    : "g" (f), "g" (zSign), "g" (zExp), "g" (zSig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187)    	    : "cc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188)    return f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190)     return ( ( (bits32) zSign )<<31 ) + ( ( (bits32) zExp )<<23 ) + zSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) #endif 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) Takes an abstract floating-point value having sign `zSign', exponent `zExp',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) and significand `zSig', and returns the proper single-precision floating-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) point value corresponding to the abstract input.  Ordinarily, the abstract
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) value is simply rounded and packed into the single-precision format, with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) the inexact exception raised if the abstract input cannot be represented
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) exactly.  If the abstract value is too large, however, the overflow and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) inexact exceptions are raised and an infinity or maximal finite value is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) returned.  If the abstract value is too small, the input value is rounded to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) a subnormal number, and the underflow and inexact exceptions are raised if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) the abstract input cannot be represented exactly as a subnormal single-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) precision floating-point number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207)     The input significand `zSig' has its binary point between bits 30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) and 29, which is 7 bits to the left of the usual location.  This shifted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) significand must be normalized or smaller.  If `zSig' is not normalized,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) `zExp' must be 0; in that case, the result returned is a subnormal number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) and it must not require rounding.  In the usual case that `zSig' is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) The handling of underflow and overflow follows the IEC/IEEE Standard for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) static float32 roundAndPackFloat32( struct roundingData *roundData, flag zSign, int16 zExp, bits32 zSig )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219)     int8 roundingMode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220)     flag roundNearestEven;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221)     int8 roundIncrement, roundBits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222)     flag isTiny;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224)     roundingMode = roundData->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225)     roundNearestEven = ( roundingMode == float_round_nearest_even );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226)     roundIncrement = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227)     if ( ! roundNearestEven ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228)         if ( roundingMode == float_round_to_zero ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229)             roundIncrement = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231)         else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232)             roundIncrement = 0x7F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233)             if ( zSign ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234)                 if ( roundingMode == float_round_up ) roundIncrement = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235)             }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236)             else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237)                 if ( roundingMode == float_round_down ) roundIncrement = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238)             }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241)     roundBits = zSig & 0x7F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242)     if ( 0xFD <= (bits16) zExp ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243)         if (    ( 0xFD < zExp )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244)              || (    ( zExp == 0xFD )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245)                   && ( (sbits32) ( zSig + roundIncrement ) < 0 ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246)            ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247)             roundData->exception |= float_flag_overflow | float_flag_inexact;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248)             return packFloat32( zSign, 0xFF, 0 ) - ( roundIncrement == 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250)         if ( zExp < 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251)             isTiny =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252)                    ( float_detect_tininess == float_tininess_before_rounding )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253)                 || ( zExp < -1 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254)                 || ( zSig + roundIncrement < 0x80000000 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255)             shift32RightJamming( zSig, - zExp, &zSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256)             zExp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257)             roundBits = zSig & 0x7F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258)             if ( isTiny && roundBits ) roundData->exception |= float_flag_underflow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261)     if ( roundBits ) roundData->exception |= float_flag_inexact;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262)     zSig = ( zSig + roundIncrement )>>7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263)     zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264)     if ( zSig == 0 ) zExp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265)     return packFloat32( zSign, zExp, zSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) Takes an abstract floating-point value having sign `zSign', exponent `zExp',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) and significand `zSig', and returns the proper single-precision floating-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) point value corresponding to the abstract input.  This routine is just like
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) `roundAndPackFloat32' except that `zSig' does not have to be normalized in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) any way.  In all cases, `zExp' must be 1 less than the ``true'' floating-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) point exponent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) static float32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280)  normalizeRoundAndPackFloat32( struct roundingData *roundData, flag zSign, int16 zExp, bits32 zSig )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282)     int8 shiftCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284)     shiftCount = countLeadingZeros32( zSig ) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285)     return roundAndPackFloat32( roundData, zSign, zExp - shiftCount, zSig<<shiftCount );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) Returns the fraction bits of the double-precision floating-point value `a'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) INLINE bits64 extractFloat64Frac( float64 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297)     return a & LIT64( 0x000FFFFFFFFFFFFF );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) Returns the exponent bits of the double-precision floating-point value `a'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) INLINE int16 extractFloat64Exp( float64 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309)     return ( a>>52 ) & 0x7FF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) Returns the sign bit of the double-precision floating-point value `a'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) #if 0	/* in softfloat.h */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) INLINE flag extractFloat64Sign( float64 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322)     return a>>63;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) Normalizes the subnormal double-precision floating-point value represented
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) by the denormalized significand `aSig'.  The normalized exponent and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) significand are stored at the locations pointed to by `zExpPtr' and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) `zSigPtr', respectively.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336)  normalizeFloat64Subnormal( bits64 aSig, int16 *zExpPtr, bits64 *zSigPtr )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338)     int8 shiftCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340)     shiftCount = countLeadingZeros64( aSig ) - 11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341)     *zSigPtr = aSig<<shiftCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342)     *zExpPtr = 1 - shiftCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) double-precision floating-point value, returning the result.  After being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) shifted into the proper positions, the three fields are simply added
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) together to form the result.  This means that any integer portion of `zSig'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) will be added into the exponent.  Since a properly normalized significand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) will have an integer portion equal to 1, the `zExp' input should be 1 less
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) than the desired result exponent whenever `zSig' is a complete, normalized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) significand.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) INLINE float64 packFloat64( flag zSign, int16 zExp, bits64 zSig )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361)     return ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<52 ) + zSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) Takes an abstract floating-point value having sign `zSign', exponent `zExp',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) and significand `zSig', and returns the proper double-precision floating-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) point value corresponding to the abstract input.  Ordinarily, the abstract
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) value is simply rounded and packed into the double-precision format, with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) the inexact exception raised if the abstract input cannot be represented
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) exactly.  If the abstract value is too large, however, the overflow and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) inexact exceptions are raised and an infinity or maximal finite value is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) returned.  If the abstract value is too small, the input value is rounded to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) a subnormal number, and the underflow and inexact exceptions are raised if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) the abstract input cannot be represented exactly as a subnormal double-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) precision floating-point number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378)     The input significand `zSig' has its binary point between bits 62
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) and 61, which is 10 bits to the left of the usual location.  This shifted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) significand must be normalized or smaller.  If `zSig' is not normalized,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) `zExp' must be 0; in that case, the result returned is a subnormal number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) and it must not require rounding.  In the usual case that `zSig' is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) The handling of underflow and overflow follows the IEC/IEEE Standard for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) static float64 roundAndPackFloat64( struct roundingData *roundData, flag zSign, int16 zExp, bits64 zSig )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390)     int8 roundingMode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391)     flag roundNearestEven;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392)     int16 roundIncrement, roundBits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393)     flag isTiny;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395)     roundingMode = roundData->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396)     roundNearestEven = ( roundingMode == float_round_nearest_even );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397)     roundIncrement = 0x200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398)     if ( ! roundNearestEven ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399)         if ( roundingMode == float_round_to_zero ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400)             roundIncrement = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402)         else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403)             roundIncrement = 0x3FF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404)             if ( zSign ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405)                 if ( roundingMode == float_round_up ) roundIncrement = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406)             }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407)             else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408)                 if ( roundingMode == float_round_down ) roundIncrement = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409)             }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412)     roundBits = zSig & 0x3FF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413)     if ( 0x7FD <= (bits16) zExp ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414)         if (    ( 0x7FD < zExp )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415)              || (    ( zExp == 0x7FD )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416)                   && ( (sbits64) ( zSig + roundIncrement ) < 0 ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417)            ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418)             //register int lr = __builtin_return_address(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419)             //printk("roundAndPackFloat64 called from 0x%08x\n",lr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420)             roundData->exception |= float_flag_overflow | float_flag_inexact;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421)             return packFloat64( zSign, 0x7FF, 0 ) - ( roundIncrement == 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423)         if ( zExp < 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424)             isTiny =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425)                    ( float_detect_tininess == float_tininess_before_rounding )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426)                 || ( zExp < -1 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427)                 || ( zSig + roundIncrement < LIT64( 0x8000000000000000 ) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428)             shift64RightJamming( zSig, - zExp, &zSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429)             zExp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430)             roundBits = zSig & 0x3FF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431)             if ( isTiny && roundBits ) roundData->exception |= float_flag_underflow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434)     if ( roundBits ) roundData->exception |= float_flag_inexact;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435)     zSig = ( zSig + roundIncrement )>>10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436)     zSig &= ~ ( ( ( roundBits ^ 0x200 ) == 0 ) & roundNearestEven );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437)     if ( zSig == 0 ) zExp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438)     return packFloat64( zSign, zExp, zSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) Takes an abstract floating-point value having sign `zSign', exponent `zExp',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) and significand `zSig', and returns the proper double-precision floating-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) point value corresponding to the abstract input.  This routine is just like
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) `roundAndPackFloat64' except that `zSig' does not have to be normalized in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) any way.  In all cases, `zExp' must be 1 less than the ``true'' floating-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) point exponent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) static float64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453)  normalizeRoundAndPackFloat64( struct roundingData *roundData, flag zSign, int16 zExp, bits64 zSig )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455)     int8 shiftCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457)     shiftCount = countLeadingZeros64( zSig ) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458)     return roundAndPackFloat64( roundData, zSign, zExp - shiftCount, zSig<<shiftCount );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) #ifdef FLOATX80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) Returns the fraction bits of the extended double-precision floating-point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) value `a'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) INLINE bits64 extractFloatx80Frac( floatx80 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473)     return a.low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) Returns the exponent bits of the extended double-precision floating-point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) value `a'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) INLINE int32 extractFloatx80Exp( floatx80 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486)     return a.high & 0x7FFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) Returns the sign bit of the extended double-precision floating-point value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) `a'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) INLINE flag extractFloatx80Sign( floatx80 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499)     return a.high>>15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) Normalizes the subnormal extended double-precision floating-point value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) represented by the denormalized significand `aSig'.  The normalized exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) and significand are stored at the locations pointed to by `zExpPtr' and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) `zSigPtr', respectively.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512)  normalizeFloatx80Subnormal( bits64 aSig, int32 *zExpPtr, bits64 *zSigPtr )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514)     int8 shiftCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516)     shiftCount = countLeadingZeros64( aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517)     *zSigPtr = aSig<<shiftCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518)     *zExpPtr = 1 - shiftCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) Packs the sign `zSign', exponent `zExp', and significand `zSig' into an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) extended double-precision floating-point value, returning the result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) INLINE floatx80 packFloatx80( flag zSign, int32 zExp, bits64 zSig )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530)     floatx80 z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532)     z.low = zSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533)     z.high = ( ( (bits16) zSign )<<15 ) + zExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534)     z.__padding = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535)     return z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) Takes an abstract floating-point value having sign `zSign', exponent `zExp',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) and extended significand formed by the concatenation of `zSig0' and `zSig1',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) and returns the proper extended double-precision floating-point value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) corresponding to the abstract input.  Ordinarily, the abstract value is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) rounded and packed into the extended double-precision format, with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) inexact exception raised if the abstract input cannot be represented
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) exactly.  If the abstract value is too large, however, the overflow and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) inexact exceptions are raised and an infinity or maximal finite value is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) returned.  If the abstract value is too small, the input value is rounded to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) a subnormal number, and the underflow and inexact exceptions are raised if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) the abstract input cannot be represented exactly as a subnormal extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) double-precision floating-point number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553)     If `roundingPrecision' is 32 or 64, the result is rounded to the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) number of bits as single or double precision, respectively.  Otherwise, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) result is rounded to the full precision of the extended double-precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557)     The input significand must be normalized or smaller.  If the input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) significand is not normalized, `zExp' must be 0; in that case, the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) returned is a subnormal number, and it must not require rounding.  The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) handling of underflow and overflow follows the IEC/IEEE Standard for Binary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) static floatx80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565)  roundAndPackFloatx80(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566)      struct roundingData *roundData, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567)  )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569)     int8 roundingMode, roundingPrecision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570)     flag roundNearestEven, increment, isTiny;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571)     int64 roundIncrement, roundMask, roundBits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573)     roundingMode = roundData->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574)     roundingPrecision = roundData->precision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575)     roundNearestEven = ( roundingMode == float_round_nearest_even );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576)     if ( roundingPrecision == 80 ) goto precision80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577)     if ( roundingPrecision == 64 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578)         roundIncrement = LIT64( 0x0000000000000400 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579)         roundMask = LIT64( 0x00000000000007FF );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581)     else if ( roundingPrecision == 32 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582)         roundIncrement = LIT64( 0x0000008000000000 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583)         roundMask = LIT64( 0x000000FFFFFFFFFF );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585)     else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586)         goto precision80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588)     zSig0 |= ( zSig1 != 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589)     if ( ! roundNearestEven ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590)         if ( roundingMode == float_round_to_zero ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591)             roundIncrement = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593)         else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594)             roundIncrement = roundMask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595)             if ( zSign ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596)                 if ( roundingMode == float_round_up ) roundIncrement = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597)             }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598)             else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599)                 if ( roundingMode == float_round_down ) roundIncrement = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600)             }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603)     roundBits = zSig0 & roundMask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604)     if ( 0x7FFD <= (bits32) ( zExp - 1 ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605)         if (    ( 0x7FFE < zExp )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606)              || ( ( zExp == 0x7FFE ) && ( zSig0 + roundIncrement < zSig0 ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607)            ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608)             goto overflow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610)         if ( zExp <= 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611)             isTiny =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612)                    ( float_detect_tininess == float_tininess_before_rounding )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613)                 || ( zExp < 0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614)                 || ( zSig0 <= zSig0 + roundIncrement );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615)             shift64RightJamming( zSig0, 1 - zExp, &zSig0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616)             zExp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617)             roundBits = zSig0 & roundMask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618)             if ( isTiny && roundBits ) roundData->exception |= float_flag_underflow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619)             if ( roundBits ) roundData->exception |= float_flag_inexact;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620)             zSig0 += roundIncrement;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621)             if ( (sbits64) zSig0 < 0 ) zExp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622)             roundIncrement = roundMask + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623)             if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624)                 roundMask |= roundIncrement;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625)             }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626)             zSig0 &= ~ roundMask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627)             return packFloatx80( zSign, zExp, zSig0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630)     if ( roundBits ) roundData->exception |= float_flag_inexact;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631)     zSig0 += roundIncrement;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632)     if ( zSig0 < roundIncrement ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633)         ++zExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634)         zSig0 = LIT64( 0x8000000000000000 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636)     roundIncrement = roundMask + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637)     if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638)         roundMask |= roundIncrement;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640)     zSig0 &= ~ roundMask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641)     if ( zSig0 == 0 ) zExp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642)     return packFloatx80( zSign, zExp, zSig0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643)  precision80:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644)     increment = ( (sbits64) zSig1 < 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645)     if ( ! roundNearestEven ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646)         if ( roundingMode == float_round_to_zero ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647)             increment = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649)         else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650)             if ( zSign ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651)                 increment = ( roundingMode == float_round_down ) && zSig1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652)             }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653)             else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654)                 increment = ( roundingMode == float_round_up ) && zSig1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655)             }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658)     if ( 0x7FFD <= (bits32) ( zExp - 1 ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659)         if (    ( 0x7FFE < zExp )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660)              || (    ( zExp == 0x7FFE )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661)                   && ( zSig0 == LIT64( 0xFFFFFFFFFFFFFFFF ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662)                   && increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663)                 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664)            ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665)             roundMask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666)  overflow:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667)             roundData->exception |= float_flag_overflow | float_flag_inexact;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668)             if (    ( roundingMode == float_round_to_zero )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669)                  || ( zSign && ( roundingMode == float_round_up ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670)                  || ( ! zSign && ( roundingMode == float_round_down ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671)                ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672)                 return packFloatx80( zSign, 0x7FFE, ~ roundMask );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673)             }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674)             return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676)         if ( zExp <= 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677)             isTiny =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678)                    ( float_detect_tininess == float_tininess_before_rounding )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679)                 || ( zExp < 0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680)                 || ! increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681)                 || ( zSig0 < LIT64( 0xFFFFFFFFFFFFFFFF ) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682)             shift64ExtraRightJamming( zSig0, zSig1, 1 - zExp, &zSig0, &zSig1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683)             zExp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684)             if ( isTiny && zSig1 ) roundData->exception |= float_flag_underflow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685)             if ( zSig1 ) roundData->exception |= float_flag_inexact;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686)             if ( roundNearestEven ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687)                 increment = ( (sbits64) zSig1 < 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688)             }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689)             else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690)                 if ( zSign ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691)                     increment = ( roundingMode == float_round_down ) && zSig1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692)                 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693)                 else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694)                     increment = ( roundingMode == float_round_up ) && zSig1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695)                 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696)             }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697)             if ( increment ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698)                 ++zSig0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699)                 zSig0 &= ~ ( ( zSig1 + zSig1 == 0 ) & roundNearestEven );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700)                 if ( (sbits64) zSig0 < 0 ) zExp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701)             }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702)             return packFloatx80( zSign, zExp, zSig0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705)     if ( zSig1 ) roundData->exception |= float_flag_inexact;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706)     if ( increment ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707)         ++zSig0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708)         if ( zSig0 == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709)             ++zExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710)             zSig0 = LIT64( 0x8000000000000000 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712)         else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713)             zSig0 &= ~ ( ( zSig1 + zSig1 == 0 ) & roundNearestEven );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716)     else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717)         if ( zSig0 == 0 ) zExp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720)     return packFloatx80( zSign, zExp, zSig0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) Takes an abstract floating-point value having sign `zSign', exponent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) `zExp', and significand formed by the concatenation of `zSig0' and `zSig1',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) and returns the proper extended double-precision floating-point value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) corresponding to the abstract input.  This routine is just like
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) `roundAndPackFloatx80' except that the input significand does not have to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) normalized.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) static floatx80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734)  normalizeRoundAndPackFloatx80(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735)      struct roundingData *roundData, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736)  )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738)     int8 shiftCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740)     if ( zSig0 == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741)         zSig0 = zSig1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742)         zSig1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743)         zExp -= 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745)     shiftCount = countLeadingZeros64( zSig0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746)     shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747)     zExp -= shiftCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748)     return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749)         roundAndPackFloatx80( roundData, zSign, zExp, zSig0, zSig1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) Returns the result of converting the 32-bit two's complement integer `a' to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) the single-precision floating-point format.  The conversion is performed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) float32 int32_to_float32(struct roundingData *roundData, int32 a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764)     flag zSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766)     if ( a == 0 ) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767)     if ( a == 0x80000000 ) return packFloat32( 1, 0x9E, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768)     zSign = ( a < 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769)     return normalizeRoundAndPackFloat32( roundData, zSign, 0x9C, zSign ? - a : a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) Returns the result of converting the 32-bit two's complement integer `a' to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) the double-precision floating-point format.  The conversion is performed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) float64 int32_to_float64( int32 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782)     flag aSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783)     uint32 absA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784)     int8 shiftCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785)     bits64 zSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787)     if ( a == 0 ) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788)     aSign = ( a < 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789)     absA = aSign ? - a : a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790)     shiftCount = countLeadingZeros32( absA ) + 21;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791)     zSig = absA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792)     return packFloat64( aSign, 0x432 - shiftCount, zSig<<shiftCount );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) #ifdef FLOATX80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) Returns the result of converting the 32-bit two's complement integer `a'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) to the extended double-precision floating-point format.  The conversion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) is performed according to the IEC/IEEE Standard for Binary Floating-point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) floatx80 int32_to_floatx80( int32 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808)     flag zSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809)     uint32 absA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810)     int8 shiftCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811)     bits64 zSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813)     if ( a == 0 ) return packFloatx80( 0, 0, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814)     zSign = ( a < 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815)     absA = zSign ? - a : a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816)     shiftCount = countLeadingZeros32( absA ) + 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817)     zSig = absA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818)     return packFloatx80( zSign, 0x403E - shiftCount, zSig<<shiftCount );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) Returns the result of converting the single-precision floating-point value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) `a' to the 32-bit two's complement integer format.  The conversion is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) performed according to the IEC/IEEE Standard for Binary Floating-point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) Arithmetic---which means in particular that the conversion is rounded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) according to the current rounding mode.  If `a' is a NaN, the largest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) positive integer is returned.  Otherwise, if the conversion overflows, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) largest integer with the same sign as `a' is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) int32 float32_to_int32( struct roundingData *roundData, float32 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837)     flag aSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838)     int16 aExp, shiftCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839)     bits32 aSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840)     bits64 zSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842)     aSig = extractFloat32Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843)     aExp = extractFloat32Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844)     aSign = extractFloat32Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845)     if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846)     if ( aExp ) aSig |= 0x00800000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847)     shiftCount = 0xAF - aExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848)     zSig = aSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849)     zSig <<= 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850)     if ( 0 < shiftCount ) shift64RightJamming( zSig, shiftCount, &zSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851)     return roundAndPackInt32( roundData, aSign, zSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) Returns the result of converting the single-precision floating-point value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) `a' to the 32-bit two's complement integer format.  The conversion is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) performed according to the IEC/IEEE Standard for Binary Floating-point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) Arithmetic, except that the conversion is always rounded toward zero.  If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) `a' is a NaN, the largest positive integer is returned.  Otherwise, if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) conversion overflows, the largest integer with the same sign as `a' is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) int32 float32_to_int32_round_to_zero( float32 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868)     flag aSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869)     int16 aExp, shiftCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870)     bits32 aSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871)     int32 z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873)     aSig = extractFloat32Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874)     aExp = extractFloat32Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875)     aSign = extractFloat32Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876)     shiftCount = aExp - 0x9E;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877)     if ( 0 <= shiftCount ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878)         if ( a == 0xCF000000 ) return 0x80000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879)         float_raise( float_flag_invalid );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880)         if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) return 0x7FFFFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881)         return 0x80000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883)     else if ( aExp <= 0x7E ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884)         if ( aExp | aSig ) float_raise( float_flag_inexact );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885)         return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887)     aSig = ( aSig | 0x00800000 )<<8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888)     z = aSig>>( - shiftCount );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889)     if ( (bits32) ( aSig<<( shiftCount & 31 ) ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890)         float_raise( float_flag_inexact );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892)     return aSign ? - z : z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) Returns the result of converting the single-precision floating-point value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) `a' to the double-precision floating-point format.  The conversion is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) performed according to the IEC/IEEE Standard for Binary Floating-point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) float64 float32_to_float64( float32 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906)     flag aSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907)     int16 aExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908)     bits32 aSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910)     aSig = extractFloat32Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911)     aExp = extractFloat32Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912)     aSign = extractFloat32Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913)     if ( aExp == 0xFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914)         if ( aSig ) return commonNaNToFloat64( float32ToCommonNaN( a ) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915)         return packFloat64( aSign, 0x7FF, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917)     if ( aExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918)         if ( aSig == 0 ) return packFloat64( aSign, 0, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919)         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920)         --aExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922)     return packFloat64( aSign, aExp + 0x380, ( (bits64) aSig )<<29 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) #ifdef FLOATX80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) Returns the result of converting the single-precision floating-point value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) `a' to the extended double-precision floating-point format.  The conversion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) is performed according to the IEC/IEEE Standard for Binary Floating-point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) floatx80 float32_to_floatx80( float32 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938)     flag aSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939)     int16 aExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940)     bits32 aSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942)     aSig = extractFloat32Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943)     aExp = extractFloat32Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944)     aSign = extractFloat32Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945)     if ( aExp == 0xFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946)         if ( aSig ) return commonNaNToFloatx80( float32ToCommonNaN( a ) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947)         return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949)     if ( aExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950)         if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951)         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953)     aSig |= 0x00800000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954)     return packFloatx80( aSign, aExp + 0x3F80, ( (bits64) aSig )<<40 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) Rounds the single-precision floating-point value `a' to an integer, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) returns the result as a single-precision floating-point value.  The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) operation is performed according to the IEC/IEEE Standard for Binary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) float32 float32_round_to_int( struct roundingData *roundData, float32 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970)     flag aSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971)     int16 aExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972)     bits32 lastBitMask, roundBitsMask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973)     int8 roundingMode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974)     float32 z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976)     aExp = extractFloat32Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977)     if ( 0x96 <= aExp ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978)         if ( ( aExp == 0xFF ) && extractFloat32Frac( a ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979)             return propagateFloat32NaN( a, a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981)         return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983)     roundingMode = roundData->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984)     if ( aExp <= 0x7E ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985)         if ( (bits32) ( a<<1 ) == 0 ) return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986)         roundData->exception |= float_flag_inexact;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987)         aSign = extractFloat32Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988)         switch ( roundingMode ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989)          case float_round_nearest_even:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990)             if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991)                 return packFloat32( aSign, 0x7F, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992)             }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993)             break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994)          case float_round_down:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995)             return aSign ? 0xBF800000 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996)          case float_round_up:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997)             return aSign ? 0x80000000 : 0x3F800000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999)         return packFloat32( aSign, 0, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)     lastBitMask = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)     lastBitMask <<= 0x96 - aExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)     roundBitsMask = lastBitMask - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)     z = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)     if ( roundingMode == float_round_nearest_even ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)         z += lastBitMask>>1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)         if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)     else if ( roundingMode != float_round_to_zero ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)         if ( extractFloat32Sign( z ) ^ ( roundingMode == float_round_up ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)             z += roundBitsMask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)     z &= ~ roundBitsMask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)     if ( z != a ) roundData->exception |= float_flag_inexact;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)     return z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) Returns the result of adding the absolute values of the single-precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) floating-point values `a' and `b'.  If `zSign' is true, the sum is negated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) before being returned.  `zSign' is ignored if the result is a NaN.  The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) addition is performed according to the IEC/IEEE Standard for Binary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) static float32 addFloat32Sigs( struct roundingData *roundData, float32 a, float32 b, flag zSign )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)     int16 aExp, bExp, zExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)     bits32 aSig, bSig, zSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)     int16 expDiff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)     aSig = extractFloat32Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)     aExp = extractFloat32Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)     bSig = extractFloat32Frac( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)     bExp = extractFloat32Exp( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)     expDiff = aExp - bExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)     aSig <<= 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)     bSig <<= 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)     if ( 0 < expDiff ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)         if ( aExp == 0xFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)             if ( aSig ) return propagateFloat32NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)             return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)         if ( bExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)             --expDiff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)         else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)             bSig |= 0x20000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)         shift32RightJamming( bSig, expDiff, &bSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)         zExp = aExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)     else if ( expDiff < 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)         if ( bExp == 0xFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)             if ( bSig ) return propagateFloat32NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)             return packFloat32( zSign, 0xFF, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)         if ( aExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)             ++expDiff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)         else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)             aSig |= 0x20000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)         shift32RightJamming( aSig, - expDiff, &aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)         zExp = bExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)     else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)         if ( aExp == 0xFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)             if ( aSig | bSig ) return propagateFloat32NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)             return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)         if ( aExp == 0 ) return packFloat32( zSign, 0, ( aSig + bSig )>>6 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)         zSig = 0x40000000 + aSig + bSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)         zExp = aExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)         goto roundAndPack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)     aSig |= 0x20000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)     zSig = ( aSig + bSig )<<1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)     --zExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)     if ( (sbits32) zSig < 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)         zSig = aSig + bSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)         ++zExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)  roundAndPack:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)     return roundAndPackFloat32( roundData, zSign, zExp, zSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) Returns the result of subtracting the absolute values of the single-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) precision floating-point values `a' and `b'.  If `zSign' is true, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) difference is negated before being returned.  `zSign' is ignored if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) result is a NaN.  The subtraction is performed according to the IEC/IEEE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) Standard for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) static float32 subFloat32Sigs( struct roundingData *roundData, float32 a, float32 b, flag zSign )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)     int16 aExp, bExp, zExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)     bits32 aSig, bSig, zSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)     int16 expDiff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)     aSig = extractFloat32Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)     aExp = extractFloat32Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)     bSig = extractFloat32Frac( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)     bExp = extractFloat32Exp( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)     expDiff = aExp - bExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)     aSig <<= 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)     bSig <<= 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)     if ( 0 < expDiff ) goto aExpBigger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)     if ( expDiff < 0 ) goto bExpBigger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)     if ( aExp == 0xFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)         if ( aSig | bSig ) return propagateFloat32NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)         roundData->exception |= float_flag_invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)         return float32_default_nan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)     if ( aExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)         aExp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)         bExp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)     if ( bSig < aSig ) goto aBigger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)     if ( aSig < bSig ) goto bBigger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)     return packFloat32( roundData->mode == float_round_down, 0, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)  bExpBigger:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)     if ( bExp == 0xFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)         if ( bSig ) return propagateFloat32NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)         return packFloat32( zSign ^ 1, 0xFF, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)     if ( aExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)         ++expDiff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)     else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)         aSig |= 0x40000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)     shift32RightJamming( aSig, - expDiff, &aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)     bSig |= 0x40000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)  bBigger:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)     zSig = bSig - aSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)     zExp = bExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)     zSign ^= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)     goto normalizeRoundAndPack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)  aExpBigger:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)     if ( aExp == 0xFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)         if ( aSig ) return propagateFloat32NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)         return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)     if ( bExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)         --expDiff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)     else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)         bSig |= 0x40000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)     shift32RightJamming( bSig, expDiff, &bSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)     aSig |= 0x40000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)  aBigger:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)     zSig = aSig - bSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)     zExp = aExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)  normalizeRoundAndPack:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)     --zExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)     return normalizeRoundAndPackFloat32( roundData, zSign, zExp, zSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) Returns the result of adding the single-precision floating-point values `a'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) and `b'.  The operation is performed according to the IEC/IEEE Standard for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) float32 float32_add( struct roundingData *roundData, float32 a, float32 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)     flag aSign, bSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)     aSign = extractFloat32Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)     bSign = extractFloat32Sign( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)     if ( aSign == bSign ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)         return addFloat32Sigs( roundData, a, b, aSign );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)     else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)         return subFloat32Sigs( roundData, a, b, aSign );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) Returns the result of subtracting the single-precision floating-point values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) float32 float32_sub( struct roundingData *roundData, float32 a, float32 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)     flag aSign, bSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)     aSign = extractFloat32Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)     bSign = extractFloat32Sign( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)     if ( aSign == bSign ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)         return subFloat32Sigs( roundData, a, b, aSign );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)     else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)         return addFloat32Sigs( roundData, a, b, aSign );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) Returns the result of multiplying the single-precision floating-point values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) float32 float32_mul( struct roundingData *roundData, float32 a, float32 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)     flag aSign, bSign, zSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)     int16 aExp, bExp, zExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223)     bits32 aSig, bSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)     bits64 zSig64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)     bits32 zSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)     aSig = extractFloat32Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228)     aExp = extractFloat32Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)     aSign = extractFloat32Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)     bSig = extractFloat32Frac( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)     bExp = extractFloat32Exp( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)     bSign = extractFloat32Sign( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)     zSign = aSign ^ bSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)     if ( aExp == 0xFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)         if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)             return propagateFloat32NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238)         if ( ( bExp | bSig ) == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)             roundData->exception |= float_flag_invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)             return float32_default_nan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)         return packFloat32( zSign, 0xFF, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)     if ( bExp == 0xFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)         if ( bSig ) return propagateFloat32NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)         if ( ( aExp | aSig ) == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)             roundData->exception |= float_flag_invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)             return float32_default_nan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)         return packFloat32( zSign, 0xFF, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)     if ( aExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253)         if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)     if ( bExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)         if ( bSig == 0 ) return packFloat32( zSign, 0, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258)         normalizeFloat32Subnormal( bSig, &bExp, &bSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)     zExp = aExp + bExp - 0x7F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)     aSig = ( aSig | 0x00800000 )<<7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)     bSig = ( bSig | 0x00800000 )<<8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)     shift64RightJamming( ( (bits64) aSig ) * bSig, 32, &zSig64 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)     zSig = zSig64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)     if ( 0 <= (sbits32) ( zSig<<1 ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)         zSig <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267)         --zExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)     return roundAndPackFloat32( roundData, zSign, zExp, zSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) Returns the result of dividing the single-precision floating-point value `a'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) by the corresponding value `b'.  The operation is performed according to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) IEC/IEEE Standard for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) float32 float32_div( struct roundingData *roundData, float32 a, float32 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)     flag aSign, bSign, zSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)     int16 aExp, bExp, zExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284)     bits32 aSig, bSig, zSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)     aSig = extractFloat32Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)     aExp = extractFloat32Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)     aSign = extractFloat32Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)     bSig = extractFloat32Frac( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290)     bExp = extractFloat32Exp( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)     bSign = extractFloat32Sign( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)     zSign = aSign ^ bSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)     if ( aExp == 0xFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294)         if ( aSig ) return propagateFloat32NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)         if ( bExp == 0xFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)             if ( bSig ) return propagateFloat32NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297)             roundData->exception |= float_flag_invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)             return float32_default_nan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)         return packFloat32( zSign, 0xFF, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)     if ( bExp == 0xFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)         if ( bSig ) return propagateFloat32NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)         return packFloat32( zSign, 0, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)     if ( bExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)         if ( bSig == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)             if ( ( aExp | aSig ) == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)                 roundData->exception |= float_flag_invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)                 return float32_default_nan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)             }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312)             roundData->exception |= float_flag_divbyzero;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)             return packFloat32( zSign, 0xFF, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)         normalizeFloat32Subnormal( bSig, &bExp, &bSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317)     if ( aExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318)         if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319)         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)     zExp = aExp - bExp + 0x7D;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)     aSig = ( aSig | 0x00800000 )<<7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323)     bSig = ( bSig | 0x00800000 )<<8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)     if ( bSig <= ( aSig + aSig ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325)         aSig >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)         ++zExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328)     {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)         bits64 tmp = ( (bits64) aSig )<<32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330)         do_div( tmp, bSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331)         zSig = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)     if ( ( zSig & 0x3F ) == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334)         zSig |= ( ( (bits64) bSig ) * zSig != ( (bits64) aSig )<<32 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336)     return roundAndPackFloat32( roundData, zSign, zExp, zSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) Returns the remainder of the single-precision floating-point value `a'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) with respect to the corresponding value `b'.  The operation is performed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) float32 float32_rem( struct roundingData *roundData, float32 a, float32 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349)     flag aSign, bSign, zSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350)     int16 aExp, bExp, expDiff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)     bits32 aSig, bSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352)     bits32 q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)     bits64 aSig64, bSig64, q64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354)     bits32 alternateASig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355)     sbits32 sigMean;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357)     aSig = extractFloat32Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)     aExp = extractFloat32Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)     aSign = extractFloat32Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360)     bSig = extractFloat32Frac( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361)     bExp = extractFloat32Exp( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)     bSign = extractFloat32Sign( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363)     if ( aExp == 0xFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364)         if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)             return propagateFloat32NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367)         roundData->exception |= float_flag_invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368)         return float32_default_nan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370)     if ( bExp == 0xFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371)         if ( bSig ) return propagateFloat32NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372)         return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)     if ( bExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375)         if ( bSig == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376)             roundData->exception |= float_flag_invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)             return float32_default_nan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379)         normalizeFloat32Subnormal( bSig, &bExp, &bSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381)     if ( aExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382)         if ( aSig == 0 ) return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)     expDiff = aExp - bExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)     aSig |= 0x00800000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387)     bSig |= 0x00800000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)     if ( expDiff < 32 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389)         aSig <<= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390)         bSig <<= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)         if ( expDiff < 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)             if ( expDiff < -1 ) return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393)             aSig >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)         q = ( bSig <= aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396)         if ( q ) aSig -= bSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397)         if ( 0 < expDiff ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398)             bits64 tmp = ( (bits64) aSig )<<32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)             do_div( tmp, bSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400)             q = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401)             q >>= 32 - expDiff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402)             bSig >>= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403)             aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405)         else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406)             aSig >>= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)             bSig >>= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)     else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411)         if ( bSig <= aSig ) aSig -= bSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)         aSig64 = ( (bits64) aSig )<<40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413)         bSig64 = ( (bits64) bSig )<<40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)         expDiff -= 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)         while ( 0 < expDiff ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416)             q64 = estimateDiv128To64( aSig64, 0, bSig64 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)             q64 = ( 2 < q64 ) ? q64 - 2 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418)             aSig64 = - ( ( bSig * q64 )<<38 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419)             expDiff -= 62;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421)         expDiff += 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422)         q64 = estimateDiv128To64( aSig64, 0, bSig64 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423)         q64 = ( 2 < q64 ) ? q64 - 2 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)         q = q64>>( 64 - expDiff );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425)         bSig <<= 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426)         aSig = ( ( aSig64>>33 )<<( expDiff - 1 ) ) - bSig * q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428)     do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429)         alternateASig = aSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430)         ++q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431)         aSig -= bSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432)     } while ( 0 <= (sbits32) aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433)     sigMean = aSig + alternateASig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434)     if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435)         aSig = alternateASig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437)     zSign = ( (sbits32) aSig < 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438)     if ( zSign ) aSig = - aSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439)     return normalizeRoundAndPackFloat32( roundData, aSign ^ zSign, bExp, aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) Returns the square root of the single-precision floating-point value `a'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) The operation is performed according to the IEC/IEEE Standard for Binary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) float32 float32_sqrt( struct roundingData *roundData, float32 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452)     flag aSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453)     int16 aExp, zExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454)     bits32 aSig, zSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)     bits64 rem, term;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457)     aSig = extractFloat32Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458)     aExp = extractFloat32Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459)     aSign = extractFloat32Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460)     if ( aExp == 0xFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461)         if ( aSig ) return propagateFloat32NaN( a, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462)         if ( ! aSign ) return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463)         roundData->exception |= float_flag_invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)         return float32_default_nan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466)     if ( aSign ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467)         if ( ( aExp | aSig ) == 0 ) return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468)         roundData->exception |= float_flag_invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469)         return float32_default_nan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471)     if ( aExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472)         if ( aSig == 0 ) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473)         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)     zExp = ( ( aExp - 0x7F )>>1 ) + 0x7E;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476)     aSig = ( aSig | 0x00800000 )<<8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477)     zSig = estimateSqrt32( aExp, aSig ) + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478)     if ( ( zSig & 0x7F ) <= 5 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)         if ( zSig < 2 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480)             zSig = 0xFFFFFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482)         else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483)             aSig >>= aExp & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484)             term = ( (bits64) zSig ) * zSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)             rem = ( ( (bits64) aSig )<<32 ) - term;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486)             while ( (sbits64) rem < 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487)                 --zSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488)                 rem += ( ( (bits64) zSig )<<1 ) | 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489)             }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490)             zSig |= ( rem != 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493)     shift32RightJamming( zSig, 1, &zSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494)     return roundAndPackFloat32( roundData, 0, zExp, zSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) Returns 1 if the single-precision floating-point value `a' is equal to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) corresponding value `b', and 0 otherwise.  The comparison is performed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) flag float32_eq( float32 a, float32 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508)     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509)          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510)        ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)         if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512)             float_raise( float_flag_invalid );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)         return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516)     return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) Returns 1 if the single-precision floating-point value `a' is less than or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) equal to the corresponding value `b', and 0 otherwise.  The comparison is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) performed according to the IEC/IEEE Standard for Binary Floating-point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) flag float32_le( float32 a, float32 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530)     flag aSign, bSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532)     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533)          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534)        ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535)         float_raise( float_flag_invalid );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536)         return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538)     aSign = extractFloat32Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539)     bSign = extractFloat32Sign( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540)     if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541)     return ( a == b ) || ( aSign ^ ( a < b ) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) Returns 1 if the single-precision floating-point value `a' is less than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) the corresponding value `b', and 0 otherwise.  The comparison is performed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) flag float32_lt( float32 a, float32 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554)     flag aSign, bSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556)     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557)          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)        ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559)         float_raise( float_flag_invalid );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560)         return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562)     aSign = extractFloat32Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563)     bSign = extractFloat32Sign( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)     if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565)     return ( a != b ) && ( aSign ^ ( a < b ) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) Returns 1 if the single-precision floating-point value `a' is equal to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) corresponding value `b', and 0 otherwise.  The invalid exception is raised
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) if either operand is a NaN.  Otherwise, the comparison is performed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) flag float32_eq_signaling( float32 a, float32 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580)     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581)          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582)        ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583)         float_raise( float_flag_invalid );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584)         return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586)     return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) Returns 1 if the single-precision floating-point value `a' is less than or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs do not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) cause an exception.  Otherwise, the comparison is performed according to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) IEC/IEEE Standard for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) flag float32_le_quiet( float32 a, float32 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600)     flag aSign, bSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601)     //int16 aExp, bExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603)     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604)          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605)        ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606)         /* Do nothing, even if NaN as we're quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607)         return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609)     aSign = extractFloat32Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610)     bSign = extractFloat32Sign( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611)     if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612)     return ( a == b ) || ( aSign ^ ( a < b ) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) Returns 1 if the single-precision floating-point value `a' is less than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) exception.  Otherwise, the comparison is performed according to the IEC/IEEE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) Standard for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) flag float32_lt_quiet( float32 a, float32 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626)     flag aSign, bSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628)     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629)          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630)        ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631)         /* Do nothing, even if NaN as we're quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632)         return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634)     aSign = extractFloat32Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635)     bSign = extractFloat32Sign( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636)     if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637)     return ( a != b ) && ( aSign ^ ( a < b ) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) Returns the result of converting the double-precision floating-point value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) `a' to the 32-bit two's complement integer format.  The conversion is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) performed according to the IEC/IEEE Standard for Binary Floating-point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) Arithmetic---which means in particular that the conversion is rounded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) according to the current rounding mode.  If `a' is a NaN, the largest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) positive integer is returned.  Otherwise, if the conversion overflows, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) largest integer with the same sign as `a' is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) int32 float64_to_int32( struct roundingData *roundData, float64 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654)     flag aSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655)     int16 aExp, shiftCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656)     bits64 aSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658)     aSig = extractFloat64Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659)     aExp = extractFloat64Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660)     aSign = extractFloat64Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661)     if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662)     if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663)     shiftCount = 0x42C - aExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664)     if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665)     return roundAndPackInt32( roundData, aSign, aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) Returns the result of converting the double-precision floating-point value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) `a' to the 32-bit two's complement integer format.  The conversion is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) performed according to the IEC/IEEE Standard for Binary Floating-point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) Arithmetic, except that the conversion is always rounded toward zero.  If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) `a' is a NaN, the largest positive integer is returned.  Otherwise, if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) conversion overflows, the largest integer with the same sign as `a' is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) int32 float64_to_int32_round_to_zero( float64 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682)     flag aSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683)     int16 aExp, shiftCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684)     bits64 aSig, savedASig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685)     int32 z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687)     aSig = extractFloat64Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688)     aExp = extractFloat64Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689)     aSign = extractFloat64Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690)     shiftCount = 0x433 - aExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691)     if ( shiftCount < 21 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692)         if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693)         goto invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695)     else if ( 52 < shiftCount ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696)         if ( aExp || aSig ) float_raise( float_flag_inexact );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697)         return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699)     aSig |= LIT64( 0x0010000000000000 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700)     savedASig = aSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701)     aSig >>= shiftCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702)     z = aSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703)     if ( aSign ) z = - z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704)     if ( ( z < 0 ) ^ aSign ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705)  invalid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706)         float_raise( float_flag_invalid );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707)         return aSign ? 0x80000000 : 0x7FFFFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709)     if ( ( aSig<<shiftCount ) != savedASig ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710)         float_raise( float_flag_inexact );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712)     return z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) Returns the result of converting the double-precision floating-point value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) `a' to the 32-bit two's complement unsigned integer format.  The conversion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) is performed according to the IEC/IEEE Standard for Binary Floating-point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) Arithmetic---which means in particular that the conversion is rounded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) according to the current rounding mode.  If `a' is a NaN, the largest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) positive integer is returned.  Otherwise, if the conversion overflows, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) largest positive integer is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) int32 float64_to_uint32( struct roundingData *roundData, float64 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729)     flag aSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730)     int16 aExp, shiftCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731)     bits64 aSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733)     aSig = extractFloat64Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734)     aExp = extractFloat64Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735)     aSign = 0; //extractFloat64Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736)     //if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737)     if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738)     shiftCount = 0x42C - aExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739)     if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740)     return roundAndPackInt32( roundData, aSign, aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) Returns the result of converting the double-precision floating-point value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) `a' to the 32-bit two's complement integer format.  The conversion is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) performed according to the IEC/IEEE Standard for Binary Floating-point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) Arithmetic, except that the conversion is always rounded toward zero.  If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) `a' is a NaN, the largest positive integer is returned.  Otherwise, if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) conversion overflows, the largest positive integer is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) int32 float64_to_uint32_round_to_zero( float64 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755)     flag aSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756)     int16 aExp, shiftCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757)     bits64 aSig, savedASig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758)     int32 z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760)     aSig = extractFloat64Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761)     aExp = extractFloat64Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762)     aSign = extractFloat64Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763)     shiftCount = 0x433 - aExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764)     if ( shiftCount < 21 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765)         if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766)         goto invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768)     else if ( 52 < shiftCount ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769)         if ( aExp || aSig ) float_raise( float_flag_inexact );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770)         return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772)     aSig |= LIT64( 0x0010000000000000 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773)     savedASig = aSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774)     aSig >>= shiftCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775)     z = aSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776)     if ( aSign ) z = - z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777)     if ( ( z < 0 ) ^ aSign ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778)  invalid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779)         float_raise( float_flag_invalid );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780)         return aSign ? 0x80000000 : 0x7FFFFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782)     if ( ( aSig<<shiftCount ) != savedASig ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783)         float_raise( float_flag_inexact );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785)     return z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) Returns the result of converting the double-precision floating-point value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) `a' to the single-precision floating-point format.  The conversion is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) performed according to the IEC/IEEE Standard for Binary Floating-point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) float32 float64_to_float32( struct roundingData *roundData, float64 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798)     flag aSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799)     int16 aExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800)     bits64 aSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801)     bits32 zSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803)     aSig = extractFloat64Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804)     aExp = extractFloat64Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805)     aSign = extractFloat64Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806)     if ( aExp == 0x7FF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807)         if ( aSig ) return commonNaNToFloat32( float64ToCommonNaN( a ) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808)         return packFloat32( aSign, 0xFF, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810)     shift64RightJamming( aSig, 22, &aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811)     zSig = aSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812)     if ( aExp || zSig ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813)         zSig |= 0x40000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814)         aExp -= 0x381;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816)     return roundAndPackFloat32( roundData, aSign, aExp, zSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) #ifdef FLOATX80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) Returns the result of converting the double-precision floating-point value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) `a' to the extended double-precision floating-point format.  The conversion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) is performed according to the IEC/IEEE Standard for Binary Floating-point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) floatx80 float64_to_floatx80( float64 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832)     flag aSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833)     int16 aExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834)     bits64 aSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836)     aSig = extractFloat64Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837)     aExp = extractFloat64Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838)     aSign = extractFloat64Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839)     if ( aExp == 0x7FF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840)         if ( aSig ) return commonNaNToFloatx80( float64ToCommonNaN( a ) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841)         return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843)     if ( aExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844)         if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845)         normalizeFloat64Subnormal( aSig, &aExp, &aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847)     return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848)         packFloatx80(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849)             aSign, aExp + 0x3C00, ( aSig | LIT64( 0x0010000000000000 ) )<<11 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) Rounds the double-precision floating-point value `a' to an integer, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) returns the result as a double-precision floating-point value.  The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) operation is performed according to the IEC/IEEE Standard for Binary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) float64 float64_round_to_int( struct roundingData *roundData, float64 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865)     flag aSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866)     int16 aExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867)     bits64 lastBitMask, roundBitsMask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868)     int8 roundingMode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869)     float64 z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871)     aExp = extractFloat64Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872)     if ( 0x433 <= aExp ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873)         if ( ( aExp == 0x7FF ) && extractFloat64Frac( a ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874)             return propagateFloat64NaN( a, a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876)         return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878)     if ( aExp <= 0x3FE ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879)         if ( (bits64) ( a<<1 ) == 0 ) return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880)         roundData->exception |= float_flag_inexact;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881)         aSign = extractFloat64Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882)         switch ( roundData->mode ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883)          case float_round_nearest_even:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884)             if ( ( aExp == 0x3FE ) && extractFloat64Frac( a ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885)                 return packFloat64( aSign, 0x3FF, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886)             }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887)             break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888)          case float_round_down:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889)             return aSign ? LIT64( 0xBFF0000000000000 ) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890)          case float_round_up:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891)             return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892)             aSign ? LIT64( 0x8000000000000000 ) : LIT64( 0x3FF0000000000000 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894)         return packFloat64( aSign, 0, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896)     lastBitMask = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897)     lastBitMask <<= 0x433 - aExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898)     roundBitsMask = lastBitMask - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899)     z = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900)     roundingMode = roundData->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901)     if ( roundingMode == float_round_nearest_even ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902)         z += lastBitMask>>1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903)         if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905)     else if ( roundingMode != float_round_to_zero ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906)         if ( extractFloat64Sign( z ) ^ ( roundingMode == float_round_up ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907)             z += roundBitsMask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910)     z &= ~ roundBitsMask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911)     if ( z != a ) roundData->exception |= float_flag_inexact;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912)     return z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) Returns the result of adding the absolute values of the double-precision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) floating-point values `a' and `b'.  If `zSign' is true, the sum is negated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) before being returned.  `zSign' is ignored if the result is a NaN.  The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) addition is performed according to the IEC/IEEE Standard for Binary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) static float64 addFloat64Sigs( struct roundingData *roundData, float64 a, float64 b, flag zSign )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927)     int16 aExp, bExp, zExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928)     bits64 aSig, bSig, zSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929)     int16 expDiff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931)     aSig = extractFloat64Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932)     aExp = extractFloat64Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933)     bSig = extractFloat64Frac( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934)     bExp = extractFloat64Exp( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935)     expDiff = aExp - bExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936)     aSig <<= 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937)     bSig <<= 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938)     if ( 0 < expDiff ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939)         if ( aExp == 0x7FF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940)             if ( aSig ) return propagateFloat64NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941)             return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943)         if ( bExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944)             --expDiff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946)         else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947)             bSig |= LIT64( 0x2000000000000000 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949)         shift64RightJamming( bSig, expDiff, &bSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950)         zExp = aExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952)     else if ( expDiff < 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953)         if ( bExp == 0x7FF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954)             if ( bSig ) return propagateFloat64NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955)             return packFloat64( zSign, 0x7FF, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957)         if ( aExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958)             ++expDiff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960)         else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961)             aSig |= LIT64( 0x2000000000000000 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963)         shift64RightJamming( aSig, - expDiff, &aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964)         zExp = bExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966)     else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967)         if ( aExp == 0x7FF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968)             if ( aSig | bSig ) return propagateFloat64NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969)             return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971)         if ( aExp == 0 ) return packFloat64( zSign, 0, ( aSig + bSig )>>9 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972)         zSig = LIT64( 0x4000000000000000 ) + aSig + bSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973)         zExp = aExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974)         goto roundAndPack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976)     aSig |= LIT64( 0x2000000000000000 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977)     zSig = ( aSig + bSig )<<1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978)     --zExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979)     if ( (sbits64) zSig < 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980)         zSig = aSig + bSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981)         ++zExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983)  roundAndPack:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984)     return roundAndPackFloat64( roundData, zSign, zExp, zSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) Returns the result of subtracting the absolute values of the double-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) precision floating-point values `a' and `b'.  If `zSign' is true, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) difference is negated before being returned.  `zSign' is ignored if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) result is a NaN.  The subtraction is performed according to the IEC/IEEE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) Standard for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) static float64 subFloat64Sigs( struct roundingData *roundData, float64 a, float64 b, flag zSign )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999)     int16 aExp, bExp, zExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000)     bits64 aSig, bSig, zSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001)     int16 expDiff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003)     aSig = extractFloat64Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004)     aExp = extractFloat64Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005)     bSig = extractFloat64Frac( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006)     bExp = extractFloat64Exp( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007)     expDiff = aExp - bExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008)     aSig <<= 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009)     bSig <<= 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010)     if ( 0 < expDiff ) goto aExpBigger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011)     if ( expDiff < 0 ) goto bExpBigger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012)     if ( aExp == 0x7FF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013)         if ( aSig | bSig ) return propagateFloat64NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014)         roundData->exception |= float_flag_invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015)         return float64_default_nan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017)     if ( aExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018)         aExp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019)         bExp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021)     if ( bSig < aSig ) goto aBigger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022)     if ( aSig < bSig ) goto bBigger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023)     return packFloat64( roundData->mode == float_round_down, 0, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024)  bExpBigger:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025)     if ( bExp == 0x7FF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026)         if ( bSig ) return propagateFloat64NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027)         return packFloat64( zSign ^ 1, 0x7FF, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029)     if ( aExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030)         ++expDiff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032)     else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033)         aSig |= LIT64( 0x4000000000000000 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035)     shift64RightJamming( aSig, - expDiff, &aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036)     bSig |= LIT64( 0x4000000000000000 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037)  bBigger:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038)     zSig = bSig - aSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039)     zExp = bExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040)     zSign ^= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041)     goto normalizeRoundAndPack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042)  aExpBigger:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043)     if ( aExp == 0x7FF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044)         if ( aSig ) return propagateFloat64NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045)         return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047)     if ( bExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048)         --expDiff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050)     else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051)         bSig |= LIT64( 0x4000000000000000 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053)     shift64RightJamming( bSig, expDiff, &bSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054)     aSig |= LIT64( 0x4000000000000000 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055)  aBigger:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056)     zSig = aSig - bSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057)     zExp = aExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058)  normalizeRoundAndPack:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059)     --zExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060)     return normalizeRoundAndPackFloat64( roundData, zSign, zExp, zSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) Returns the result of adding the double-precision floating-point values `a'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) and `b'.  The operation is performed according to the IEC/IEEE Standard for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) float64 float64_add( struct roundingData *roundData, float64 a, float64 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073)     flag aSign, bSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075)     aSign = extractFloat64Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076)     bSign = extractFloat64Sign( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077)     if ( aSign == bSign ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078)         return addFloat64Sigs( roundData, a, b, aSign );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080)     else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081)         return subFloat64Sigs( roundData, a, b, aSign );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) Returns the result of subtracting the double-precision floating-point values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) float64 float64_sub( struct roundingData *roundData, float64 a, float64 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095)     flag aSign, bSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097)     aSign = extractFloat64Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098)     bSign = extractFloat64Sign( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099)     if ( aSign == bSign ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100)         return subFloat64Sigs( roundData, a, b, aSign );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102)     else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103)         return addFloat64Sigs( roundData, a, b, aSign );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) Returns the result of multiplying the double-precision floating-point values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) float64 float64_mul( struct roundingData *roundData, float64 a, float64 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117)     flag aSign, bSign, zSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118)     int16 aExp, bExp, zExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119)     bits64 aSig, bSig, zSig0, zSig1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121)     aSig = extractFloat64Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122)     aExp = extractFloat64Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123)     aSign = extractFloat64Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124)     bSig = extractFloat64Frac( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125)     bExp = extractFloat64Exp( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126)     bSign = extractFloat64Sign( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127)     zSign = aSign ^ bSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128)     if ( aExp == 0x7FF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129)         if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130)             return propagateFloat64NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132)         if ( ( bExp | bSig ) == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133)             roundData->exception |= float_flag_invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134)             return float64_default_nan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136)         return packFloat64( zSign, 0x7FF, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138)     if ( bExp == 0x7FF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139)         if ( bSig ) return propagateFloat64NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140)         if ( ( aExp | aSig ) == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141)             roundData->exception |= float_flag_invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142)             return float64_default_nan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144)         return packFloat64( zSign, 0x7FF, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146)     if ( aExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147)         if ( aSig == 0 ) return packFloat64( zSign, 0, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148)         normalizeFloat64Subnormal( aSig, &aExp, &aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150)     if ( bExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151)         if ( bSig == 0 ) return packFloat64( zSign, 0, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152)         normalizeFloat64Subnormal( bSig, &bExp, &bSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154)     zExp = aExp + bExp - 0x3FF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155)     aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156)     bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157)     mul64To128( aSig, bSig, &zSig0, &zSig1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158)     zSig0 |= ( zSig1 != 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159)     if ( 0 <= (sbits64) ( zSig0<<1 ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160)         zSig0 <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161)         --zExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163)     return roundAndPackFloat64( roundData, zSign, zExp, zSig0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) Returns the result of dividing the double-precision floating-point value `a'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) by the corresponding value `b'.  The operation is performed according to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) the IEC/IEEE Standard for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) float64 float64_div( struct roundingData *roundData, float64 a, float64 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176)     flag aSign, bSign, zSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177)     int16 aExp, bExp, zExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178)     bits64 aSig, bSig, zSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179)     bits64 rem0, rem1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180)     bits64 term0, term1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182)     aSig = extractFloat64Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183)     aExp = extractFloat64Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184)     aSign = extractFloat64Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185)     bSig = extractFloat64Frac( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186)     bExp = extractFloat64Exp( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187)     bSign = extractFloat64Sign( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188)     zSign = aSign ^ bSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189)     if ( aExp == 0x7FF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190)         if ( aSig ) return propagateFloat64NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191)         if ( bExp == 0x7FF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192)             if ( bSig ) return propagateFloat64NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193)             roundData->exception |= float_flag_invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194)             return float64_default_nan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196)         return packFloat64( zSign, 0x7FF, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198)     if ( bExp == 0x7FF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199)         if ( bSig ) return propagateFloat64NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200)         return packFloat64( zSign, 0, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202)     if ( bExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203)         if ( bSig == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204)             if ( ( aExp | aSig ) == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205)                 roundData->exception |= float_flag_invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206)                 return float64_default_nan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207)             }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208)             roundData->exception |= float_flag_divbyzero;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209)             return packFloat64( zSign, 0x7FF, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211)         normalizeFloat64Subnormal( bSig, &bExp, &bSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213)     if ( aExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214)         if ( aSig == 0 ) return packFloat64( zSign, 0, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215)         normalizeFloat64Subnormal( aSig, &aExp, &aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217)     zExp = aExp - bExp + 0x3FD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218)     aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219)     bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220)     if ( bSig <= ( aSig + aSig ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221)         aSig >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222)         ++zExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224)     zSig = estimateDiv128To64( aSig, 0, bSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225)     if ( ( zSig & 0x1FF ) <= 2 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226)         mul64To128( bSig, zSig, &term0, &term1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227)         sub128( aSig, 0, term0, term1, &rem0, &rem1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228)         while ( (sbits64) rem0 < 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229)             --zSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230)             add128( rem0, rem1, 0, bSig, &rem0, &rem1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232)         zSig |= ( rem1 != 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234)     return roundAndPackFloat64( roundData, zSign, zExp, zSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) Returns the remainder of the double-precision floating-point value `a'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) with respect to the corresponding value `b'.  The operation is performed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) float64 float64_rem( struct roundingData *roundData, float64 a, float64 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247)     flag aSign, bSign, zSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248)     int16 aExp, bExp, expDiff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249)     bits64 aSig, bSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250)     bits64 q, alternateASig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251)     sbits64 sigMean;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253)     aSig = extractFloat64Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254)     aExp = extractFloat64Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255)     aSign = extractFloat64Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256)     bSig = extractFloat64Frac( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257)     bExp = extractFloat64Exp( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258)     bSign = extractFloat64Sign( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259)     if ( aExp == 0x7FF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260)         if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261)             return propagateFloat64NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263)         roundData->exception |= float_flag_invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264)         return float64_default_nan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266)     if ( bExp == 0x7FF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267)         if ( bSig ) return propagateFloat64NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268)         return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270)     if ( bExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271)         if ( bSig == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272)             roundData->exception |= float_flag_invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273)             return float64_default_nan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275)         normalizeFloat64Subnormal( bSig, &bExp, &bSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277)     if ( aExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278)         if ( aSig == 0 ) return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279)         normalizeFloat64Subnormal( aSig, &aExp, &aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281)     expDiff = aExp - bExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282)     aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283)     bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284)     if ( expDiff < 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285)         if ( expDiff < -1 ) return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286)         aSig >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288)     q = ( bSig <= aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289)     if ( q ) aSig -= bSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290)     expDiff -= 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291)     while ( 0 < expDiff ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292)         q = estimateDiv128To64( aSig, 0, bSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293)         q = ( 2 < q ) ? q - 2 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294)         aSig = - ( ( bSig>>2 ) * q );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295)         expDiff -= 62;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297)     expDiff += 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298)     if ( 0 < expDiff ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299)         q = estimateDiv128To64( aSig, 0, bSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300)         q = ( 2 < q ) ? q - 2 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301)         q >>= 64 - expDiff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302)         bSig >>= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303)         aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305)     else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306)         aSig >>= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307)         bSig >>= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309)     do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310)         alternateASig = aSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311)         ++q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312)         aSig -= bSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313)     } while ( 0 <= (sbits64) aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314)     sigMean = aSig + alternateASig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315)     if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316)         aSig = alternateASig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318)     zSign = ( (sbits64) aSig < 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319)     if ( zSign ) aSig = - aSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320)     return normalizeRoundAndPackFloat64( roundData, aSign ^ zSign, bExp, aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) Returns the square root of the double-precision floating-point value `a'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) The operation is performed according to the IEC/IEEE Standard for Binary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) float64 float64_sqrt( struct roundingData *roundData, float64 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333)     flag aSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334)     int16 aExp, zExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335)     bits64 aSig, zSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336)     bits64 rem0, rem1, term0, term1; //, shiftedRem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337)     //float64 z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339)     aSig = extractFloat64Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340)     aExp = extractFloat64Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341)     aSign = extractFloat64Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342)     if ( aExp == 0x7FF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343)         if ( aSig ) return propagateFloat64NaN( a, a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344)         if ( ! aSign ) return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345)         roundData->exception |= float_flag_invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346)         return float64_default_nan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348)     if ( aSign ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349)         if ( ( aExp | aSig ) == 0 ) return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350)         roundData->exception |= float_flag_invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351)         return float64_default_nan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353)     if ( aExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354)         if ( aSig == 0 ) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355)         normalizeFloat64Subnormal( aSig, &aExp, &aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357)     zExp = ( ( aExp - 0x3FF )>>1 ) + 0x3FE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358)     aSig |= LIT64( 0x0010000000000000 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359)     zSig = estimateSqrt32( aExp, aSig>>21 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360)     zSig <<= 31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361)     aSig <<= 9 - ( aExp & 1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362)     zSig = estimateDiv128To64( aSig, 0, zSig ) + zSig + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363)     if ( ( zSig & 0x3FF ) <= 5 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364)         if ( zSig < 2 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365)             zSig = LIT64( 0xFFFFFFFFFFFFFFFF );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367)         else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368)             aSig <<= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369)             mul64To128( zSig, zSig, &term0, &term1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370)             sub128( aSig, 0, term0, term1, &rem0, &rem1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371)             while ( (sbits64) rem0 < 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372)                 --zSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373)                 shortShift128Left( 0, zSig, 1, &term0, &term1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374)                 term1 |= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375)                 add128( rem0, rem1, term0, term1, &rem0, &rem1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376)             }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377)             zSig |= ( ( rem0 | rem1 ) != 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380)     shift64RightJamming( zSig, 1, &zSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381)     return roundAndPackFloat64( roundData, 0, zExp, zSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) Returns 1 if the double-precision floating-point value `a' is equal to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) corresponding value `b', and 0 otherwise.  The comparison is performed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) flag float64_eq( float64 a, float64 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395)     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396)          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397)        ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398)         if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399)             float_raise( float_flag_invalid );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401)         return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403)     return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) Returns 1 if the double-precision floating-point value `a' is less than or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) equal to the corresponding value `b', and 0 otherwise.  The comparison is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) performed according to the IEC/IEEE Standard for Binary Floating-point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) flag float64_le( float64 a, float64 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417)     flag aSign, bSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419)     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420)          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421)        ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422)         float_raise( float_flag_invalid );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423)         return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425)     aSign = extractFloat64Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426)     bSign = extractFloat64Sign( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427)     if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428)     return ( a == b ) || ( aSign ^ ( a < b ) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) Returns 1 if the double-precision floating-point value `a' is less than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) the corresponding value `b', and 0 otherwise.  The comparison is performed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) flag float64_lt( float64 a, float64 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441)     flag aSign, bSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443)     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444)          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445)        ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446)         float_raise( float_flag_invalid );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447)         return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449)     aSign = extractFloat64Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450)     bSign = extractFloat64Sign( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451)     if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452)     return ( a != b ) && ( aSign ^ ( a < b ) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) Returns 1 if the double-precision floating-point value `a' is equal to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) corresponding value `b', and 0 otherwise.  The invalid exception is raised
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) if either operand is a NaN.  Otherwise, the comparison is performed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) flag float64_eq_signaling( float64 a, float64 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467)     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468)          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469)        ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470)         float_raise( float_flag_invalid );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471)         return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473)     return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) Returns 1 if the double-precision floating-point value `a' is less than or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs do not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) cause an exception.  Otherwise, the comparison is performed according to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) IEC/IEEE Standard for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) flag float64_le_quiet( float64 a, float64 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487)     flag aSign, bSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488)     //int16 aExp, bExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490)     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491)          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492)        ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493)         /* Do nothing, even if NaN as we're quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494)         return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496)     aSign = extractFloat64Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497)     bSign = extractFloat64Sign( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498)     if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499)     return ( a == b ) || ( aSign ^ ( a < b ) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) Returns 1 if the double-precision floating-point value `a' is less than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) exception.  Otherwise, the comparison is performed according to the IEC/IEEE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) Standard for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) flag float64_lt_quiet( float64 a, float64 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513)     flag aSign, bSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515)     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516)          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517)        ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518)         /* Do nothing, even if NaN as we're quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519)         return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521)     aSign = extractFloat64Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522)     bSign = extractFloat64Sign( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523)     if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524)     return ( a != b ) && ( aSign ^ ( a < b ) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) #ifdef FLOATX80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) Returns the result of converting the extended double-precision floating-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) point value `a' to the 32-bit two's complement integer format.  The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) conversion is performed according to the IEC/IEEE Standard for Binary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) Floating-point Arithmetic---which means in particular that the conversion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) is rounded according to the current rounding mode.  If `a' is a NaN, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) largest positive integer is returned.  Otherwise, if the conversion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) overflows, the largest integer with the same sign as `a' is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) int32 floatx80_to_int32( struct roundingData *roundData, floatx80 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543)     flag aSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544)     int32 aExp, shiftCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545)     bits64 aSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547)     aSig = extractFloatx80Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548)     aExp = extractFloatx80Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549)     aSign = extractFloatx80Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550)     if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551)     shiftCount = 0x4037 - aExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552)     if ( shiftCount <= 0 ) shiftCount = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553)     shift64RightJamming( aSig, shiftCount, &aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554)     return roundAndPackInt32( roundData, aSign, aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) Returns the result of converting the extended double-precision floating-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) point value `a' to the 32-bit two's complement integer format.  The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) conversion is performed according to the IEC/IEEE Standard for Binary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) Floating-point Arithmetic, except that the conversion is always rounded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) toward zero.  If `a' is a NaN, the largest positive integer is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) Otherwise, if the conversion overflows, the largest integer with the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) sign as `a' is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) int32 floatx80_to_int32_round_to_zero( floatx80 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571)     flag aSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572)     int32 aExp, shiftCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573)     bits64 aSig, savedASig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574)     int32 z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576)     aSig = extractFloatx80Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577)     aExp = extractFloatx80Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578)     aSign = extractFloatx80Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579)     shiftCount = 0x403E - aExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580)     if ( shiftCount < 32 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581)         if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582)         goto invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584)     else if ( 63 < shiftCount ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585)         if ( aExp || aSig ) float_raise( float_flag_inexact );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586)         return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588)     savedASig = aSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589)     aSig >>= shiftCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590)     z = aSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591)     if ( aSign ) z = - z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592)     if ( ( z < 0 ) ^ aSign ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593)  invalid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594)         float_raise( float_flag_invalid );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595)         return aSign ? 0x80000000 : 0x7FFFFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597)     if ( ( aSig<<shiftCount ) != savedASig ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598)         float_raise( float_flag_inexact );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600)     return z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) Returns the result of converting the extended double-precision floating-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) point value `a' to the single-precision floating-point format.  The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) conversion is performed according to the IEC/IEEE Standard for Binary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) float32 floatx80_to_float32( struct roundingData *roundData, floatx80 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614)     flag aSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615)     int32 aExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616)     bits64 aSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618)     aSig = extractFloatx80Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619)     aExp = extractFloatx80Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620)     aSign = extractFloatx80Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621)     if ( aExp == 0x7FFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622)         if ( (bits64) ( aSig<<1 ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623)             return commonNaNToFloat32( floatx80ToCommonNaN( a ) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625)         return packFloat32( aSign, 0xFF, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627)     shift64RightJamming( aSig, 33, &aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628)     if ( aExp || aSig ) aExp -= 0x3F81;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629)     return roundAndPackFloat32( roundData, aSign, aExp, aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) Returns the result of converting the extended double-precision floating-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) point value `a' to the double-precision floating-point format.  The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) conversion is performed according to the IEC/IEEE Standard for Binary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) float64 floatx80_to_float64( struct roundingData *roundData, floatx80 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643)     flag aSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644)     int32 aExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645)     bits64 aSig, zSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647)     aSig = extractFloatx80Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648)     aExp = extractFloatx80Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649)     aSign = extractFloatx80Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650)     if ( aExp == 0x7FFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651)         if ( (bits64) ( aSig<<1 ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652)             return commonNaNToFloat64( floatx80ToCommonNaN( a ) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654)         return packFloat64( aSign, 0x7FF, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656)     shift64RightJamming( aSig, 1, &zSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657)     if ( aExp || aSig ) aExp -= 0x3C01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658)     return roundAndPackFloat64( roundData, aSign, aExp, zSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) Rounds the extended double-precision floating-point value `a' to an integer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) and returns the result as an extended quadruple-precision floating-point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) value.  The operation is performed according to the IEC/IEEE Standard for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) floatx80 floatx80_round_to_int( struct roundingData *roundData, floatx80 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672)     flag aSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673)     int32 aExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674)     bits64 lastBitMask, roundBitsMask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675)     int8 roundingMode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676)     floatx80 z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678)     aExp = extractFloatx80Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679)     if ( 0x403E <= aExp ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680)         if ( ( aExp == 0x7FFF ) && (bits64) ( extractFloatx80Frac( a )<<1 ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681)             return propagateFloatx80NaN( a, a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683)         return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685)     if ( aExp <= 0x3FFE ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686)         if (    ( aExp == 0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687)              && ( (bits64) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688)             return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690)         roundData->exception |= float_flag_inexact;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691)         aSign = extractFloatx80Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692)         switch ( roundData->mode ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693)          case float_round_nearest_even:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694)             if ( ( aExp == 0x3FFE ) && (bits64) ( extractFloatx80Frac( a )<<1 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695)                ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696)                 return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697)                     packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698)             }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699)             break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700)          case float_round_down:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701)             return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702)                   aSign ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703)                       packFloatx80( 1, 0x3FFF, LIT64( 0x8000000000000000 ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704)                 : packFloatx80( 0, 0, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705)          case float_round_up:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706)             return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707)                   aSign ? packFloatx80( 1, 0, 0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708)                 : packFloatx80( 0, 0x3FFF, LIT64( 0x8000000000000000 ) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710)         return packFloatx80( aSign, 0, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712)     lastBitMask = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713)     lastBitMask <<= 0x403E - aExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714)     roundBitsMask = lastBitMask - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715)     z = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716)     roundingMode = roundData->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717)     if ( roundingMode == float_round_nearest_even ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718)         z.low += lastBitMask>>1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719)         if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721)     else if ( roundingMode != float_round_to_zero ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722)         if ( extractFloatx80Sign( z ) ^ ( roundingMode == float_round_up ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723)             z.low += roundBitsMask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726)     z.low &= ~ roundBitsMask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727)     if ( z.low == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728)         ++z.high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729)         z.low = LIT64( 0x8000000000000000 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731)     if ( z.low != a.low ) roundData->exception |= float_flag_inexact;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732)     return z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) Returns the result of adding the absolute values of the extended double-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) precision floating-point values `a' and `b'.  If `zSign' is true, the sum is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) negated before being returned.  `zSign' is ignored if the result is a NaN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) The addition is performed according to the IEC/IEEE Standard for Binary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) static floatx80 addFloatx80Sigs( struct roundingData *roundData, floatx80 a, floatx80 b, flag zSign )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747)     int32 aExp, bExp, zExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748)     bits64 aSig, bSig, zSig0, zSig1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749)     int32 expDiff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751)     aSig = extractFloatx80Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752)     aExp = extractFloatx80Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753)     bSig = extractFloatx80Frac( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754)     bExp = extractFloatx80Exp( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755)     expDiff = aExp - bExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756)     if ( 0 < expDiff ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757)         if ( aExp == 0x7FFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758)             if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759)             return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761)         if ( bExp == 0 ) --expDiff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762)         shift64ExtraRightJamming( bSig, 0, expDiff, &bSig, &zSig1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763)         zExp = aExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765)     else if ( expDiff < 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766)         if ( bExp == 0x7FFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767)             if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768)             return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770)         if ( aExp == 0 ) ++expDiff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771)         shift64ExtraRightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772)         zExp = bExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774)     else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775)         if ( aExp == 0x7FFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776)             if ( (bits64) ( ( aSig | bSig )<<1 ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777)                 return propagateFloatx80NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778)             }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779)             return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781)         zSig1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782)         zSig0 = aSig + bSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783)         if ( aExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784)             normalizeFloatx80Subnormal( zSig0, &zExp, &zSig0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785)             goto roundAndPack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787)         zExp = aExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788)         goto shiftRight1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791)     zSig0 = aSig + bSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793)     if ( (sbits64) zSig0 < 0 ) goto roundAndPack; 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794)  shiftRight1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795)     shift64ExtraRightJamming( zSig0, zSig1, 1, &zSig0, &zSig1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796)     zSig0 |= LIT64( 0x8000000000000000 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797)     ++zExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798)  roundAndPack:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799)     return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800)         roundAndPackFloatx80(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801)             roundData, zSign, zExp, zSig0, zSig1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) Returns the result of subtracting the absolute values of the extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) double-precision floating-point values `a' and `b'.  If `zSign' is true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) the difference is negated before being returned.  `zSign' is ignored if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) result is a NaN.  The subtraction is performed according to the IEC/IEEE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) Standard for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) static floatx80 subFloatx80Sigs( struct roundingData *roundData, floatx80 a, floatx80 b, flag zSign )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816)     int32 aExp, bExp, zExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817)     bits64 aSig, bSig, zSig0, zSig1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818)     int32 expDiff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819)     floatx80 z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821)     aSig = extractFloatx80Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822)     aExp = extractFloatx80Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823)     bSig = extractFloatx80Frac( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824)     bExp = extractFloatx80Exp( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825)     expDiff = aExp - bExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826)     if ( 0 < expDiff ) goto aExpBigger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827)     if ( expDiff < 0 ) goto bExpBigger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828)     if ( aExp == 0x7FFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829)         if ( (bits64) ( ( aSig | bSig )<<1 ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830)             return propagateFloatx80NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832)         roundData->exception |= float_flag_invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833)         z.low = floatx80_default_nan_low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834)         z.high = floatx80_default_nan_high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835)         z.__padding = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836)         return z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838)     if ( aExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839)         aExp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840)         bExp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842)     zSig1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843)     if ( bSig < aSig ) goto aBigger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844)     if ( aSig < bSig ) goto bBigger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845)     return packFloatx80( roundData->mode == float_round_down, 0, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846)  bExpBigger:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847)     if ( bExp == 0x7FFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848)         if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849)         return packFloatx80( zSign ^ 1, 0x7FFF, LIT64( 0x8000000000000000 ) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851)     if ( aExp == 0 ) ++expDiff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852)     shift128RightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853)  bBigger:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854)     sub128( bSig, 0, aSig, zSig1, &zSig0, &zSig1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855)     zExp = bExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856)     zSign ^= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857)     goto normalizeRoundAndPack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858)  aExpBigger:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859)     if ( aExp == 0x7FFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860)         if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861)         return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863)     if ( bExp == 0 ) --expDiff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864)     shift128RightJamming( bSig, 0, expDiff, &bSig, &zSig1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865)  aBigger:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866)     sub128( aSig, 0, bSig, zSig1, &zSig0, &zSig1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867)     zExp = aExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868)  normalizeRoundAndPack:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869)     return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870)         normalizeRoundAndPackFloatx80(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871)             roundData, zSign, zExp, zSig0, zSig1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) Returns the result of adding the extended double-precision floating-point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) values `a' and `b'.  The operation is performed according to the IEC/IEEE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) Standard for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) floatx80 floatx80_add( struct roundingData *roundData, floatx80 a, floatx80 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884)     flag aSign, bSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886)     aSign = extractFloatx80Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887)     bSign = extractFloatx80Sign( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888)     if ( aSign == bSign ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889)         return addFloatx80Sigs( roundData, a, b, aSign );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891)     else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892)         return subFloatx80Sigs( roundData, a, b, aSign );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) Returns the result of subtracting the extended double-precision floating-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) point values `a' and `b'.  The operation is performed according to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) IEC/IEEE Standard for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) floatx80 floatx80_sub( struct roundingData *roundData, floatx80 a, floatx80 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906)     flag aSign, bSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908)     aSign = extractFloatx80Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909)     bSign = extractFloatx80Sign( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910)     if ( aSign == bSign ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911)         return subFloatx80Sigs( roundData, a, b, aSign );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913)     else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914)         return addFloatx80Sigs( roundData, a, b, aSign );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) Returns the result of multiplying the extended double-precision floating-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) point values `a' and `b'.  The operation is performed according to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) IEC/IEEE Standard for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) floatx80 floatx80_mul( struct roundingData *roundData, floatx80 a, floatx80 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928)     flag aSign, bSign, zSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929)     int32 aExp, bExp, zExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930)     bits64 aSig, bSig, zSig0, zSig1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931)     floatx80 z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933)     aSig = extractFloatx80Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934)     aExp = extractFloatx80Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935)     aSign = extractFloatx80Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936)     bSig = extractFloatx80Frac( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937)     bExp = extractFloatx80Exp( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938)     bSign = extractFloatx80Sign( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939)     zSign = aSign ^ bSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940)     if ( aExp == 0x7FFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941)         if (    (bits64) ( aSig<<1 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942)              || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943)             return propagateFloatx80NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945)         if ( ( bExp | bSig ) == 0 ) goto invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946)         return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948)     if ( bExp == 0x7FFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949)         if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950)         if ( ( aExp | aSig ) == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951)  invalid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952)             roundData->exception |= float_flag_invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953)             z.low = floatx80_default_nan_low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954)             z.high = floatx80_default_nan_high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955)             z.__padding = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956)             return z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958)         return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960)     if ( aExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961)         if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962)         normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964)     if ( bExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965)         if ( bSig == 0 ) return packFloatx80( zSign, 0, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966)         normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968)     zExp = aExp + bExp - 0x3FFE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969)     mul64To128( aSig, bSig, &zSig0, &zSig1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970)     if ( 0 < (sbits64) zSig0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971)         shortShift128Left( zSig0, zSig1, 1, &zSig0, &zSig1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972)         --zExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974)     return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975)         roundAndPackFloatx80(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976)             roundData, zSign, zExp, zSig0, zSig1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) Returns the result of dividing the extended double-precision floating-point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) value `a' by the corresponding value `b'.  The operation is performed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) floatx80 floatx80_div( struct roundingData *roundData, floatx80 a, floatx80 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989)     flag aSign, bSign, zSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990)     int32 aExp, bExp, zExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991)     bits64 aSig, bSig, zSig0, zSig1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992)     bits64 rem0, rem1, rem2, term0, term1, term2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993)     floatx80 z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995)     aSig = extractFloatx80Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996)     aExp = extractFloatx80Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997)     aSign = extractFloatx80Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998)     bSig = extractFloatx80Frac( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999)     bExp = extractFloatx80Exp( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000)     bSign = extractFloatx80Sign( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001)     zSign = aSign ^ bSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002)     if ( aExp == 0x7FFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003)         if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004)         if ( bExp == 0x7FFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005)             if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006)             goto invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008)         return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010)     if ( bExp == 0x7FFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011)         if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012)         return packFloatx80( zSign, 0, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014)     if ( bExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015)         if ( bSig == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016)             if ( ( aExp | aSig ) == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017)  invalid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018)                 roundData->exception |= float_flag_invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019)                 z.low = floatx80_default_nan_low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020)                 z.high = floatx80_default_nan_high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021)                 z.__padding = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022)                 return z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023)             }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024)             roundData->exception |= float_flag_divbyzero;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025)             return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027)         normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029)     if ( aExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030)         if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031)         normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033)     zExp = aExp - bExp + 0x3FFE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034)     rem1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035)     if ( bSig <= aSig ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036)         shift128Right( aSig, 0, 1, &aSig, &rem1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037)         ++zExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039)     zSig0 = estimateDiv128To64( aSig, rem1, bSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040)     mul64To128( bSig, zSig0, &term0, &term1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041)     sub128( aSig, rem1, term0, term1, &rem0, &rem1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042)     while ( (sbits64) rem0 < 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043)         --zSig0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044)         add128( rem0, rem1, 0, bSig, &rem0, &rem1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046)     zSig1 = estimateDiv128To64( rem1, 0, bSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047)     if ( (bits64) ( zSig1<<1 ) <= 8 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048)         mul64To128( bSig, zSig1, &term1, &term2 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049)         sub128( rem1, 0, term1, term2, &rem1, &rem2 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050)         while ( (sbits64) rem1 < 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051)             --zSig1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052)             add128( rem1, rem2, 0, bSig, &rem1, &rem2 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054)         zSig1 |= ( ( rem1 | rem2 ) != 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056)     return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057)         roundAndPackFloatx80(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058)             roundData, zSign, zExp, zSig0, zSig1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) Returns the remainder of the extended double-precision floating-point value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) `a' with respect to the corresponding value `b'.  The operation is performed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) floatx80 floatx80_rem( struct roundingData *roundData, floatx80 a, floatx80 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071)     flag aSign, bSign, zSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072)     int32 aExp, bExp, expDiff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073)     bits64 aSig0, aSig1, bSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074)     bits64 q, term0, term1, alternateASig0, alternateASig1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075)     floatx80 z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077)     aSig0 = extractFloatx80Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078)     aExp = extractFloatx80Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079)     aSign = extractFloatx80Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080)     bSig = extractFloatx80Frac( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081)     bExp = extractFloatx80Exp( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082)     bSign = extractFloatx80Sign( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083)     if ( aExp == 0x7FFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084)         if (    (bits64) ( aSig0<<1 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085)              || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086)             return propagateFloatx80NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088)         goto invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090)     if ( bExp == 0x7FFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091)         if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092)         return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094)     if ( bExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095)         if ( bSig == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096)  invalid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097)             roundData->exception |= float_flag_invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098)             z.low = floatx80_default_nan_low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099)             z.high = floatx80_default_nan_high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100)             z.__padding = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101)             return z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103)         normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105)     if ( aExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106)         if ( (bits64) ( aSig0<<1 ) == 0 ) return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107)         normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109)     bSig |= LIT64( 0x8000000000000000 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110)     zSign = aSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111)     expDiff = aExp - bExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112)     aSig1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113)     if ( expDiff < 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114)         if ( expDiff < -1 ) return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115)         shift128Right( aSig0, 0, 1, &aSig0, &aSig1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116)         expDiff = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118)     q = ( bSig <= aSig0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119)     if ( q ) aSig0 -= bSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120)     expDiff -= 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121)     while ( 0 < expDiff ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122)         q = estimateDiv128To64( aSig0, aSig1, bSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123)         q = ( 2 < q ) ? q - 2 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124)         mul64To128( bSig, q, &term0, &term1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125)         sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126)         shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127)         expDiff -= 62;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129)     expDiff += 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130)     if ( 0 < expDiff ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131)         q = estimateDiv128To64( aSig0, aSig1, bSig );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132)         q = ( 2 < q ) ? q - 2 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133)         q >>= 64 - expDiff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134)         mul64To128( bSig, q<<( 64 - expDiff ), &term0, &term1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135)         sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136)         shortShift128Left( 0, bSig, 64 - expDiff, &term0, &term1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137)         while ( le128( term0, term1, aSig0, aSig1 ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138)             ++q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139)             sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142)     else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143)         term1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144)         term0 = bSig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146)     sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147)     if (    lt128( alternateASig0, alternateASig1, aSig0, aSig1 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148)          || (    eq128( alternateASig0, alternateASig1, aSig0, aSig1 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149)               && ( q & 1 ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150)        ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151)         aSig0 = alternateASig0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152)         aSig1 = alternateASig1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153)         zSign = ! zSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156)     return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157)         normalizeRoundAndPackFloatx80(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158)             roundData, zSign, bExp + expDiff, aSig0, aSig1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) Returns the square root of the extended double-precision floating-point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) value `a'.  The operation is performed according to the IEC/IEEE Standard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) floatx80 floatx80_sqrt( struct roundingData *roundData, floatx80 a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171)     flag aSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172)     int32 aExp, zExp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173)     bits64 aSig0, aSig1, zSig0, zSig1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174)     bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175)     bits64 shiftedRem0, shiftedRem1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176)     floatx80 z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178)     aSig0 = extractFloatx80Frac( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179)     aExp = extractFloatx80Exp( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180)     aSign = extractFloatx80Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181)     if ( aExp == 0x7FFF ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182)         if ( (bits64) ( aSig0<<1 ) ) return propagateFloatx80NaN( a, a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183)         if ( ! aSign ) return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184)         goto invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186)     if ( aSign ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187)         if ( ( aExp | aSig0 ) == 0 ) return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188)  invalid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189)         roundData->exception |= float_flag_invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190)         z.low = floatx80_default_nan_low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191)         z.high = floatx80_default_nan_high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192)         z.__padding = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193)         return z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195)     if ( aExp == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196)         if ( aSig0 == 0 ) return packFloatx80( 0, 0, 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197)         normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199)     zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200)     zSig0 = estimateSqrt32( aExp, aSig0>>32 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201)     zSig0 <<= 31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202)     aSig1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203)     shift128Right( aSig0, 0, ( aExp & 1 ) + 2, &aSig0, &aSig1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204)     zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0 ) + zSig0 + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205)     if ( 0 <= (sbits64) zSig0 ) zSig0 = LIT64( 0xFFFFFFFFFFFFFFFF );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206)     shortShift128Left( aSig0, aSig1, 2, &aSig0, &aSig1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207)     mul64To128( zSig0, zSig0, &term0, &term1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208)     sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209)     while ( (sbits64) rem0 < 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210)         --zSig0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211)         shortShift128Left( 0, zSig0, 1, &term0, &term1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212)         term1 |= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213)         add128( rem0, rem1, term0, term1, &rem0, &rem1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215)     shortShift128Left( rem0, rem1, 63, &shiftedRem0, &shiftedRem1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216)     zSig1 = estimateDiv128To64( shiftedRem0, shiftedRem1, zSig0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217)     if ( (bits64) ( zSig1<<1 ) <= 10 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218)         if ( zSig1 == 0 ) zSig1 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219)         mul64To128( zSig0, zSig1, &term1, &term2 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220)         shortShift128Left( term1, term2, 1, &term1, &term2 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221)         sub128( rem1, 0, term1, term2, &rem1, &rem2 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222)         mul64To128( zSig1, zSig1, &term2, &term3 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223)         sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224)         while ( (sbits64) rem1 < 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225)             --zSig1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226)             shortShift192Left( 0, zSig0, zSig1, 1, &term1, &term2, &term3 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227)             term3 |= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228)             add192(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229)                 rem1, rem2, rem3, term1, term2, term3, &rem1, &rem2, &rem3 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231)         zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233)     return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234)         roundAndPackFloatx80(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235)             roundData, 0, zExp, zSig0, zSig1 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) Returns 1 if the extended double-precision floating-point value `a' is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) equal to the corresponding value `b', and 0 otherwise.  The comparison is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) performed according to the IEC/IEEE Standard for Binary Floating-point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) flag floatx80_eq( floatx80 a, floatx80 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250)     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251)               && (bits64) ( extractFloatx80Frac( a )<<1 ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252)          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253)               && (bits64) ( extractFloatx80Frac( b )<<1 ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254)        ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255)         if (    floatx80_is_signaling_nan( a )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256)              || floatx80_is_signaling_nan( b ) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257)             float_raise( float_flag_invalid );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258)         }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259)         return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261)     return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262)            ( a.low == b.low )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263)         && (    ( a.high == b.high )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264)              || (    ( a.low == 0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265)                   && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266)            );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) Returns 1 if the extended double-precision floating-point value `a' is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) less than or equal to the corresponding value `b', and 0 otherwise.  The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) comparison is performed according to the IEC/IEEE Standard for Binary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) flag floatx80_le( floatx80 a, floatx80 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280)     flag aSign, bSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282)     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283)               && (bits64) ( extractFloatx80Frac( a )<<1 ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284)          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285)               && (bits64) ( extractFloatx80Frac( b )<<1 ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286)        ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287)         float_raise( float_flag_invalid );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288)         return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290)     aSign = extractFloatx80Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291)     bSign = extractFloatx80Sign( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292)     if ( aSign != bSign ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293)         return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294)                aSign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295)             || (    ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296)                  == 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298)     return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299)           aSign ? le128( b.high, b.low, a.high, a.low )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300)         : le128( a.high, a.low, b.high, b.low );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) Returns 1 if the extended double-precision floating-point value `a' is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) less than the corresponding value `b', and 0 otherwise.  The comparison
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) is performed according to the IEC/IEEE Standard for Binary Floating-point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) flag floatx80_lt( floatx80 a, floatx80 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314)     flag aSign, bSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316)     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317)               && (bits64) ( extractFloatx80Frac( a )<<1 ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318)          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319)               && (bits64) ( extractFloatx80Frac( b )<<1 ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320)        ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321)         float_raise( float_flag_invalid );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322)         return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324)     aSign = extractFloatx80Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325)     bSign = extractFloatx80Sign( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326)     if ( aSign != bSign ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327)         return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328)                aSign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329)             && (    ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330)                  != 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332)     return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333)           aSign ? lt128( b.high, b.low, a.high, a.low )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334)         : lt128( a.high, a.low, b.high, b.low );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) Returns 1 if the extended double-precision floating-point value `a' is equal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) to the corresponding value `b', and 0 otherwise.  The invalid exception is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) raised if either operand is a NaN.  Otherwise, the comparison is performed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) flag floatx80_eq_signaling( floatx80 a, floatx80 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349)     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350)               && (bits64) ( extractFloatx80Frac( a )<<1 ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351)          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352)               && (bits64) ( extractFloatx80Frac( b )<<1 ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353)        ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354)         float_raise( float_flag_invalid );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355)         return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357)     return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358)            ( a.low == b.low )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359)         && (    ( a.high == b.high )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360)              || (    ( a.low == 0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361)                   && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362)            );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) Returns 1 if the extended double-precision floating-point value `a' is less
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) than or equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) do not cause an exception.  Otherwise, the comparison is performed according
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) flag floatx80_le_quiet( floatx80 a, floatx80 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376)     flag aSign, bSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378)     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379)               && (bits64) ( extractFloatx80Frac( a )<<1 ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380)          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381)               && (bits64) ( extractFloatx80Frac( b )<<1 ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382)        ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383)         /* Do nothing, even if NaN as we're quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384)         return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386)     aSign = extractFloatx80Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387)     bSign = extractFloatx80Sign( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388)     if ( aSign != bSign ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389)         return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390)                aSign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391)             || (    ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392)                  == 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394)     return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395)           aSign ? le128( b.high, b.low, a.high, a.low )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396)         : le128( a.high, a.low, b.high, b.low );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) Returns 1 if the extended double-precision floating-point value `a' is less
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) than the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) an exception.  Otherwise, the comparison is performed according to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) IEC/IEEE Standard for Binary Floating-point Arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) -------------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) flag floatx80_lt_quiet( floatx80 a, floatx80 b )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410)     flag aSign, bSign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412)     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413)               && (bits64) ( extractFloatx80Frac( a )<<1 ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414)          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415)               && (bits64) ( extractFloatx80Frac( b )<<1 ) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416)        ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417)         /* Do nothing, even if NaN as we're quiet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418)         return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420)     aSign = extractFloatx80Sign( a );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421)     bSign = extractFloatx80Sign( b );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422)     if ( aSign != bSign ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423)         return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424)                aSign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425)             && (    ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426)                  != 0 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428)     return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429)           aSign ? lt128( b.high, b.low, a.high, a.low )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430)         : lt128( a.high, a.low, b.high, b.low );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435)