1bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner/*
2bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner * QEMU float support
3bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner *
4bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner * Derived from SoftFloat.
5bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner */
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*============================================================================
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectThis C source file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectPackage, Release 2b.
118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectWritten by John R. Hauser.  This work was made possible in part by the
138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectInternational Computer Science Institute, located at Suite 600, 1947 Center
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectStreet, Berkeley, California 94704.  Funding was partially provided by the
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectNational Science Foundation under grant MIP-9311980.  The original version
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectof this code was written as part of a project to build a fixed-point vector
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectprocessor in collaboration with the University of California at Berkeley,
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectoverseen by Profs. Nelson Morgan and John Wawrzynek.  More information
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectis available through the Web page `http://www.cs.berkeley.edu/~jhauser/
208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectarithmetic/SoftFloat.html'.
218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectTHIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort has
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectbeen made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectRESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectAND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectCOSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectEFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectINSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectOTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectDerivative works are acceptable, even for commercial purposes, so long as
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project(1) the source code for the derivative work includes prominent notice that
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectthe work is derivative, and (2) the source code includes prominent notice with
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectthese four paragraphs for those parts of this code that are retained.
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project=============================================================================*/
378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "softfloat.h"
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Primitive arithmetic functions, including multi-word arithmetic, and
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| division and square root approximations.  (Can be specialized to target if
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| desired.)
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "softfloat-macros.h"
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Functions and definitions to determine:  (1) whether tininess for underflow
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| is detected before or after rounding by default, (2) what (if anything)
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| happens when exceptions are raised, (3) how signaling NaNs are distinguished
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| are propagated from function inputs to output.  These details are target-
538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| specific.
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "softfloat-specialize.h"
568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid set_float_rounding_mode(int val STATUS_PARAM)
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    STATUS(float_rounding_mode) = val;
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid set_float_exception_flags(int val STATUS_PARAM)
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    STATUS(float_exception_flags) = val;
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef FLOATX80
688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid set_floatx80_rounding_precision(int val STATUS_PARAM)
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    STATUS(floatx80_rounding_precision) = val;
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
75bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| Returns the fraction bits of the half-precision floating-point value `a'.
76bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner*----------------------------------------------------------------------------*/
77bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
78bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' TurnerINLINE uint32_t extractFloat16Frac(float16 a)
79bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner{
80bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    return float16_val(a) & 0x3ff;
81bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner}
82bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
83bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner/*----------------------------------------------------------------------------
84bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| Returns the exponent bits of the half-precision floating-point value `a'.
85bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner*----------------------------------------------------------------------------*/
86bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
87bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' TurnerINLINE int16 extractFloat16Exp(float16 a)
88bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner{
89bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    return (float16_val(a) >> 10) & 0x1f;
90bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner}
91bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
92bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner/*----------------------------------------------------------------------------
93bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| Returns the sign bit of the single-precision floating-point value `a'.
94bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner*----------------------------------------------------------------------------*/
95bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
96bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' TurnerINLINE flag extractFloat16Sign(float16 a)
97bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner{
98bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    return float16_val(a)>>15;
99bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner}
100bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
101bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner/*----------------------------------------------------------------------------
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Takes a 64-bit fixed-point value `absZ' with binary point between bits 6
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| and 7, and returns the properly rounded 32-bit integer corresponding to the
1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| input.  If `zSign' is 1, the input is negated before being converted to an
1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| integer.  Bit 63 of `absZ' must be zero.  Ordinarily, the fixed-point input
1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| is simply rounded to an integer, with the inexact exception raised if the
1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| input cannot be represented exactly as an integer.  However, if the fixed-
1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| point input is too large, the invalid exception is raised and the largest
1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| positive or negative integer is returned.
1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
112bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turnerstatic int32 roundAndPackInt32( flag zSign, uint64_t absZ STATUS_PARAM)
1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8 roundingMode;
1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag roundNearestEven;
1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8 roundIncrement, roundBits;
1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 z;
1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    roundingMode = STATUS(float_rounding_mode);
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    roundNearestEven = ( roundingMode == float_round_nearest_even );
1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    roundIncrement = 0x40;
1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( ! roundNearestEven ) {
1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( roundingMode == float_round_to_zero ) {
1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            roundIncrement = 0;
1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else {
1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            roundIncrement = 0x7F;
1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( zSign ) {
1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if ( roundingMode == float_round_up ) roundIncrement = 0;
1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else {
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if ( roundingMode == float_round_down ) roundIncrement = 0;
1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    roundBits = absZ & 0x7F;
1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    absZ = ( absZ + roundIncrement )>>7;
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    absZ &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    z = absZ;
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( zSign ) z = - z;
1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) {
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
143bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        return zSign ? (int32_t) 0x80000000 : 0x7FFFFFFF;
1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return z;
1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and
1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `absZ1', with binary point between bits 63 and 64 (between the input words),
1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| and returns the properly rounded 64-bit integer corresponding to the input.
1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| If `zSign' is 1, the input is negated before being converted to an integer.
1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Ordinarily, the fixed-point input is simply rounded to an integer, with
1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| the inexact exception raised if the input cannot be represented exactly as
1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| an integer.  However, if the fixed-point input is too large, the invalid
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| exception is raised and the largest positive or negative integer is
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| returned.
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
162bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turnerstatic int64 roundAndPackInt64( flag zSign, uint64_t absZ0, uint64_t absZ1 STATUS_PARAM)
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8 roundingMode;
1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag roundNearestEven, increment;
1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64 z;
1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    roundingMode = STATUS(float_rounding_mode);
1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    roundNearestEven = ( roundingMode == float_round_nearest_even );
170bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    increment = ( (int64_t) absZ1 < 0 );
1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( ! roundNearestEven ) {
1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( roundingMode == float_round_to_zero ) {
1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            increment = 0;
1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else {
1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( zSign ) {
1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                increment = ( roundingMode == float_round_down ) && absZ1;
1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else {
1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                increment = ( roundingMode == float_round_up ) && absZ1;
1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( increment ) {
1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ++absZ0;
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( absZ0 == 0 ) goto overflow;
187bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        absZ0 &= ~ ( ( (uint64_t) ( absZ1<<1 ) == 0 ) & roundNearestEven );
1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    z = absZ0;
1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( zSign ) z = - z;
1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( z && ( ( z < 0 ) ^ zSign ) ) {
1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project overflow:
1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return
195bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner              zSign ? (int64_t) LIT64( 0x8000000000000000 )
1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            : LIT64( 0x7FFFFFFFFFFFFFFF );
1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( absZ1 ) STATUS(float_exception_flags) |= float_flag_inexact;
1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return z;
2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the fraction bits of the single-precision floating-point value `a'.
2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
207bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' TurnerINLINE uint32_t extractFloat32Frac( float32 a )
2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return float32_val(a) & 0x007FFFFF;
2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the exponent bits of the single-precision floating-point value `a'.
2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectINLINE int16 extractFloat32Exp( float32 a )
2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ( float32_val(a)>>23 ) & 0xFF;
2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the sign bit of the single-precision floating-point value `a'.
2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectINLINE flag extractFloat32Sign( float32 a )
2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return float32_val(a)>>31;
2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
237bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| If `a' is denormal and we are in flush-to-zero mode then set the
238bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| input-denormal exception and return zero. Otherwise just return the value.
239bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner*----------------------------------------------------------------------------*/
240bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turnerstatic float32 float32_squash_input_denormal(float32 a STATUS_PARAM)
241bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner{
242bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if (STATUS(flush_inputs_to_zero)) {
243bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if (extractFloat32Exp(a) == 0 && extractFloat32Frac(a) != 0) {
244bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            float_raise(float_flag_input_denormal STATUS_VAR);
245bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            return make_float32(float32_val(a) & 0x80000000);
246bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        }
247bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    }
248bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    return a;
249bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner}
250bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
251bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner/*----------------------------------------------------------------------------
2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Normalizes the subnormal single-precision floating-point value represented
2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| by the denormalized significand `aSig'.  The normalized exponent and
2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| significand are stored at the locations pointed to by `zExpPtr' and
2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `zSigPtr', respectively.
2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
259bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner normalizeFloat32Subnormal( uint32_t aSig, int16 *zExpPtr, uint32_t *zSigPtr )
2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8 shiftCount;
2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shiftCount = countLeadingZeros32( aSig ) - 8;
2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *zSigPtr = aSig<<shiftCount;
2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *zExpPtr = 1 - shiftCount;
2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| single-precision floating-point value, returning the result.  After being
2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| shifted into the proper positions, the three fields are simply added
2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| together to form the result.  This means that any integer portion of `zSig'
2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| will be added into the exponent.  Since a properly normalized significand
2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| will have an integer portion equal to 1, the `zExp' input should be 1 less
2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| than the desired result exponent whenever `zSig' is a complete, normalized
2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| significand.
2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
280bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' TurnerINLINE float32 packFloat32( flag zSign, int16 zExp, uint32_t zSig )
2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return make_float32(
284bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner          ( ( (uint32_t) zSign )<<31 ) + ( ( (uint32_t) zExp )<<23 ) + zSig);
2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| and significand `zSig', and returns the proper single-precision floating-
2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| point value corresponding to the abstract input.  Ordinarily, the abstract
2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| value is simply rounded and packed into the single-precision format, with
2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| the inexact exception raised if the abstract input cannot be represented
2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| exactly.  However, if the abstract value is too large, the overflow and
2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| inexact exceptions are raised and an infinity or maximal finite value is
2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| returned.  If the abstract value is too small, the input value is rounded to
2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| a subnormal number, and the underflow and inexact exceptions are raised if
2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| the abstract input cannot be represented exactly as a subnormal single-
2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| precision floating-point number.
3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project|     The input significand `zSig' has its binary point between bits 30
3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| and 29, which is 7 bits to the left of the usual location.  This shifted
3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| significand must be normalized or smaller.  If `zSig' is not normalized,
3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `zExp' must be 0; in that case, the result returned is a subnormal number,
3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| and it must not require rounding.  In the usual case that `zSig' is
3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| The handling of underflow and overflow follows the IEC/IEEE Standard for
3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Binary Floating-Point Arithmetic.
3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
310bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turnerstatic float32 roundAndPackFloat32( flag zSign, int16 zExp, uint32_t zSig STATUS_PARAM)
3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8 roundingMode;
3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag roundNearestEven;
3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8 roundIncrement, roundBits;
3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag isTiny;
3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    roundingMode = STATUS(float_rounding_mode);
3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    roundNearestEven = ( roundingMode == float_round_nearest_even );
3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    roundIncrement = 0x40;
3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( ! roundNearestEven ) {
3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( roundingMode == float_round_to_zero ) {
3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            roundIncrement = 0;
3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else {
3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            roundIncrement = 0x7F;
3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( zSign ) {
3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if ( roundingMode == float_round_up ) roundIncrement = 0;
3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else {
3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if ( roundingMode == float_round_down ) roundIncrement = 0;
3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    roundBits = zSig & 0x7F;
335bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( 0xFD <= (uint16_t) zExp ) {
3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (    ( 0xFD < zExp )
3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             || (    ( zExp == 0xFD )
338bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner                  && ( (int32_t) ( zSig + roundIncrement ) < 0 ) )
3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           ) {
3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return packFloat32( zSign, 0xFF, - ( roundIncrement == 0 ));
3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( zExp < 0 ) {
3445285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            if (STATUS(flush_to_zero)) {
3455285864985be9077e58e42235af6582dee72e841David 'Digit' Turner                float_raise(float_flag_output_denormal STATUS_VAR);
3465285864985be9077e58e42235af6582dee72e841David 'Digit' Turner                return packFloat32(zSign, 0, 0);
3475285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            }
3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            isTiny =
3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                || ( zExp < -1 )
3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                || ( zSig + roundIncrement < 0x80000000 );
3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            shift32RightJamming( zSig, - zExp, &zSig );
3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            zExp = 0;
3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            roundBits = zSig & 0x7F;
3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( isTiny && roundBits ) float_raise( float_flag_underflow STATUS_VAR);
3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig = ( zSig + roundIncrement )>>7;
3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( zSig == 0 ) zExp = 0;
3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return packFloat32( zSign, zExp, zSig );
3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| and significand `zSig', and returns the proper single-precision floating-
3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| point value corresponding to the abstract input.  This routine is just like
3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `roundAndPackFloat32' except that `zSig' does not have to be normalized.
3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Bit 31 of `zSig' must be zero, and `zExp' must be 1 less than the ``true''
3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| floating-point exponent.
3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic float32
376bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner normalizeRoundAndPackFloat32( flag zSign, int16 zExp, uint32_t zSig STATUS_PARAM)
3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8 shiftCount;
3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shiftCount = countLeadingZeros32( zSig ) - 1;
3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return roundAndPackFloat32( zSign, zExp - shiftCount, zSig<<shiftCount STATUS_VAR);
3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the fraction bits of the double-precision floating-point value `a'.
3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
389bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' TurnerINLINE uint64_t extractFloat64Frac( float64 a )
3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return float64_val(a) & LIT64( 0x000FFFFFFFFFFFFF );
3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the exponent bits of the double-precision floating-point value `a'.
3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectINLINE int16 extractFloat64Exp( float64 a )
4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ( float64_val(a)>>52 ) & 0x7FF;
4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the sign bit of the double-precision floating-point value `a'.
4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectINLINE flag extractFloat64Sign( float64 a )
4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return float64_val(a)>>63;
4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
419bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| If `a' is denormal and we are in flush-to-zero mode then set the
420bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| input-denormal exception and return zero. Otherwise just return the value.
421bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner*----------------------------------------------------------------------------*/
422bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turnerstatic float64 float64_squash_input_denormal(float64 a STATUS_PARAM)
423bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner{
424bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if (STATUS(flush_inputs_to_zero)) {
425bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if (extractFloat64Exp(a) == 0 && extractFloat64Frac(a) != 0) {
426bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            float_raise(float_flag_input_denormal STATUS_VAR);
427bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            return make_float64(float64_val(a) & (1ULL << 63));
428bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        }
429bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    }
430bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    return a;
431bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner}
432bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
433bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner/*----------------------------------------------------------------------------
4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Normalizes the subnormal double-precision floating-point value represented
4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| by the denormalized significand `aSig'.  The normalized exponent and
4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| significand are stored at the locations pointed to by `zExpPtr' and
4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `zSigPtr', respectively.
4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
441bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner normalizeFloat64Subnormal( uint64_t aSig, int16 *zExpPtr, uint64_t *zSigPtr )
4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8 shiftCount;
4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shiftCount = countLeadingZeros64( aSig ) - 11;
4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *zSigPtr = aSig<<shiftCount;
4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *zExpPtr = 1 - shiftCount;
4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| double-precision floating-point value, returning the result.  After being
4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| shifted into the proper positions, the three fields are simply added
4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| together to form the result.  This means that any integer portion of `zSig'
4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| will be added into the exponent.  Since a properly normalized significand
4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| will have an integer portion equal to 1, the `zExp' input should be 1 less
4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| than the desired result exponent whenever `zSig' is a complete, normalized
4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| significand.
4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
462bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' TurnerINLINE float64 packFloat64( flag zSign, int16 zExp, uint64_t zSig )
4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return make_float64(
466bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        ( ( (uint64_t) zSign )<<63 ) + ( ( (uint64_t) zExp )<<52 ) + zSig);
4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| and significand `zSig', and returns the proper double-precision floating-
4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| point value corresponding to the abstract input.  Ordinarily, the abstract
4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| value is simply rounded and packed into the double-precision format, with
4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| the inexact exception raised if the abstract input cannot be represented
4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| exactly.  However, if the abstract value is too large, the overflow and
4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| inexact exceptions are raised and an infinity or maximal finite value is
4788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| returned.  If the abstract value is too small, the input value is rounded
4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| to a subnormal number, and the underflow and inexact exceptions are raised
4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| if the abstract input cannot be represented exactly as a subnormal double-
4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| precision floating-point number.
4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project|     The input significand `zSig' has its binary point between bits 62
4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| and 61, which is 10 bits to the left of the usual location.  This shifted
4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| significand must be normalized or smaller.  If `zSig' is not normalized,
4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `zExp' must be 0; in that case, the result returned is a subnormal number,
4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| and it must not require rounding.  In the usual case that `zSig' is
4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| The handling of underflow and overflow follows the IEC/IEEE Standard for
4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Binary Floating-Point Arithmetic.
4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
492bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turnerstatic float64 roundAndPackFloat64( flag zSign, int16 zExp, uint64_t zSig STATUS_PARAM)
4938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8 roundingMode;
4958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag roundNearestEven;
4968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 roundIncrement, roundBits;
4978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag isTiny;
4988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    roundingMode = STATUS(float_rounding_mode);
5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    roundNearestEven = ( roundingMode == float_round_nearest_even );
5018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    roundIncrement = 0x200;
5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( ! roundNearestEven ) {
5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( roundingMode == float_round_to_zero ) {
5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            roundIncrement = 0;
5058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else {
5078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            roundIncrement = 0x3FF;
5088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( zSign ) {
5098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if ( roundingMode == float_round_up ) roundIncrement = 0;
5108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
5118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else {
5128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if ( roundingMode == float_round_down ) roundIncrement = 0;
5138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    roundBits = zSig & 0x3FF;
517bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( 0x7FD <= (uint16_t) zExp ) {
5188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (    ( 0x7FD < zExp )
5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             || (    ( zExp == 0x7FD )
520bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner                  && ( (int64_t) ( zSig + roundIncrement ) < 0 ) )
5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           ) {
5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return packFloat64( zSign, 0x7FF, - ( roundIncrement == 0 ));
5248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( zExp < 0 ) {
5265285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            if (STATUS(flush_to_zero)) {
5275285864985be9077e58e42235af6582dee72e841David 'Digit' Turner                float_raise(float_flag_output_denormal STATUS_VAR);
5285285864985be9077e58e42235af6582dee72e841David 'Digit' Turner                return packFloat64(zSign, 0, 0);
5295285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            }
5308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            isTiny =
5318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
5328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                || ( zExp < -1 )
5338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                || ( zSig + roundIncrement < LIT64( 0x8000000000000000 ) );
5348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            shift64RightJamming( zSig, - zExp, &zSig );
5358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            zExp = 0;
5368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            roundBits = zSig & 0x3FF;
5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( isTiny && roundBits ) float_raise( float_flag_underflow STATUS_VAR);
5388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig = ( zSig + roundIncrement )>>10;
5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig &= ~ ( ( ( roundBits ^ 0x200 ) == 0 ) & roundNearestEven );
5438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( zSig == 0 ) zExp = 0;
5448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return packFloat64( zSign, zExp, zSig );
5458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
5498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| and significand `zSig', and returns the proper double-precision floating-
5518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| point value corresponding to the abstract input.  This routine is just like
5528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `roundAndPackFloat64' except that `zSig' does not have to be normalized.
5538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Bit 63 of `zSig' must be zero, and `zExp' must be 1 less than the ``true''
5548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| floating-point exponent.
5558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
5568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic float64
558bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner normalizeRoundAndPackFloat64( flag zSign, int16 zExp, uint64_t zSig STATUS_PARAM)
5598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8 shiftCount;
5618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shiftCount = countLeadingZeros64( zSig ) - 1;
5638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return roundAndPackFloat64( zSign, zExp - shiftCount, zSig<<shiftCount STATUS_VAR);
5648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef FLOATX80
5688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
5708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the fraction bits of the extended double-precision floating-point
5718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| value `a'.
5728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
5738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
574bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' TurnerINLINE uint64_t extractFloatx80Frac( floatx80 a )
5758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return a.low;
5788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
5828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the exponent bits of the extended double-precision floating-point
5838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| value `a'.
5848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
5858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectINLINE int32 extractFloatx80Exp( floatx80 a )
5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return a.high & 0x7FFF;
5908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
5948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the sign bit of the extended double-precision floating-point value
5958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `a'.
5968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectINLINE flag extractFloatx80Sign( floatx80 a )
5998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return a.high>>15;
6028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
6068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Normalizes the subnormal extended double-precision floating-point value
6078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| represented by the denormalized significand `aSig'.  The normalized exponent
6088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| and significand are stored at the locations pointed to by `zExpPtr' and
6098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `zSigPtr', respectively.
6108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
6118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
613bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner normalizeFloatx80Subnormal( uint64_t aSig, int32 *zExpPtr, uint64_t *zSigPtr )
6148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8 shiftCount;
6168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shiftCount = countLeadingZeros64( aSig );
6188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *zSigPtr = aSig<<shiftCount;
6198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *zExpPtr = 1 - shiftCount;
6208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
6248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Packs the sign `zSign', exponent `zExp', and significand `zSig' into an
6258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| extended double-precision floating-point value, returning the result.
6268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
6278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
628bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' TurnerINLINE floatx80 packFloatx80( flag zSign, int32 zExp, uint64_t zSig )
6298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    floatx80 z;
6318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    z.low = zSig;
633bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    z.high = ( ( (uint16_t) zSign )<<15 ) + zExp;
6348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return z;
6358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
6398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
6408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| and extended significand formed by the concatenation of `zSig0' and `zSig1',
6418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| and returns the proper extended double-precision floating-point value
6428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| corresponding to the abstract input.  Ordinarily, the abstract value is
6438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| rounded and packed into the extended double-precision format, with the
6448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| inexact exception raised if the abstract input cannot be represented
6458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| exactly.  However, if the abstract value is too large, the overflow and
6468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| inexact exceptions are raised and an infinity or maximal finite value is
6478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| returned.  If the abstract value is too small, the input value is rounded to
6488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| a subnormal number, and the underflow and inexact exceptions are raised if
6498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| the abstract input cannot be represented exactly as a subnormal extended
6508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| double-precision floating-point number.
6518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project|     If `roundingPrecision' is 32 or 64, the result is rounded to the same
6528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| number of bits as single or double precision, respectively.  Otherwise, the
6538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| result is rounded to the full precision of the extended double-precision
6548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| format.
6558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project|     The input significand must be normalized or smaller.  If the input
6568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| significand is not normalized, `zExp' must be 0; in that case, the result
6578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| returned is a subnormal number, and it must not require rounding.  The
6588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| handling of underflow and overflow follows the IEC/IEEE Standard for Binary
6598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Floating-Point Arithmetic.
6608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
6618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic floatx80
6638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project roundAndPackFloatx80(
664bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner     int8 roundingPrecision, flag zSign, int32 zExp, uint64_t zSig0, uint64_t zSig1
6658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project STATUS_PARAM)
6668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8 roundingMode;
6688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag roundNearestEven, increment, isTiny;
6698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64 roundIncrement, roundMask, roundBits;
6708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    roundingMode = STATUS(float_rounding_mode);
6728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    roundNearestEven = ( roundingMode == float_round_nearest_even );
6738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( roundingPrecision == 80 ) goto precision80;
6748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( roundingPrecision == 64 ) {
6758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        roundIncrement = LIT64( 0x0000000000000400 );
6768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        roundMask = LIT64( 0x00000000000007FF );
6778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else if ( roundingPrecision == 32 ) {
6798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        roundIncrement = LIT64( 0x0000008000000000 );
6808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        roundMask = LIT64( 0x000000FFFFFFFFFF );
6818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
6838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto precision80;
6848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig0 |= ( zSig1 != 0 );
6868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( ! roundNearestEven ) {
6878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( roundingMode == float_round_to_zero ) {
6888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            roundIncrement = 0;
6898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
6908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else {
6918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            roundIncrement = roundMask;
6928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( zSign ) {
6938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if ( roundingMode == float_round_up ) roundIncrement = 0;
6948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
6958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else {
6968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if ( roundingMode == float_round_down ) roundIncrement = 0;
6978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
6988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
6998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    roundBits = zSig0 & roundMask;
701bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( 0x7FFD <= (uint32_t) ( zExp - 1 ) ) {
7028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (    ( 0x7FFE < zExp )
7038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             || ( ( zExp == 0x7FFE ) && ( zSig0 + roundIncrement < zSig0 ) )
7048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           ) {
7058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto overflow;
7068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
7078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( zExp <= 0 ) {
7085285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            if (STATUS(flush_to_zero)) {
7095285864985be9077e58e42235af6582dee72e841David 'Digit' Turner                float_raise(float_flag_output_denormal STATUS_VAR);
7105285864985be9077e58e42235af6582dee72e841David 'Digit' Turner                return packFloatx80(zSign, 0, 0);
7115285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            }
7128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            isTiny =
7138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
7148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                || ( zExp < 0 )
7158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                || ( zSig0 <= zSig0 + roundIncrement );
7168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            shift64RightJamming( zSig0, 1 - zExp, &zSig0 );
7178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            zExp = 0;
7188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            roundBits = zSig0 & roundMask;
7198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( isTiny && roundBits ) float_raise( float_flag_underflow STATUS_VAR);
7208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
7218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            zSig0 += roundIncrement;
722bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            if ( (int64_t) zSig0 < 0 ) zExp = 1;
7238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            roundIncrement = roundMask + 1;
7248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
7258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                roundMask |= roundIncrement;
7268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
7278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            zSig0 &= ~ roundMask;
7288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return packFloatx80( zSign, zExp, zSig0 );
7298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
7308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
7328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig0 += roundIncrement;
7338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( zSig0 < roundIncrement ) {
7348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ++zExp;
7358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSig0 = LIT64( 0x8000000000000000 );
7368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    roundIncrement = roundMask + 1;
7388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
7398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        roundMask |= roundIncrement;
7408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig0 &= ~ roundMask;
7428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( zSig0 == 0 ) zExp = 0;
7438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return packFloatx80( zSign, zExp, zSig0 );
7448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project precision80:
745bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    increment = ( (int64_t) zSig1 < 0 );
7468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( ! roundNearestEven ) {
7478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( roundingMode == float_round_to_zero ) {
7488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            increment = 0;
7498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
7508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else {
7518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( zSign ) {
7528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                increment = ( roundingMode == float_round_down ) && zSig1;
7538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
7548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else {
7558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                increment = ( roundingMode == float_round_up ) && zSig1;
7568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
7578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
7588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
759bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( 0x7FFD <= (uint32_t) ( zExp - 1 ) ) {
7608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (    ( 0x7FFE < zExp )
7618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             || (    ( zExp == 0x7FFE )
7628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  && ( zSig0 == LIT64( 0xFFFFFFFFFFFFFFFF ) )
7638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  && increment
7648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                )
7658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           ) {
7668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            roundMask = 0;
7678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project overflow:
7688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
7698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (    ( roundingMode == float_round_to_zero )
7708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 || ( zSign && ( roundingMode == float_round_up ) )
7718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 || ( ! zSign && ( roundingMode == float_round_down ) )
7728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               ) {
7738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return packFloatx80( zSign, 0x7FFE, ~ roundMask );
7748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
7758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
7768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
7778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( zExp <= 0 ) {
7788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            isTiny =
7798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
7808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                || ( zExp < 0 )
7818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                || ! increment
7828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                || ( zSig0 < LIT64( 0xFFFFFFFFFFFFFFFF ) );
7838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            shift64ExtraRightJamming( zSig0, zSig1, 1 - zExp, &zSig0, &zSig1 );
7848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            zExp = 0;
7858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( isTiny && zSig1 ) float_raise( float_flag_underflow STATUS_VAR);
7868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( zSig1 ) STATUS(float_exception_flags) |= float_flag_inexact;
7878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( roundNearestEven ) {
788bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner                increment = ( (int64_t) zSig1 < 0 );
7898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
7908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else {
7918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if ( zSign ) {
7928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    increment = ( roundingMode == float_round_down ) && zSig1;
7938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
7948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                else {
7958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    increment = ( roundingMode == float_round_up ) && zSig1;
7968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
7978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
7988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( increment ) {
7998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ++zSig0;
8008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                zSig0 &=
801bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner                    ~ ( ( (uint64_t) ( zSig1<<1 ) == 0 ) & roundNearestEven );
802bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner                if ( (int64_t) zSig0 < 0 ) zExp = 1;
8038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
8048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return packFloatx80( zSign, zExp, zSig0 );
8058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
8068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( zSig1 ) STATUS(float_exception_flags) |= float_flag_inexact;
8088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( increment ) {
8098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ++zSig0;
8108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( zSig0 == 0 ) {
8118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ++zExp;
8128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            zSig0 = LIT64( 0x8000000000000000 );
8138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
8148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else {
815bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            zSig0 &= ~ ( ( (uint64_t) ( zSig1<<1 ) == 0 ) & roundNearestEven );
8168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
8178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
8198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( zSig0 == 0 ) zExp = 0;
8208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return packFloatx80( zSign, zExp, zSig0 );
8228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
8268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Takes an abstract floating-point value having sign `zSign', exponent
8278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `zExp', and significand formed by the concatenation of `zSig0' and `zSig1',
8288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| and returns the proper extended double-precision floating-point value
8298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| corresponding to the abstract input.  This routine is just like
8308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `roundAndPackFloatx80' except that the input significand does not have to be
8318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| normalized.
8328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
8338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic floatx80
8358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project normalizeRoundAndPackFloatx80(
836bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner     int8 roundingPrecision, flag zSign, int32 zExp, uint64_t zSig0, uint64_t zSig1
8378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project STATUS_PARAM)
8388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8 shiftCount;
8408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( zSig0 == 0 ) {
8428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSig0 = zSig1;
8438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSig1 = 0;
8448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zExp -= 64;
8458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shiftCount = countLeadingZeros64( zSig0 );
8478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
8488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zExp -= shiftCount;
8498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return
8508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        roundAndPackFloatx80( roundingPrecision, zSign, zExp, zSig0, zSig1 STATUS_VAR);
8518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
8558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef FLOAT128
8578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
8598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the least-significant 64 fraction bits of the quadruple-precision
8608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| floating-point value `a'.
8618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
8628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
863bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' TurnerINLINE uint64_t extractFloat128Frac1( float128 a )
8648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return a.low;
8678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
8718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the most-significant 48 fraction bits of the quadruple-precision
8728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| floating-point value `a'.
8738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
8748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
875bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' TurnerINLINE uint64_t extractFloat128Frac0( float128 a )
8768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return a.high & LIT64( 0x0000FFFFFFFFFFFF );
8798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
8838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the exponent bits of the quadruple-precision floating-point value
8848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `a'.
8858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
8868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectINLINE int32 extractFloat128Exp( float128 a )
8888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ( a.high>>48 ) & 0x7FFF;
8918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
8958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the sign bit of the quadruple-precision floating-point value `a'.
8968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
8978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectINLINE flag extractFloat128Sign( float128 a )
8998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return a.high>>63;
9028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
9068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Normalizes the subnormal quadruple-precision floating-point value
9078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| represented by the denormalized significand formed by the concatenation of
9088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `aSig0' and `aSig1'.  The normalized exponent is stored at the location
9098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| pointed to by `zExpPtr'.  The most significant 49 bits of the normalized
9108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| significand are stored at the location pointed to by `zSig0Ptr', and the
9118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| least significant 64 bits of the normalized significand are stored at the
9128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| location pointed to by `zSig1Ptr'.
9138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
9148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
9168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project normalizeFloat128Subnormal(
917bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner     uint64_t aSig0,
918bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner     uint64_t aSig1,
9198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     int32 *zExpPtr,
920bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner     uint64_t *zSig0Ptr,
921bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner     uint64_t *zSig1Ptr
9228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project )
9238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8 shiftCount;
9258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSig0 == 0 ) {
9278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shiftCount = countLeadingZeros64( aSig1 ) - 15;
9288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( shiftCount < 0 ) {
9298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            *zSig0Ptr = aSig1>>( - shiftCount );
9308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            *zSig1Ptr = aSig1<<( shiftCount & 63 );
9318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
9328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else {
9338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            *zSig0Ptr = aSig1<<shiftCount;
9348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            *zSig1Ptr = 0;
9358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
9368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        *zExpPtr = - shiftCount - 63;
9378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
9398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shiftCount = countLeadingZeros64( aSig0 ) - 15;
9408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shortShift128Left( aSig0, aSig1, shiftCount, zSig0Ptr, zSig1Ptr );
9418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        *zExpPtr = 1 - shiftCount;
9428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
9478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Packs the sign `zSign', the exponent `zExp', and the significand formed
9488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| by the concatenation of `zSig0' and `zSig1' into a quadruple-precision
9498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| floating-point value, returning the result.  After being shifted into the
9508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| proper positions, the three fields `zSign', `zExp', and `zSig0' are simply
9518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| added together to form the most significant 32 bits of the result.  This
9528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| means that any integer portion of `zSig0' will be added into the exponent.
9538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Since a properly normalized significand will have an integer portion equal
9548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| to 1, the `zExp' input should be 1 less than the desired result exponent
9558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| whenever `zSig0' and `zSig1' concatenated form a complete, normalized
9568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| significand.
9578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
9588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectINLINE float128
960bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner packFloat128( flag zSign, int32 zExp, uint64_t zSig0, uint64_t zSig1 )
9618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    float128 z;
9638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    z.low = zSig1;
965bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    z.high = ( ( (uint64_t) zSign )<<63 ) + ( ( (uint64_t) zExp )<<48 ) + zSig0;
9668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return z;
9678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
9718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
9728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| and extended significand formed by the concatenation of `zSig0', `zSig1',
9738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| and `zSig2', and returns the proper quadruple-precision floating-point value
9748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| corresponding to the abstract input.  Ordinarily, the abstract value is
9758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| simply rounded and packed into the quadruple-precision format, with the
9768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| inexact exception raised if the abstract input cannot be represented
9778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| exactly.  However, if the abstract value is too large, the overflow and
9788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| inexact exceptions are raised and an infinity or maximal finite value is
9798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| returned.  If the abstract value is too small, the input value is rounded to
9808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| a subnormal number, and the underflow and inexact exceptions are raised if
9818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| the abstract input cannot be represented exactly as a subnormal quadruple-
9828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| precision floating-point number.
9838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project|     The input significand must be normalized or smaller.  If the input
9848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| significand is not normalized, `zExp' must be 0; in that case, the result
9858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| returned is a subnormal number, and it must not require rounding.  In the
9868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| usual case that the input significand is normalized, `zExp' must be 1 less
9878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| than the ``true'' floating-point exponent.  The handling of underflow and
9888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| overflow follows the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
9898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
9908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic float128
9928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project roundAndPackFloat128(
993bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner     flag zSign, int32 zExp, uint64_t zSig0, uint64_t zSig1, uint64_t zSig2 STATUS_PARAM)
9948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8 roundingMode;
9968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag roundNearestEven, increment, isTiny;
9978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    roundingMode = STATUS(float_rounding_mode);
9998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    roundNearestEven = ( roundingMode == float_round_nearest_even );
1000bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    increment = ( (int64_t) zSig2 < 0 );
10018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( ! roundNearestEven ) {
10028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( roundingMode == float_round_to_zero ) {
10038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            increment = 0;
10048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
10058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else {
10068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( zSign ) {
10078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                increment = ( roundingMode == float_round_down ) && zSig2;
10088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
10098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else {
10108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                increment = ( roundingMode == float_round_up ) && zSig2;
10118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
10128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
10138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1014bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( 0x7FFD <= (uint32_t) zExp ) {
10158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (    ( 0x7FFD < zExp )
10168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             || (    ( zExp == 0x7FFD )
10178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  && eq128(
10188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                         LIT64( 0x0001FFFFFFFFFFFF ),
10198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                         LIT64( 0xFFFFFFFFFFFFFFFF ),
10208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                         zSig0,
10218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                         zSig1
10228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     )
10238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  && increment
10248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                )
10258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           ) {
10268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
10278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (    ( roundingMode == float_round_to_zero )
10288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 || ( zSign && ( roundingMode == float_round_up ) )
10298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 || ( ! zSign && ( roundingMode == float_round_down ) )
10308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               ) {
10318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return
10328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    packFloat128(
10338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        zSign,
10348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        0x7FFE,
10358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        LIT64( 0x0000FFFFFFFFFFFF ),
10368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        LIT64( 0xFFFFFFFFFFFFFFFF )
10378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    );
10388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
10398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return packFloat128( zSign, 0x7FFF, 0, 0 );
10408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
10418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( zExp < 0 ) {
10425285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            if (STATUS(flush_to_zero)) {
10435285864985be9077e58e42235af6582dee72e841David 'Digit' Turner                float_raise(float_flag_output_denormal STATUS_VAR);
10445285864985be9077e58e42235af6582dee72e841David 'Digit' Turner                return packFloat128(zSign, 0, 0, 0);
10455285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            }
10468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            isTiny =
10478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
10488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                || ( zExp < -1 )
10498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                || ! increment
10508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                || lt128(
10518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       zSig0,
10528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       zSig1,
10538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       LIT64( 0x0001FFFFFFFFFFFF ),
10548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       LIT64( 0xFFFFFFFFFFFFFFFF )
10558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   );
10568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            shift128ExtraRightJamming(
10578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                zSig0, zSig1, zSig2, - zExp, &zSig0, &zSig1, &zSig2 );
10588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            zExp = 0;
10598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( isTiny && zSig2 ) float_raise( float_flag_underflow STATUS_VAR);
10608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( roundNearestEven ) {
1061bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner                increment = ( (int64_t) zSig2 < 0 );
10628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
10638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else {
10648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if ( zSign ) {
10658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    increment = ( roundingMode == float_round_down ) && zSig2;
10668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
10678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                else {
10688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    increment = ( roundingMode == float_round_up ) && zSig2;
10698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
10708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
10718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
10728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( zSig2 ) STATUS(float_exception_flags) |= float_flag_inexact;
10748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( increment ) {
10758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        add128( zSig0, zSig1, 0, 1, &zSig0, &zSig1 );
10768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSig1 &= ~ ( ( zSig2 + zSig2 == 0 ) & roundNearestEven );
10778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
10798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ( zSig0 | zSig1 ) == 0 ) zExp = 0;
10808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return packFloat128( zSign, zExp, zSig0, zSig1 );
10828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
10868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
10878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| and significand formed by the concatenation of `zSig0' and `zSig1', and
10888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| returns the proper quadruple-precision floating-point value corresponding
10898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| to the abstract input.  This routine is just like `roundAndPackFloat128'
10908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| except that the input significand has fewer bits and does not have to be
10918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| normalized.  In all cases, `zExp' must be 1 less than the ``true'' floating-
10928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| point exponent.
10938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
10948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic float128
10968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project normalizeRoundAndPackFloat128(
1097bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner     flag zSign, int32 zExp, uint64_t zSig0, uint64_t zSig1 STATUS_PARAM)
10988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
10998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8 shiftCount;
1100bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t zSig2;
11018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( zSig0 == 0 ) {
11038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSig0 = zSig1;
11048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSig1 = 0;
11058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zExp -= 64;
11068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
11078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shiftCount = countLeadingZeros64( zSig0 ) - 15;
11088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( 0 <= shiftCount ) {
11098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSig2 = 0;
11108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
11118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
11128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
11138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shift128ExtraRightJamming(
11148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            zSig0, zSig1, 0, - shiftCount, &zSig0, &zSig1, &zSig2 );
11158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
11168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zExp -= shiftCount;
11178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 STATUS_VAR);
11188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
11228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
11248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the 32-bit two's complement integer `a'
11258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| to the single-precision floating-point format.  The conversion is performed
11268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
11278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
11288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 int32_to_float32( int32 a STATUS_PARAM )
11308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag zSign;
11328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( a == 0 ) return float32_zero;
1134bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( a == (int32_t) 0x80000000 ) return packFloat32( 1, 0x9E, 0 );
11358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSign = ( a < 0 );
11368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return normalizeRoundAndPackFloat32( zSign, 0x9C, zSign ? - a : a STATUS_VAR );
11378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
11418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the 32-bit two's complement integer `a'
11428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| to the double-precision floating-point format.  The conversion is performed
11438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
11448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
11458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat64 int32_to_float64( int32 a STATUS_PARAM )
11478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag zSign;
11498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32 absA;
11508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8 shiftCount;
1151bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t zSig;
11528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( a == 0 ) return float64_zero;
11548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSign = ( a < 0 );
11558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    absA = zSign ? - a : a;
11568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shiftCount = countLeadingZeros32( absA ) + 21;
11578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig = absA;
11588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return packFloat64( zSign, 0x432 - shiftCount, zSig<<shiftCount );
11598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef FLOATX80
11638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
11658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the 32-bit two's complement integer `a'
11668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| to the extended double-precision floating-point format.  The conversion
11678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| is performed according to the IEC/IEEE Standard for Binary Floating-Point
11688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Arithmetic.
11698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
11708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloatx80 int32_to_floatx80( int32 a STATUS_PARAM )
11728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag zSign;
11748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32 absA;
11758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8 shiftCount;
1176bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t zSig;
11778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( a == 0 ) return packFloatx80( 0, 0, 0 );
11798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSign = ( a < 0 );
11808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    absA = zSign ? - a : a;
11818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shiftCount = countLeadingZeros32( absA ) + 32;
11828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig = absA;
11838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return packFloatx80( zSign, 0x403E - shiftCount, zSig<<shiftCount );
11848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
11888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef FLOAT128
11908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
11928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the 32-bit two's complement integer `a' to
11938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| the quadruple-precision floating-point format.  The conversion is performed
11948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
11958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
11968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat128 int32_to_float128( int32 a STATUS_PARAM )
11988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag zSign;
12008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32 absA;
12018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8 shiftCount;
1202bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t zSig0;
12038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( a == 0 ) return packFloat128( 0, 0, 0, 0 );
12058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSign = ( a < 0 );
12068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    absA = zSign ? - a : a;
12078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shiftCount = countLeadingZeros32( absA ) + 17;
12088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig0 = absA;
12098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return packFloat128( zSign, 0x402E - shiftCount, zSig0<<shiftCount, 0 );
12108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
12148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
12168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the 64-bit two's complement integer `a'
12178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| to the single-precision floating-point format.  The conversion is performed
12188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
12198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
12208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 int64_to_float32( int64 a STATUS_PARAM )
12228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag zSign;
12248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64 absA;
12258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8 shiftCount;
12268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( a == 0 ) return float32_zero;
12288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSign = ( a < 0 );
12298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    absA = zSign ? - a : a;
12308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shiftCount = countLeadingZeros64( absA ) - 40;
12318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( 0 <= shiftCount ) {
12328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloat32( zSign, 0x95 - shiftCount, absA<<shiftCount );
12338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
12358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shiftCount += 7;
12368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( shiftCount < 0 ) {
12378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            shift64RightJamming( absA, - shiftCount, &absA );
12388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
12398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else {
12408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            absA <<= shiftCount;
12418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
12428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return roundAndPackFloat32( zSign, 0x9C - shiftCount, absA STATUS_VAR );
12438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 uint64_to_float32( uint64 a STATUS_PARAM )
12488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8 shiftCount;
12508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( a == 0 ) return float32_zero;
12528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shiftCount = countLeadingZeros64( a ) - 40;
12538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( 0 <= shiftCount ) {
12548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloat32( 1 > 0, 0x95 - shiftCount, a<<shiftCount );
12558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
12578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shiftCount += 7;
12588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( shiftCount < 0 ) {
12598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            shift64RightJamming( a, - shiftCount, &a );
12608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
12618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else {
12628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            a <<= shiftCount;
12638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
12648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return roundAndPackFloat32( 1 > 0, 0x9C - shiftCount, a STATUS_VAR );
12658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
12698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the 64-bit two's complement integer `a'
12708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| to the double-precision floating-point format.  The conversion is performed
12718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
12728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
12738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat64 int64_to_float64( int64 a STATUS_PARAM )
12758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag zSign;
12778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( a == 0 ) return float64_zero;
1279bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( a == (int64_t) LIT64( 0x8000000000000000 ) ) {
12808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloat64( 1, 0x43E, 0 );
12818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSign = ( a < 0 );
12838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return normalizeRoundAndPackFloat64( zSign, 0x43C, zSign ? - a : a STATUS_VAR );
12848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat64 uint64_to_float64( uint64 a STATUS_PARAM )
12888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( a == 0 ) return float64_zero;
12908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return normalizeRoundAndPackFloat64( 0, 0x43C, a STATUS_VAR );
12918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef FLOATX80
12958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
12978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the 64-bit two's complement integer `a'
12988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| to the extended double-precision floating-point format.  The conversion
12998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| is performed according to the IEC/IEEE Standard for Binary Floating-Point
13008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Arithmetic.
13018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
13028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloatx80 int64_to_floatx80( int64 a STATUS_PARAM )
13048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag zSign;
13068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64 absA;
13078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8 shiftCount;
13088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( a == 0 ) return packFloatx80( 0, 0, 0 );
13108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSign = ( a < 0 );
13118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    absA = zSign ? - a : a;
13128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shiftCount = countLeadingZeros64( absA );
13138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return packFloatx80( zSign, 0x403E - shiftCount, absA<<shiftCount );
13148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
13188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef FLOAT128
13208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
13228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the 64-bit two's complement integer `a' to
13238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| the quadruple-precision floating-point format.  The conversion is performed
13248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
13258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
13268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat128 int64_to_float128( int64 a STATUS_PARAM )
13288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag zSign;
13308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64 absA;
13318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8 shiftCount;
13328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 zExp;
1333bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t zSig0, zSig1;
13348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( a == 0 ) return packFloat128( 0, 0, 0, 0 );
13368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSign = ( a < 0 );
13378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    absA = zSign ? - a : a;
13388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shiftCount = countLeadingZeros64( absA ) + 49;
13398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zExp = 0x406E - shiftCount;
13408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( 64 <= shiftCount ) {
13418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSig1 = 0;
13428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSig0 = absA;
13438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shiftCount -= 64;
13448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
13468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSig1 = absA;
13478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSig0 = 0;
13488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
13508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return packFloat128( zSign, zExp, zSig0, zSig1 );
13518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
13558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
13578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the single-precision floating-point value
13588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `a' to the 32-bit two's complement integer format.  The conversion is
13598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| performed according to the IEC/IEEE Standard for Binary Floating-Point
13608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Arithmetic---which means in particular that the conversion is rounded
13618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| according to the current rounding mode.  If `a' is a NaN, the largest
13628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| positive integer is returned.  Otherwise, if the conversion overflows, the
13638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| largest integer with the same sign as `a' is returned.
13648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
13658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint32 float32_to_int32( float32 a STATUS_PARAM )
13678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
13698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 aExp, shiftCount;
1370bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t aSig;
1371bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig64;
13728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1373bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float32_squash_input_denormal(a STATUS_VAR);
13748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloat32Frac( a );
13758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat32Exp( a );
13768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat32Sign( a );
13778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( ( aExp == 0xFF ) && aSig ) aSign = 0;
13788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp ) aSig |= 0x00800000;
13798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shiftCount = 0xAF - aExp;
13808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig64 = aSig;
13818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig64 <<= 32;
13828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( 0 < shiftCount ) shift64RightJamming( aSig64, shiftCount, &aSig64 );
13838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return roundAndPackInt32( aSign, aSig64 STATUS_VAR );
13848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
13888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the single-precision floating-point value
13898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `a' to the 32-bit two's complement integer format.  The conversion is
13908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| performed according to the IEC/IEEE Standard for Binary Floating-Point
13918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Arithmetic, except that the conversion is always rounded toward zero.
13928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| If `a' is a NaN, the largest positive integer is returned.  Otherwise, if
13938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| the conversion overflows, the largest integer with the same sign as `a' is
13948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| returned.
13958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
13968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint32 float32_to_int32_round_to_zero( float32 a STATUS_PARAM )
13988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
14008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 aExp, shiftCount;
1401bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t aSig;
14028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 z;
1403bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float32_squash_input_denormal(a STATUS_VAR);
14048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloat32Frac( a );
14068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat32Exp( a );
14078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat32Sign( a );
14088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shiftCount = aExp - 0x9E;
14098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( 0 <= shiftCount ) {
14108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( float32_val(a) != 0xCF000000 ) {
14118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_invalid STATUS_VAR);
14128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) return 0x7FFFFFFF;
14138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1414bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        return (int32_t) 0x80000000;
14158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
14168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else if ( aExp <= 0x7E ) {
14178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aExp | aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
14188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
14198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
14208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = ( aSig | 0x00800000 )<<8;
14218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    z = aSig>>( - shiftCount );
1422bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( (uint32_t) ( aSig<<( shiftCount & 31 ) ) ) {
14238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        STATUS(float_exception_flags) |= float_flag_inexact;
14248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
14258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSign ) z = - z;
14268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return z;
14278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
14318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the single-precision floating-point value
1432bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| `a' to the 16-bit two's complement integer format.  The conversion is
1433bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| performed according to the IEC/IEEE Standard for Binary Floating-Point
1434bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| Arithmetic, except that the conversion is always rounded toward zero.
1435bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| If `a' is a NaN, the largest positive integer is returned.  Otherwise, if
1436bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| the conversion overflows, the largest integer with the same sign as `a' is
1437bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| returned.
1438bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner*----------------------------------------------------------------------------*/
1439bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
1440bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turnerint16 float32_to_int16_round_to_zero( float32 a STATUS_PARAM )
1441bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner{
1442bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    flag aSign;
1443bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    int16 aExp, shiftCount;
1444bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t aSig;
1445bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    int32 z;
1446bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
1447bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    aSig = extractFloat32Frac( a );
1448bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    aExp = extractFloat32Exp( a );
1449bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    aSign = extractFloat32Sign( a );
1450bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    shiftCount = aExp - 0x8E;
1451bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( 0 <= shiftCount ) {
1452bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( float32_val(a) != 0xC7000000 ) {
1453bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            float_raise( float_flag_invalid STATUS_VAR);
1454bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) {
1455bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner                return 0x7FFF;
1456bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            }
1457bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        }
1458bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        return (int32_t) 0xffff8000;
1459bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    }
1460bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    else if ( aExp <= 0x7E ) {
1461bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( aExp | aSig ) {
1462bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            STATUS(float_exception_flags) |= float_flag_inexact;
1463bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        }
1464bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        return 0;
1465bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    }
1466bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    shiftCount -= 0x10;
1467bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    aSig = ( aSig | 0x00800000 )<<8;
1468bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    z = aSig>>( - shiftCount );
1469bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( (uint32_t) ( aSig<<( shiftCount & 31 ) ) ) {
1470bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        STATUS(float_exception_flags) |= float_flag_inexact;
1471bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    }
1472bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( aSign ) {
1473bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        z = - z;
1474bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    }
1475bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    return z;
1476bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
1477bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner}
1478bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
1479bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner/*----------------------------------------------------------------------------
1480bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| Returns the result of converting the single-precision floating-point value
14818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `a' to the 64-bit two's complement integer format.  The conversion is
14828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| performed according to the IEC/IEEE Standard for Binary Floating-Point
14838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Arithmetic---which means in particular that the conversion is rounded
14848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| according to the current rounding mode.  If `a' is a NaN, the largest
14858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| positive integer is returned.  Otherwise, if the conversion overflows, the
14868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| largest integer with the same sign as `a' is returned.
14878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
14888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint64 float32_to_int64( float32 a STATUS_PARAM )
14908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
14928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 aExp, shiftCount;
1493bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t aSig;
1494bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig64, aSigExtra;
1495bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float32_squash_input_denormal(a STATUS_VAR);
14968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloat32Frac( a );
14988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat32Exp( a );
14998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat32Sign( a );
15008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shiftCount = 0xBE - aExp;
15018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( shiftCount < 0 ) {
15028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
15038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) {
15048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return LIT64( 0x7FFFFFFFFFFFFFFF );
15058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1506bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        return (int64_t) LIT64( 0x8000000000000000 );
15078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
15088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp ) aSig |= 0x00800000;
15098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig64 = aSig;
15108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig64 <<= 40;
15118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shift64ExtraRightJamming( aSig64, 0, shiftCount, &aSig64, &aSigExtra );
15128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return roundAndPackInt64( aSign, aSig64, aSigExtra STATUS_VAR );
15138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
15158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
15178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the single-precision floating-point value
15188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `a' to the 64-bit two's complement integer format.  The conversion is
15198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| performed according to the IEC/IEEE Standard for Binary Floating-Point
15208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Arithmetic, except that the conversion is always rounded toward zero.  If
15218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `a' is a NaN, the largest positive integer is returned.  Otherwise, if the
15228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| conversion overflows, the largest integer with the same sign as `a' is
15238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| returned.
15248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
15258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint64 float32_to_int64_round_to_zero( float32 a STATUS_PARAM )
15278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
15288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
15298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 aExp, shiftCount;
1530bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t aSig;
1531bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig64;
15328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64 z;
1533bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float32_squash_input_denormal(a STATUS_VAR);
15348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloat32Frac( a );
15368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat32Exp( a );
15378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat32Sign( a );
15388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shiftCount = aExp - 0xBE;
15398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( 0 <= shiftCount ) {
15408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( float32_val(a) != 0xDF000000 ) {
15418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_invalid STATUS_VAR);
15428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) {
15438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return LIT64( 0x7FFFFFFFFFFFFFFF );
15448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
15458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1546bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        return (int64_t) LIT64( 0x8000000000000000 );
15478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
15488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else if ( aExp <= 0x7E ) {
15498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aExp | aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
15508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
15518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
15528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig64 = aSig | 0x00800000;
15538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig64 <<= 40;
15548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    z = aSig64>>( - shiftCount );
1555bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( (uint64_t) ( aSig64<<( shiftCount & 63 ) ) ) {
15568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        STATUS(float_exception_flags) |= float_flag_inexact;
15578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
15588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSign ) z = - z;
15598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return z;
15608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
15628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
15648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the single-precision floating-point value
15658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `a' to the double-precision floating-point format.  The conversion is
15668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| performed according to the IEC/IEEE Standard for Binary Floating-Point
15678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Arithmetic.
15688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
15698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat64 float32_to_float64( float32 a STATUS_PARAM )
15718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
15728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
15738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 aExp;
1574bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t aSig;
1575bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float32_squash_input_denormal(a STATUS_VAR);
15768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloat32Frac( a );
15788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat32Exp( a );
15798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat32Sign( a );
15808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0xFF ) {
1581bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( aSig ) return commonNaNToFloat64( float32ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
15828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloat64( aSign, 0x7FF, 0 );
15838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
15848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0 ) {
15858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig == 0 ) return packFloat64( aSign, 0, 0 );
15868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
15878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        --aExp;
15888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1589bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    return packFloat64( aSign, aExp + 0x380, ( (uint64_t) aSig )<<29 );
15908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
15928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef FLOATX80
15948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
15968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the single-precision floating-point value
15978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `a' to the extended double-precision floating-point format.  The conversion
15988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| is performed according to the IEC/IEEE Standard for Binary Floating-Point
15998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Arithmetic.
16008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
16018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloatx80 float32_to_floatx80( float32 a STATUS_PARAM )
16038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
16048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
16058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 aExp;
1606bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t aSig;
16078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1608bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float32_squash_input_denormal(a STATUS_VAR);
16098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloat32Frac( a );
16108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat32Exp( a );
16118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat32Sign( a );
16128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0xFF ) {
1613bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( aSig ) return commonNaNToFloatx80( float32ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
16148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
16158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
16168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0 ) {
16178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
16188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
16198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
16208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig |= 0x00800000;
1621bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    return packFloatx80( aSign, aExp + 0x3F80, ( (uint64_t) aSig )<<40 );
16228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
16248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
16268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef FLOAT128
16288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
16308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the single-precision floating-point value
16318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `a' to the double-precision floating-point format.  The conversion is
16328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| performed according to the IEC/IEEE Standard for Binary Floating-Point
16338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Arithmetic.
16348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
16358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat128 float32_to_float128( float32 a STATUS_PARAM )
16378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
16388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
16398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 aExp;
1640bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t aSig;
16418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1642bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float32_squash_input_denormal(a STATUS_VAR);
16438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloat32Frac( a );
16448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat32Exp( a );
16458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat32Sign( a );
16468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0xFF ) {
1647bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( aSig ) return commonNaNToFloat128( float32ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
16488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloat128( aSign, 0x7FFF, 0, 0 );
16498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
16508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0 ) {
16518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 );
16528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
16538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        --aExp;
16548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1655bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    return packFloat128( aSign, aExp + 0x3F80, ( (uint64_t) aSig )<<25, 0 );
16568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
16588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
16608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
16628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Rounds the single-precision floating-point value `a' to an integer, and
16638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| returns the result as a single-precision floating-point value.  The
16648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| operation is performed according to the IEC/IEEE Standard for Binary
16658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Floating-Point Arithmetic.
16668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
16678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 float32_round_to_int( float32 a STATUS_PARAM)
16698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
16708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
16718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 aExp;
1672bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t lastBitMask, roundBitsMask;
16738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8 roundingMode;
1674bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t z;
1675bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float32_squash_input_denormal(a STATUS_VAR);
16768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat32Exp( a );
16788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( 0x96 <= aExp ) {
16798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ( aExp == 0xFF ) && extractFloat32Frac( a ) ) {
16808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return propagateFloat32NaN( a, a STATUS_VAR );
16818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
16828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return a;
16838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
16848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp <= 0x7E ) {
1685bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( (uint32_t) ( float32_val(a)<<1 ) == 0 ) return a;
16868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        STATUS(float_exception_flags) |= float_flag_inexact;
16878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSign = extractFloat32Sign( a );
16888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch ( STATUS(float_rounding_mode) ) {
16898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case float_round_nearest_even:
16908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) {
16918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return packFloat32( aSign, 0x7F, 0 );
16928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
16938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
16948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case float_round_down:
16958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return make_float32(aSign ? 0xBF800000 : 0);
16968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case float_round_up:
16978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return make_float32(aSign ? 0x80000000 : 0x3F800000);
16988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
16998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloat32( aSign, 0, 0 );
17008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
17018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    lastBitMask = 1;
17028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    lastBitMask <<= 0x96 - aExp;
17038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    roundBitsMask = lastBitMask - 1;
17048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    z = float32_val(a);
17058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    roundingMode = STATUS(float_rounding_mode);
17068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( roundingMode == float_round_nearest_even ) {
17078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        z += lastBitMask>>1;
17088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
17098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
17108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else if ( roundingMode != float_round_to_zero ) {
17118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( extractFloat32Sign( make_float32(z) ) ^ ( roundingMode == float_round_up ) ) {
17128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            z += roundBitsMask;
17138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
17158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    z &= ~ roundBitsMask;
17168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( z != float32_val(a) ) STATUS(float_exception_flags) |= float_flag_inexact;
17178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return make_float32(z);
17188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
17208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
17228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of adding the absolute values of the single-precision
17238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| floating-point values `a' and `b'.  If `zSign' is 1, the sum is negated
17248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| before being returned.  `zSign' is ignored if the result is a NaN.
17258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| The addition is performed according to the IEC/IEEE Standard for Binary
17268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Floating-Point Arithmetic.
17278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
17288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic float32 addFloat32Sigs( float32 a, float32 b, flag zSign STATUS_PARAM)
17308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
17318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 aExp, bExp, zExp;
1732bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t aSig, bSig, zSig;
17338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 expDiff;
17348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloat32Frac( a );
17368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat32Exp( a );
17378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig = extractFloat32Frac( b );
17388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bExp = extractFloat32Exp( b );
17398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    expDiff = aExp - bExp;
17408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig <<= 6;
17418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig <<= 6;
17428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( 0 < expDiff ) {
17438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aExp == 0xFF ) {
17448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( aSig ) return propagateFloat32NaN( a, b STATUS_VAR );
17458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return a;
17468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bExp == 0 ) {
17488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            --expDiff;
17498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else {
17518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            bSig |= 0x20000000;
17528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shift32RightJamming( bSig, expDiff, &bSig );
17548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zExp = aExp;
17558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
17568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else if ( expDiff < 0 ) {
17578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bExp == 0xFF ) {
17588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
17598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return packFloat32( zSign, 0xFF, 0 );
17608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aExp == 0 ) {
17628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ++expDiff;
17638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else {
17658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            aSig |= 0x20000000;
17668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shift32RightJamming( aSig, - expDiff, &aSig );
17688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zExp = bExp;
17698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
17708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
17718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aExp == 0xFF ) {
17728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( aSig | bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
17738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return a;
17748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if ( aExp == 0 ) {
17765285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            if (STATUS(flush_to_zero)) {
17775285864985be9077e58e42235af6582dee72e841David 'Digit' Turner                if (aSig | bSig) {
17785285864985be9077e58e42235af6582dee72e841David 'Digit' Turner                    float_raise(float_flag_output_denormal STATUS_VAR);
17795285864985be9077e58e42235af6582dee72e841David 'Digit' Turner                }
17805285864985be9077e58e42235af6582dee72e841David 'Digit' Turner                return packFloat32(zSign, 0, 0);
17815285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            }
17825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return packFloat32( zSign, 0, ( aSig + bSig )>>6 );
17835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
17848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSig = 0x40000000 + aSig + bSig;
17858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zExp = aExp;
17868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto roundAndPack;
17878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
17888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig |= 0x20000000;
17898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig = ( aSig + bSig )<<1;
17908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    --zExp;
1791bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( (int32_t) zSig < 0 ) {
17928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSig = aSig + bSig;
17938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ++zExp;
17948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
17958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project roundAndPack:
17968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return roundAndPackFloat32( zSign, zExp, zSig STATUS_VAR );
17978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
17998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
18018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of subtracting the absolute values of the single-
18028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| precision floating-point values `a' and `b'.  If `zSign' is 1, the
18038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| difference is negated before being returned.  `zSign' is ignored if the
18048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| result is a NaN.  The subtraction is performed according to the IEC/IEEE
18058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Standard for Binary Floating-Point Arithmetic.
18068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
18078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic float32 subFloat32Sigs( float32 a, float32 b, flag zSign STATUS_PARAM)
18098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
18108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 aExp, bExp, zExp;
1811bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t aSig, bSig, zSig;
18128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 expDiff;
18138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloat32Frac( a );
18158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat32Exp( a );
18168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig = extractFloat32Frac( b );
18178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bExp = extractFloat32Exp( b );
18188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    expDiff = aExp - bExp;
18198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig <<= 7;
18208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig <<= 7;
18218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( 0 < expDiff ) goto aExpBigger;
18228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( expDiff < 0 ) goto bExpBigger;
18238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0xFF ) {
18248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig | bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
18258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
18268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return float32_default_nan;
18278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
18288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0 ) {
18298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aExp = 1;
18308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        bExp = 1;
18318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
18328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bSig < aSig ) goto aBigger;
18338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSig < bSig ) goto bBigger;
18348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return packFloat32( STATUS(float_rounding_mode) == float_round_down, 0, 0 );
18358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bExpBigger:
18368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0xFF ) {
18378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
18388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloat32( zSign ^ 1, 0xFF, 0 );
18398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
18408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0 ) {
18418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ++expDiff;
18428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
18438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
18448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSig |= 0x40000000;
18458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
18468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shift32RightJamming( aSig, - expDiff, &aSig );
18478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig |= 0x40000000;
18488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bBigger:
18498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig = bSig - aSig;
18508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zExp = bExp;
18518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSign ^= 1;
18528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    goto normalizeRoundAndPack;
18538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project aExpBigger:
18548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0xFF ) {
18558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig ) return propagateFloat32NaN( a, b STATUS_VAR );
18568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return a;
18578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
18588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0 ) {
18598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        --expDiff;
18608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
18618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
18628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        bSig |= 0x40000000;
18638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
18648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shift32RightJamming( bSig, expDiff, &bSig );
18658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig |= 0x40000000;
18668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project aBigger:
18678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig = aSig - bSig;
18688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zExp = aExp;
18698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project normalizeRoundAndPack:
18708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    --zExp;
18718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return normalizeRoundAndPackFloat32( zSign, zExp, zSig STATUS_VAR );
18728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
18748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
18768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of adding the single-precision floating-point values `a'
18778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| and `b'.  The operation is performed according to the IEC/IEEE Standard for
18788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Binary Floating-Point Arithmetic.
18798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
18808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 float32_add( float32 a, float32 b STATUS_PARAM )
18828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
18838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign;
1884bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float32_squash_input_denormal(a STATUS_VAR);
1885bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    b = float32_squash_input_denormal(b STATUS_VAR);
18868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat32Sign( a );
18888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloat32Sign( b );
18898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSign == bSign ) {
18908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return addFloat32Sigs( a, b, aSign STATUS_VAR);
18918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
18928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
18938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return subFloat32Sigs( a, b, aSign STATUS_VAR );
18948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
18958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
18978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
18998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of subtracting the single-precision floating-point values
19008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
19018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| for Binary Floating-Point Arithmetic.
19028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
19038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 float32_sub( float32 a, float32 b STATUS_PARAM )
19058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
19068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign;
1907bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float32_squash_input_denormal(a STATUS_VAR);
1908bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    b = float32_squash_input_denormal(b STATUS_VAR);
19098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat32Sign( a );
19118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloat32Sign( b );
19128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSign == bSign ) {
19138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return subFloat32Sigs( a, b, aSign STATUS_VAR );
19148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
19158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
19168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return addFloat32Sigs( a, b, aSign STATUS_VAR );
19178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
19188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
19208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
19228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of multiplying the single-precision floating-point values
19238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
19248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| for Binary Floating-Point Arithmetic.
19258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
19268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 float32_mul( float32 a, float32 b STATUS_PARAM )
19288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
19298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign, zSign;
19308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 aExp, bExp, zExp;
1931bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t aSig, bSig;
1932bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t zSig64;
1933bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t zSig;
1934bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
1935bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float32_squash_input_denormal(a STATUS_VAR);
1936bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    b = float32_squash_input_denormal(b STATUS_VAR);
19378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloat32Frac( a );
19398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat32Exp( a );
19408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat32Sign( a );
19418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig = extractFloat32Frac( b );
19428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bExp = extractFloat32Exp( b );
19438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloat32Sign( b );
19448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSign = aSign ^ bSign;
19458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0xFF ) {
19468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
19478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return propagateFloat32NaN( a, b STATUS_VAR );
19488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
19498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ( bExp | bSig ) == 0 ) {
19508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_invalid STATUS_VAR);
19518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return float32_default_nan;
19528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
19538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloat32( zSign, 0xFF, 0 );
19548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
19558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0xFF ) {
19568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
19578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ( aExp | aSig ) == 0 ) {
19588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_invalid STATUS_VAR);
19598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return float32_default_nan;
19608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
19618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloat32( zSign, 0xFF, 0 );
19628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
19638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0 ) {
19648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
19658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
19668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
19678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0 ) {
19688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bSig == 0 ) return packFloat32( zSign, 0, 0 );
19698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloat32Subnormal( bSig, &bExp, &bSig );
19708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
19718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zExp = aExp + bExp - 0x7F;
19728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = ( aSig | 0x00800000 )<<7;
19738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig = ( bSig | 0x00800000 )<<8;
1974bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    shift64RightJamming( ( (uint64_t) aSig ) * bSig, 32, &zSig64 );
19758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig = zSig64;
1976bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( 0 <= (int32_t) ( zSig<<1 ) ) {
19778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSig <<= 1;
19788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        --zExp;
19798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
19808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return roundAndPackFloat32( zSign, zExp, zSig STATUS_VAR );
19818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
19838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
19858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of dividing the single-precision floating-point value `a'
19868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| by the corresponding value `b'.  The operation is performed according to the
19878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
19888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
19898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 float32_div( float32 a, float32 b STATUS_PARAM )
19918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
19928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign, zSign;
19938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 aExp, bExp, zExp;
1994bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t aSig, bSig, zSig;
1995bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float32_squash_input_denormal(a STATUS_VAR);
1996bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    b = float32_squash_input_denormal(b STATUS_VAR);
19978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloat32Frac( a );
19998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat32Exp( a );
20008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat32Sign( a );
20018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig = extractFloat32Frac( b );
20028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bExp = extractFloat32Exp( b );
20038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloat32Sign( b );
20048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSign = aSign ^ bSign;
20058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0xFF ) {
20068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig ) return propagateFloat32NaN( a, b STATUS_VAR );
20078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bExp == 0xFF ) {
20088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
20098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_invalid STATUS_VAR);
20108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return float32_default_nan;
20118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
20128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloat32( zSign, 0xFF, 0 );
20138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
20148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0xFF ) {
20158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
20168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloat32( zSign, 0, 0 );
20178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
20188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0 ) {
20198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bSig == 0 ) {
20208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( ( aExp | aSig ) == 0 ) {
20218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                float_raise( float_flag_invalid STATUS_VAR);
20228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return float32_default_nan;
20238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
20248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_divbyzero STATUS_VAR);
20258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return packFloat32( zSign, 0xFF, 0 );
20268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
20278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloat32Subnormal( bSig, &bExp, &bSig );
20288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
20298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0 ) {
20308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
20318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
20328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
20338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zExp = aExp - bExp + 0x7D;
20348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = ( aSig | 0x00800000 )<<7;
20358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig = ( bSig | 0x00800000 )<<8;
20368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bSig <= ( aSig + aSig ) ) {
20378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSig >>= 1;
20388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ++zExp;
20398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2040bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    zSig = ( ( (uint64_t) aSig )<<32 ) / bSig;
20418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( ( zSig & 0x3F ) == 0 ) {
2042bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        zSig |= ( (uint64_t) bSig * zSig != ( (uint64_t) aSig )<<32 );
20438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
20448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return roundAndPackFloat32( zSign, zExp, zSig STATUS_VAR );
20458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
20478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
20498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the remainder of the single-precision floating-point value `a'
20508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| with respect to the corresponding value `b'.  The operation is performed
20518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
20528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
20538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 float32_rem( float32 a, float32 b STATUS_PARAM )
20558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
20562738c26579c211c46eedf84a4e61c73243551888David Turner    flag aSign, zSign;
20578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 aExp, bExp, expDiff;
2058bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t aSig, bSig;
2059bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t q;
2060bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig64, bSig64, q64;
2061bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t alternateASig;
2062bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    int32_t sigMean;
2063bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float32_squash_input_denormal(a STATUS_VAR);
2064bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    b = float32_squash_input_denormal(b STATUS_VAR);
20658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloat32Frac( a );
20678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat32Exp( a );
20688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat32Sign( a );
20698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig = extractFloat32Frac( b );
20708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bExp = extractFloat32Exp( b );
20718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0xFF ) {
20728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
20738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return propagateFloat32NaN( a, b STATUS_VAR );
20748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
20758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
20768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return float32_default_nan;
20778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
20788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0xFF ) {
20798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
20808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return a;
20818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
20828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0 ) {
20838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bSig == 0 ) {
20848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_invalid STATUS_VAR);
20858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return float32_default_nan;
20868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
20878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloat32Subnormal( bSig, &bExp, &bSig );
20888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
20898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0 ) {
20908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig == 0 ) return a;
20918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
20928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
20938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    expDiff = aExp - bExp;
20948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig |= 0x00800000;
20958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig |= 0x00800000;
20968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( expDiff < 32 ) {
20978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSig <<= 8;
20988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        bSig <<= 8;
20998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( expDiff < 0 ) {
21008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( expDiff < -1 ) return a;
21018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            aSig >>= 1;
21028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
21038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        q = ( bSig <= aSig );
21048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( q ) aSig -= bSig;
21058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( 0 < expDiff ) {
2106bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            q = ( ( (uint64_t) aSig )<<32 ) / bSig;
21078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            q >>= 32 - expDiff;
21088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            bSig >>= 2;
21098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
21108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
21118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else {
21128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            aSig >>= 2;
21138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            bSig >>= 2;
21148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
21158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
21168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
21178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bSig <= aSig ) aSig -= bSig;
2118bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        aSig64 = ( (uint64_t) aSig )<<40;
2119bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        bSig64 = ( (uint64_t) bSig )<<40;
21208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        expDiff -= 64;
21218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        while ( 0 < expDiff ) {
21228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            q64 = estimateDiv128To64( aSig64, 0, bSig64 );
21238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            q64 = ( 2 < q64 ) ? q64 - 2 : 0;
21248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            aSig64 = - ( ( bSig * q64 )<<38 );
21258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            expDiff -= 62;
21268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
21278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        expDiff += 64;
21288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        q64 = estimateDiv128To64( aSig64, 0, bSig64 );
21298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        q64 = ( 2 < q64 ) ? q64 - 2 : 0;
21308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        q = q64>>( 64 - expDiff );
21318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        bSig <<= 6;
21328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSig = ( ( aSig64>>33 )<<( expDiff - 1 ) ) - bSig * q;
21338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
21348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do {
21358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        alternateASig = aSig;
21368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ++q;
21378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSig -= bSig;
2138bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    } while ( 0 <= (int32_t) aSig );
21398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sigMean = aSig + alternateASig;
21408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {
21418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSig = alternateASig;
21428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2143bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    zSign = ( (int32_t) aSig < 0 );
21448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( zSign ) aSig = - aSig;
21458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig STATUS_VAR );
21468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
21488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
21508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the square root of the single-precision floating-point value `a'.
21518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| The operation is performed according to the IEC/IEEE Standard for Binary
21528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Floating-Point Arithmetic.
21538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
21548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 float32_sqrt( float32 a STATUS_PARAM )
21568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
21578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
21588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 aExp, zExp;
2159bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t aSig, zSig;
2160bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t rem, term;
2161bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float32_squash_input_denormal(a STATUS_VAR);
21628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloat32Frac( a );
21648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat32Exp( a );
21658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat32Sign( a );
21668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0xFF ) {
21678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig ) return propagateFloat32NaN( a, float32_zero STATUS_VAR );
21688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ! aSign ) return a;
21698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
21708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return float32_default_nan;
21718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
21728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSign ) {
21738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ( aExp | aSig ) == 0 ) return a;
21748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
21758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return float32_default_nan;
21768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
21778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0 ) {
21788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig == 0 ) return float32_zero;
21798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
21808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
21818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zExp = ( ( aExp - 0x7F )>>1 ) + 0x7E;
21828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = ( aSig | 0x00800000 )<<8;
21838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig = estimateSqrt32( aExp, aSig ) + 2;
21848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( ( zSig & 0x7F ) <= 5 ) {
21858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( zSig < 2 ) {
21868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            zSig = 0x7FFFFFFF;
21878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto roundAndPack;
21888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
21898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSig >>= aExp & 1;
2190bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        term = ( (uint64_t) zSig ) * zSig;
2191bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        rem = ( ( (uint64_t) aSig )<<32 ) - term;
2192bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        while ( (int64_t) rem < 0 ) {
21938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            --zSig;
2194bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            rem += ( ( (uint64_t) zSig )<<1 ) | 1;
21958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
21968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSig |= ( rem != 0 );
21978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
21988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shift32RightJamming( zSig, 1, &zSig );
21998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project roundAndPack:
22008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return roundAndPackFloat32( 0, zExp, zSig STATUS_VAR );
22018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
22038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
22052738c26579c211c46eedf84a4e61c73243551888David Turner| Returns the binary exponential of the single-precision floating-point value
22062738c26579c211c46eedf84a4e61c73243551888David Turner| `a'. The operation is performed according to the IEC/IEEE Standard for
22072738c26579c211c46eedf84a4e61c73243551888David Turner| Binary Floating-Point Arithmetic.
22082738c26579c211c46eedf84a4e61c73243551888David Turner|
22092738c26579c211c46eedf84a4e61c73243551888David Turner| Uses the following identities:
22102738c26579c211c46eedf84a4e61c73243551888David Turner|
22112738c26579c211c46eedf84a4e61c73243551888David Turner| 1. -------------------------------------------------------------------------
22122738c26579c211c46eedf84a4e61c73243551888David Turner|      x    x*ln(2)
22132738c26579c211c46eedf84a4e61c73243551888David Turner|     2  = e
22142738c26579c211c46eedf84a4e61c73243551888David Turner|
22152738c26579c211c46eedf84a4e61c73243551888David Turner| 2. -------------------------------------------------------------------------
22162738c26579c211c46eedf84a4e61c73243551888David Turner|                      2     3     4     5           n
22172738c26579c211c46eedf84a4e61c73243551888David Turner|      x        x     x     x     x     x           x
22182738c26579c211c46eedf84a4e61c73243551888David Turner|     e  = 1 + --- + --- + --- + --- + --- + ... + --- + ...
22192738c26579c211c46eedf84a4e61c73243551888David Turner|               1!    2!    3!    4!    5!          n!
22202738c26579c211c46eedf84a4e61c73243551888David Turner*----------------------------------------------------------------------------*/
22212738c26579c211c46eedf84a4e61c73243551888David Turner
22222738c26579c211c46eedf84a4e61c73243551888David Turnerstatic const float64 float32_exp2_coefficients[15] =
22232738c26579c211c46eedf84a4e61c73243551888David Turner{
2224bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    const_float64( 0x3ff0000000000000ll ), /*  1 */
2225bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    const_float64( 0x3fe0000000000000ll ), /*  2 */
2226bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    const_float64( 0x3fc5555555555555ll ), /*  3 */
2227bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    const_float64( 0x3fa5555555555555ll ), /*  4 */
2228bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    const_float64( 0x3f81111111111111ll ), /*  5 */
2229bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    const_float64( 0x3f56c16c16c16c17ll ), /*  6 */
2230bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    const_float64( 0x3f2a01a01a01a01all ), /*  7 */
2231bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    const_float64( 0x3efa01a01a01a01all ), /*  8 */
2232bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    const_float64( 0x3ec71de3a556c734ll ), /*  9 */
2233bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    const_float64( 0x3e927e4fb7789f5cll ), /* 10 */
2234bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    const_float64( 0x3e5ae64567f544e4ll ), /* 11 */
2235bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    const_float64( 0x3e21eed8eff8d898ll ), /* 12 */
2236bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    const_float64( 0x3de6124613a86d09ll ), /* 13 */
2237bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    const_float64( 0x3da93974a8c07c9dll ), /* 14 */
2238bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    const_float64( 0x3d6ae7f3e733b81fll ), /* 15 */
22392738c26579c211c46eedf84a4e61c73243551888David Turner};
22402738c26579c211c46eedf84a4e61c73243551888David Turner
22412738c26579c211c46eedf84a4e61c73243551888David Turnerfloat32 float32_exp2( float32 a STATUS_PARAM )
22422738c26579c211c46eedf84a4e61c73243551888David Turner{
22432738c26579c211c46eedf84a4e61c73243551888David Turner    flag aSign;
22442738c26579c211c46eedf84a4e61c73243551888David Turner    int16 aExp;
2245bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t aSig;
22462738c26579c211c46eedf84a4e61c73243551888David Turner    float64 r, x, xn;
22472738c26579c211c46eedf84a4e61c73243551888David Turner    int i;
2248bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float32_squash_input_denormal(a STATUS_VAR);
22492738c26579c211c46eedf84a4e61c73243551888David Turner
22502738c26579c211c46eedf84a4e61c73243551888David Turner    aSig = extractFloat32Frac( a );
22512738c26579c211c46eedf84a4e61c73243551888David Turner    aExp = extractFloat32Exp( a );
22522738c26579c211c46eedf84a4e61c73243551888David Turner    aSign = extractFloat32Sign( a );
22532738c26579c211c46eedf84a4e61c73243551888David Turner
22542738c26579c211c46eedf84a4e61c73243551888David Turner    if ( aExp == 0xFF) {
22552738c26579c211c46eedf84a4e61c73243551888David Turner        if ( aSig ) return propagateFloat32NaN( a, float32_zero STATUS_VAR );
22562738c26579c211c46eedf84a4e61c73243551888David Turner        return (aSign) ? float32_zero : a;
22572738c26579c211c46eedf84a4e61c73243551888David Turner    }
22582738c26579c211c46eedf84a4e61c73243551888David Turner    if (aExp == 0) {
22592738c26579c211c46eedf84a4e61c73243551888David Turner        if (aSig == 0) return float32_one;
22602738c26579c211c46eedf84a4e61c73243551888David Turner    }
22612738c26579c211c46eedf84a4e61c73243551888David Turner
22622738c26579c211c46eedf84a4e61c73243551888David Turner    float_raise( float_flag_inexact STATUS_VAR);
22632738c26579c211c46eedf84a4e61c73243551888David Turner
22642738c26579c211c46eedf84a4e61c73243551888David Turner    /* ******************************* */
22652738c26579c211c46eedf84a4e61c73243551888David Turner    /* using float64 for approximation */
22662738c26579c211c46eedf84a4e61c73243551888David Turner    /* ******************************* */
22672738c26579c211c46eedf84a4e61c73243551888David Turner    x = float32_to_float64(a STATUS_VAR);
22682738c26579c211c46eedf84a4e61c73243551888David Turner    x = float64_mul(x, float64_ln2 STATUS_VAR);
22692738c26579c211c46eedf84a4e61c73243551888David Turner
22702738c26579c211c46eedf84a4e61c73243551888David Turner    xn = x;
22712738c26579c211c46eedf84a4e61c73243551888David Turner    r = float64_one;
22722738c26579c211c46eedf84a4e61c73243551888David Turner    for (i = 0 ; i < 15 ; i++) {
22732738c26579c211c46eedf84a4e61c73243551888David Turner        float64 f;
22742738c26579c211c46eedf84a4e61c73243551888David Turner
22752738c26579c211c46eedf84a4e61c73243551888David Turner        f = float64_mul(xn, float32_exp2_coefficients[i] STATUS_VAR);
22762738c26579c211c46eedf84a4e61c73243551888David Turner        r = float64_add(r, f STATUS_VAR);
22772738c26579c211c46eedf84a4e61c73243551888David Turner
22782738c26579c211c46eedf84a4e61c73243551888David Turner        xn = float64_mul(xn, x STATUS_VAR);
22792738c26579c211c46eedf84a4e61c73243551888David Turner    }
22802738c26579c211c46eedf84a4e61c73243551888David Turner
22812738c26579c211c46eedf84a4e61c73243551888David Turner    return float64_to_float32(r, status);
22822738c26579c211c46eedf84a4e61c73243551888David Turner}
22832738c26579c211c46eedf84a4e61c73243551888David Turner
22842738c26579c211c46eedf84a4e61c73243551888David Turner/*----------------------------------------------------------------------------
22855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner| Returns the binary log of the single-precision floating-point value `a'.
22865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner| The operation is performed according to the IEC/IEEE Standard for Binary
22875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner| Floating-Point Arithmetic.
22885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner*----------------------------------------------------------------------------*/
22895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerfloat32 float32_log2( float32 a STATUS_PARAM )
22905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
22915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    flag aSign, zSign;
22925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int16 aExp;
2293bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t aSig, zSig, i;
22945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2295bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float32_squash_input_denormal(a STATUS_VAR);
22965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    aSig = extractFloat32Frac( a );
22975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    aExp = extractFloat32Exp( a );
22985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    aSign = extractFloat32Sign( a );
22995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if ( aExp == 0 ) {
23015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if ( aSig == 0 ) return packFloat32( 1, 0xFF, 0 );
23025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
23035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
23045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if ( aSign ) {
23055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        float_raise( float_flag_invalid STATUS_VAR);
23065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return float32_default_nan;
23075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
23085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if ( aExp == 0xFF ) {
23095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if ( aSig ) return propagateFloat32NaN( a, float32_zero STATUS_VAR );
23105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return a;
23115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
23125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    aExp -= 0x7F;
23145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    aSig |= 0x00800000;
23155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    zSign = aExp < 0;
23165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    zSig = aExp << 23;
23175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (i = 1 << 22; i > 0; i >>= 1) {
2319bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        aSig = ( (uint64_t)aSig * aSig ) >> 23;
23205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if ( aSig & 0x01000000 ) {
23215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            aSig >>= 1;
23225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            zSig |= i;
23235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
23245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
23255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if ( zSign )
23275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        zSig = -zSig;
23285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return normalizeRoundAndPackFloat32( zSign, 0x85, zSig STATUS_VAR );
23305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
23315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/*----------------------------------------------------------------------------
23338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns 1 if the single-precision floating-point value `a' is equal to
2334bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| the corresponding value `b', and 0 otherwise.  The invalid exception is
2335bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| raised if either operand is a NaN.  Otherwise, the comparison is performed
23368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
23378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
23388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint float32_eq( float32 a, float32 b STATUS_PARAM )
23408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2341bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t av, bv;
2342bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float32_squash_input_denormal(a STATUS_VAR);
2343bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    b = float32_squash_input_denormal(b STATUS_VAR);
23448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
23468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
23478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       ) {
2348bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        float_raise( float_flag_invalid STATUS_VAR);
23498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
23508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2351bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    av = float32_val(a);
2352bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    bv = float32_val(b);
2353bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    return ( av == bv ) || ( (uint32_t) ( ( av | bv )<<1 ) == 0 );
23548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
23558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
23578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns 1 if the single-precision floating-point value `a' is less than
2358bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| or equal to the corresponding value `b', and 0 otherwise.  The invalid
2359bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| exception is raised if either operand is a NaN.  The comparison is performed
2360bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
23618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
23628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint float32_le( float32 a, float32 b STATUS_PARAM )
23648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
23658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign;
2366bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t av, bv;
2367bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float32_squash_input_denormal(a STATUS_VAR);
2368bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    b = float32_squash_input_denormal(b STATUS_VAR);
23698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
23718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
23728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       ) {
23738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
23748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
23758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
23768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat32Sign( a );
23778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloat32Sign( b );
23788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    av = float32_val(a);
23798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bv = float32_val(b);
2380bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( aSign != bSign ) return aSign || ( (uint32_t) ( ( av | bv )<<1 ) == 0 );
23818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ( av == bv ) || ( aSign ^ ( av < bv ) );
23828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
23848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
23868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns 1 if the single-precision floating-point value `a' is less than
2387bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| the corresponding value `b', and 0 otherwise.  The invalid exception is
2388bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| raised if either operand is a NaN.  The comparison is performed according
2389bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
23908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
23918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint float32_lt( float32 a, float32 b STATUS_PARAM )
23938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
23948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign;
2395bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t av, bv;
2396bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float32_squash_input_denormal(a STATUS_VAR);
2397bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    b = float32_squash_input_denormal(b STATUS_VAR);
23988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
24008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
24018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       ) {
24028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
24038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
24048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
24058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat32Sign( a );
24068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloat32Sign( b );
24078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    av = float32_val(a);
24088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bv = float32_val(b);
2409bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( aSign != bSign ) return aSign && ( (uint32_t) ( ( av | bv )<<1 ) != 0 );
24108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ( av != bv ) && ( aSign ^ ( av < bv ) );
24118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
24138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
2415bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| Returns 1 if the single-precision floating-point values `a' and `b' cannot
2416bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| be compared, and 0 otherwise.  The invalid exception is raised if either
2417bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| operand is a NaN.  The comparison is performed according to the IEC/IEEE
2418bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| Standard for Binary Floating-Point Arithmetic.
24198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
24208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2421bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turnerint float32_unordered( float32 a, float32 b STATUS_PARAM )
24228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2423bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float32_squash_input_denormal(a STATUS_VAR);
2424bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    b = float32_squash_input_denormal(b STATUS_VAR);
24258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
24278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
24288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       ) {
24298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
2430bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        return 1;
24318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2432bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    return 0;
2433bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner}
24348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2435bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner/*----------------------------------------------------------------------------
2436bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| Returns 1 if the single-precision floating-point value `a' is equal to
2437bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
2438bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| exception.  The comparison is performed according to the IEC/IEEE Standard
2439bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| for Binary Floating-Point Arithmetic.
2440bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner*----------------------------------------------------------------------------*/
2441bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
2442bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turnerint float32_eq_quiet( float32 a, float32 b STATUS_PARAM )
2443bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner{
2444bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float32_squash_input_denormal(a STATUS_VAR);
2445bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    b = float32_squash_input_denormal(b STATUS_VAR);
2446bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
2447bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
2448bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
2449bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner       ) {
2450bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
2451bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            float_raise( float_flag_invalid STATUS_VAR);
2452bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        }
2453bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        return 0;
2454bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    }
2455bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    return ( float32_val(a) == float32_val(b) ) ||
2456bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            ( (uint32_t) ( ( float32_val(a) | float32_val(b) )<<1 ) == 0 );
24578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
24588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
24608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns 1 if the single-precision floating-point value `a' is less than or
24618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs do not
24628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| cause an exception.  Otherwise, the comparison is performed according to the
24638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
24648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
24658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint float32_le_quiet( float32 a, float32 b STATUS_PARAM )
24678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
24688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign;
2469bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t av, bv;
2470bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float32_squash_input_denormal(a STATUS_VAR);
2471bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    b = float32_squash_input_denormal(b STATUS_VAR);
24728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
24748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
24758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       ) {
24768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
24778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_invalid STATUS_VAR);
24788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
24798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
24808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
24818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat32Sign( a );
24828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloat32Sign( b );
24838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    av = float32_val(a);
24848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bv = float32_val(b);
2485bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( aSign != bSign ) return aSign || ( (uint32_t) ( ( av | bv )<<1 ) == 0 );
24868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ( av == bv ) || ( aSign ^ ( av < bv ) );
24878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
24898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
24918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns 1 if the single-precision floating-point value `a' is less than
24928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
24938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| exception.  Otherwise, the comparison is performed according to the IEC/IEEE
24948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Standard for Binary Floating-Point Arithmetic.
24958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
24968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint float32_lt_quiet( float32 a, float32 b STATUS_PARAM )
24988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
24998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign;
2500bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t av, bv;
2501bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float32_squash_input_denormal(a STATUS_VAR);
2502bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    b = float32_squash_input_denormal(b STATUS_VAR);
25038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
25058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
25068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       ) {
25078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
25088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_invalid STATUS_VAR);
25098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
25108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
25118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
25128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat32Sign( a );
25138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloat32Sign( b );
25148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    av = float32_val(a);
25158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bv = float32_val(b);
2516bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( aSign != bSign ) return aSign && ( (uint32_t) ( ( av | bv )<<1 ) != 0 );
25178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ( av != bv ) && ( aSign ^ ( av < bv ) );
25188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
25208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
2522bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| Returns 1 if the single-precision floating-point values `a' and `b' cannot
2523bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| be compared, and 0 otherwise.  Quiet NaNs do not cause an exception.  The
2524bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| comparison is performed according to the IEC/IEEE Standard for Binary
2525bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| Floating-Point Arithmetic.
2526bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner*----------------------------------------------------------------------------*/
2527bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
2528bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turnerint float32_unordered_quiet( float32 a, float32 b STATUS_PARAM )
2529bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner{
2530bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float32_squash_input_denormal(a STATUS_VAR);
2531bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    b = float32_squash_input_denormal(b STATUS_VAR);
2532bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
2533bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
2534bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner         || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
2535bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner       ) {
2536bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
2537bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            float_raise( float_flag_invalid STATUS_VAR);
2538bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        }
2539bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        return 1;
2540bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    }
2541bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    return 0;
2542bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner}
2543bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
2544bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner/*----------------------------------------------------------------------------
25458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the double-precision floating-point value
25468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `a' to the 32-bit two's complement integer format.  The conversion is
25478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| performed according to the IEC/IEEE Standard for Binary Floating-Point
25488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Arithmetic---which means in particular that the conversion is rounded
25498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| according to the current rounding mode.  If `a' is a NaN, the largest
25508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| positive integer is returned.  Otherwise, if the conversion overflows, the
25518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| largest integer with the same sign as `a' is returned.
25528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
25538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint32 float64_to_int32( float64 a STATUS_PARAM )
25558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
25568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
25578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 aExp, shiftCount;
2558bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig;
2559bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float64_squash_input_denormal(a STATUS_VAR);
25608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloat64Frac( a );
25628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat64Exp( a );
25638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat64Sign( a );
25648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
25658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
25668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shiftCount = 0x42C - aExp;
25678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig );
25688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return roundAndPackInt32( aSign, aSig STATUS_VAR );
25698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
25718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
25738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the double-precision floating-point value
25748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `a' to the 32-bit two's complement integer format.  The conversion is
25758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| performed according to the IEC/IEEE Standard for Binary Floating-Point
25768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Arithmetic, except that the conversion is always rounded toward zero.
25778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| If `a' is a NaN, the largest positive integer is returned.  Otherwise, if
25788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| the conversion overflows, the largest integer with the same sign as `a' is
25798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| returned.
25808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
25818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint32 float64_to_int32_round_to_zero( float64 a STATUS_PARAM )
25838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
25848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
25858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 aExp, shiftCount;
2586bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig, savedASig;
25878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 z;
2588bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float64_squash_input_denormal(a STATUS_VAR);
25898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloat64Frac( a );
25918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat64Exp( a );
25928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat64Sign( a );
25938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( 0x41E < aExp ) {
25948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
25958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto invalid;
25968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
25978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else if ( aExp < 0x3FF ) {
25988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aExp || aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
25998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
26008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
26018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig |= LIT64( 0x0010000000000000 );
26028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shiftCount = 0x433 - aExp;
26038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    savedASig = aSig;
26048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig >>= shiftCount;
26058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    z = aSig;
26068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSign ) z = - z;
26078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( ( z < 0 ) ^ aSign ) {
26088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project invalid:
26098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
2610bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        return aSign ? (int32_t) 0x80000000 : 0x7FFFFFFF;
26118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
26128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( ( aSig<<shiftCount ) != savedASig ) {
26138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        STATUS(float_exception_flags) |= float_flag_inexact;
26148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
26158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return z;
26168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
26178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
26188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
26198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
26208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the double-precision floating-point value
2621bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| `a' to the 16-bit two's complement integer format.  The conversion is
2622bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| performed according to the IEC/IEEE Standard for Binary Floating-Point
2623bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| Arithmetic, except that the conversion is always rounded toward zero.
2624bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| If `a' is a NaN, the largest positive integer is returned.  Otherwise, if
2625bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| the conversion overflows, the largest integer with the same sign as `a' is
2626bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| returned.
2627bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner*----------------------------------------------------------------------------*/
2628bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
2629bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turnerint16 float64_to_int16_round_to_zero( float64 a STATUS_PARAM )
2630bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner{
2631bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    flag aSign;
2632bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    int16 aExp, shiftCount;
2633bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig, savedASig;
2634bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    int32 z;
2635bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
2636bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    aSig = extractFloat64Frac( a );
2637bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    aExp = extractFloat64Exp( a );
2638bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    aSign = extractFloat64Sign( a );
2639bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( 0x40E < aExp ) {
2640bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( ( aExp == 0x7FF ) && aSig ) {
2641bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            aSign = 0;
2642bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        }
2643bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        goto invalid;
2644bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    }
2645bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    else if ( aExp < 0x3FF ) {
2646bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( aExp || aSig ) {
2647bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            STATUS(float_exception_flags) |= float_flag_inexact;
2648bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        }
2649bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        return 0;
2650bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    }
2651bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    aSig |= LIT64( 0x0010000000000000 );
2652bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    shiftCount = 0x433 - aExp;
2653bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    savedASig = aSig;
2654bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    aSig >>= shiftCount;
2655bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    z = aSig;
2656bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( aSign ) {
2657bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        z = - z;
2658bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    }
2659bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( ( (int16_t)z < 0 ) ^ aSign ) {
2660bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner invalid:
2661bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        float_raise( float_flag_invalid STATUS_VAR);
2662bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        return aSign ? (int32_t) 0xffff8000 : 0x7FFF;
2663bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    }
2664bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( ( aSig<<shiftCount ) != savedASig ) {
2665bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        STATUS(float_exception_flags) |= float_flag_inexact;
2666bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    }
2667bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    return z;
2668bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner}
2669bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
2670bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner/*----------------------------------------------------------------------------
2671bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| Returns the result of converting the double-precision floating-point value
26728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `a' to the 64-bit two's complement integer format.  The conversion is
26738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| performed according to the IEC/IEEE Standard for Binary Floating-Point
26748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Arithmetic---which means in particular that the conversion is rounded
26758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| according to the current rounding mode.  If `a' is a NaN, the largest
26768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| positive integer is returned.  Otherwise, if the conversion overflows, the
26778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| largest integer with the same sign as `a' is returned.
26788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
26798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
26808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint64 float64_to_int64( float64 a STATUS_PARAM )
26818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
26828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
26838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 aExp, shiftCount;
2684bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig, aSigExtra;
2685bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float64_squash_input_denormal(a STATUS_VAR);
26868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
26878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloat64Frac( a );
26888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat64Exp( a );
26898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat64Sign( a );
26908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
26918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shiftCount = 0x433 - aExp;
26928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( shiftCount <= 0 ) {
26938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( 0x43E < aExp ) {
26948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_invalid STATUS_VAR);
26958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (    ! aSign
26968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 || (    ( aExp == 0x7FF )
26978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                      && ( aSig != LIT64( 0x0010000000000000 ) ) )
26988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               ) {
26998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return LIT64( 0x7FFFFFFFFFFFFFFF );
27008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
2701bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            return (int64_t) LIT64( 0x8000000000000000 );
27028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
27038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSigExtra = 0;
27048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSig <<= - shiftCount;
27058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
27068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
27078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shift64ExtraRightJamming( aSig, 0, shiftCount, &aSig, &aSigExtra );
27088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
27098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return roundAndPackInt64( aSign, aSig, aSigExtra STATUS_VAR );
27108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
27128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
27148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the double-precision floating-point value
27158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `a' to the 64-bit two's complement integer format.  The conversion is
27168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| performed according to the IEC/IEEE Standard for Binary Floating-Point
27178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Arithmetic, except that the conversion is always rounded toward zero.
27188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| If `a' is a NaN, the largest positive integer is returned.  Otherwise, if
27198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| the conversion overflows, the largest integer with the same sign as `a' is
27208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| returned.
27218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
27228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint64 float64_to_int64_round_to_zero( float64 a STATUS_PARAM )
27248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
27258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
27268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 aExp, shiftCount;
2727bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig;
27288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64 z;
2729bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float64_squash_input_denormal(a STATUS_VAR);
27308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloat64Frac( a );
27328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat64Exp( a );
27338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat64Sign( a );
27348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
27358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shiftCount = aExp - 0x433;
27368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( 0 <= shiftCount ) {
27378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( 0x43E <= aExp ) {
27388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( float64_val(a) != LIT64( 0xC3E0000000000000 ) ) {
27398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                float_raise( float_flag_invalid STATUS_VAR);
27408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (    ! aSign
27418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     || (    ( aExp == 0x7FF )
27428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                          && ( aSig != LIT64( 0x0010000000000000 ) ) )
27438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   ) {
27448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    return LIT64( 0x7FFFFFFFFFFFFFFF );
27458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
27468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
2747bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            return (int64_t) LIT64( 0x8000000000000000 );
27488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
27498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        z = aSig<<shiftCount;
27508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
27518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
27528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aExp < 0x3FE ) {
27538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( aExp | aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
27548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 0;
27558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
27568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        z = aSig>>( - shiftCount );
2757bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( (uint64_t) ( aSig<<( shiftCount & 63 ) ) ) {
27588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            STATUS(float_exception_flags) |= float_flag_inexact;
27598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
27608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
27618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSign ) z = - z;
27628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return z;
27638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
27658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
27678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the double-precision floating-point value
27688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `a' to the single-precision floating-point format.  The conversion is
27698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| performed according to the IEC/IEEE Standard for Binary Floating-Point
27708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Arithmetic.
27718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
27728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 float64_to_float32( float64 a STATUS_PARAM )
27748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
27758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
27768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 aExp;
2777bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig;
2778bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t zSig;
2779bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float64_squash_input_denormal(a STATUS_VAR);
27808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloat64Frac( a );
27828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat64Exp( a );
27838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat64Sign( a );
27848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0x7FF ) {
2785bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( aSig ) return commonNaNToFloat32( float64ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
27868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloat32( aSign, 0xFF, 0 );
27878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
27888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shift64RightJamming( aSig, 22, &aSig );
27898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig = aSig;
27908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp || zSig ) {
27918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSig |= 0x40000000;
27928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aExp -= 0x381;
27938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
27948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return roundAndPackFloat32( aSign, aExp, zSig STATUS_VAR );
27958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
27978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27982c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner
27992c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner/*----------------------------------------------------------------------------
28002c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
28012c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner| half-precision floating-point value, returning the result.  After being
28022c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner| shifted into the proper positions, the three fields are simply added
28032c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner| together to form the result.  This means that any integer portion of `zSig'
28042c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner| will be added into the exponent.  Since a properly normalized significand
28052c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner| will have an integer portion equal to 1, the `zExp' input should be 1 less
28062c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner| than the desired result exponent whenever `zSig' is a complete, normalized
28072c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner| significand.
28082c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner*----------------------------------------------------------------------------*/
2809bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turnerstatic float16 packFloat16(flag zSign, int16 zExp, uint16_t zSig)
28102c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner{
2811bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    return make_float16(
2812bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        (((uint32_t)zSign) << 15) + (((uint32_t)zExp) << 10) + zSig);
28132c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner}
28142c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner
28152c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner/* Half precision floats come in two formats: standard IEEE and "ARM" format.
28162c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner   The latter gains extra exponent range by omitting the NaN/Inf encodings.  */
2817bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
2818bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turnerfloat32 float16_to_float32(float16 a, flag ieee STATUS_PARAM)
28192c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner{
28202c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    flag aSign;
28212c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    int16 aExp;
2822bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t aSig;
28232c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner
2824bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    aSign = extractFloat16Sign(a);
2825bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    aExp = extractFloat16Exp(a);
2826bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    aSig = extractFloat16Frac(a);
28272c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner
28282c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    if (aExp == 0x1f && ieee) {
28292c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        if (aSig) {
2830bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            return commonNaNToFloat32(float16ToCommonNaN(a STATUS_VAR) STATUS_VAR);
28312c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        }
28322c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        return packFloat32(aSign, 0xff, aSig << 13);
28332c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    }
28342c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    if (aExp == 0) {
28352c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        int8 shiftCount;
28362c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner
28372c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        if (aSig == 0) {
28382c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner            return packFloat32(aSign, 0, 0);
28392c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        }
28402c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner
28412c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        shiftCount = countLeadingZeros32( aSig ) - 21;
28422c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        aSig = aSig << shiftCount;
28432c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        aExp = -shiftCount;
28442c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    }
28452c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    return packFloat32( aSign, aExp + 0x70, aSig << 13);
28462c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner}
28472c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner
2848bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turnerfloat16 float32_to_float16(float32 a, flag ieee STATUS_PARAM)
28492c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner{
28502c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    flag aSign;
28512c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    int16 aExp;
2852bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t aSig;
2853bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t mask;
2854bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t increment;
28552c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    int8 roundingMode;
2856bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float32_squash_input_denormal(a STATUS_VAR);
28572c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner
28582c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    aSig = extractFloat32Frac( a );
28592c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    aExp = extractFloat32Exp( a );
28602c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    aSign = extractFloat32Sign( a );
28612c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    if ( aExp == 0xFF ) {
28622c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        if (aSig) {
2863bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            /* Input is a NaN */
2864bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            float16 r = commonNaNToFloat16( float32ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
2865bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            if (!ieee) {
2866bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner                return packFloat16(aSign, 0, 0);
2867bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            }
2868bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            return r;
28692c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        }
2870bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        /* Infinity */
2871bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if (!ieee) {
2872bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            float_raise(float_flag_invalid STATUS_VAR);
2873bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            return packFloat16(aSign, 0x1f, 0x3ff);
2874bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        }
2875bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        return packFloat16(aSign, 0x1f, 0);
28762c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    }
2877bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if (aExp == 0 && aSig == 0) {
28782c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        return packFloat16(aSign, 0, 0);
28792c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    }
28802c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    /* Decimal point between bits 22 and 23.  */
28812c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    aSig |= 0x00800000;
28822c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    aExp -= 0x7f;
28832c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    if (aExp < -14) {
2884bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        mask = 0x00ffffff;
2885bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if (aExp >= -24) {
2886bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            mask >>= 25 + aExp;
28872c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        }
28882c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    } else {
28892c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        mask = 0x00001fff;
28902c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    }
28912c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    if (aSig & mask) {
28922c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        float_raise( float_flag_underflow STATUS_VAR );
28932c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        roundingMode = STATUS(float_rounding_mode);
28942c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        switch (roundingMode) {
28952c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        case float_round_nearest_even:
28962c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner            increment = (mask + 1) >> 1;
28972c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner            if ((aSig & mask) == increment) {
28982c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner                increment = aSig & (increment << 1);
28992c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner            }
29002c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner            break;
29012c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        case float_round_up:
29022c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner            increment = aSign ? 0 : mask;
29032c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner            break;
29042c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        case float_round_down:
29052c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner            increment = aSign ? mask : 0;
29062c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner            break;
29072c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        default: /* round_to_zero */
29082c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner            increment = 0;
29092c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner            break;
29102c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        }
29112c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        aSig += increment;
29122c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        if (aSig >= 0x01000000) {
29132c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner            aSig >>= 1;
29142c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner            aExp++;
29152c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        }
29162c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    } else if (aExp < -14
29172c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner          && STATUS(float_detect_tininess) == float_tininess_before_rounding) {
29182c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        float_raise( float_flag_underflow STATUS_VAR);
29192c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    }
29202c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner
29212c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    if (ieee) {
29222c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        if (aExp > 15) {
29232c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner            float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
29242c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner            return packFloat16(aSign, 0x1f, 0);
29252c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        }
29262c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    } else {
29272c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        if (aExp > 16) {
2928bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            float_raise(float_flag_invalid | float_flag_inexact STATUS_VAR);
29292c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner            return packFloat16(aSign, 0x1f, 0x3ff);
29302c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        }
29312c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    }
29322c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    if (aExp < -24) {
29332c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        return packFloat16(aSign, 0, 0);
29342c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    }
29352c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    if (aExp < -14) {
29362c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        aSig >>= -14 - aExp;
29372c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner        aExp = -14;
29382c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    }
29392c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner    return packFloat16(aSign, aExp + 14, aSig >> 13);
29402c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner}
29412c538c86c15d597cc875dc926e4e39285c5625dfDavid 'Digit' Turner
29428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef FLOATX80
29438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
29448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
29458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the double-precision floating-point value
29468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `a' to the extended double-precision floating-point format.  The conversion
29478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| is performed according to the IEC/IEEE Standard for Binary Floating-Point
29488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Arithmetic.
29498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
29508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
29518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloatx80 float64_to_floatx80( float64 a STATUS_PARAM )
29528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
29538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
29548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 aExp;
2955bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig;
29568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2957bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float64_squash_input_denormal(a STATUS_VAR);
29588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloat64Frac( a );
29598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat64Exp( a );
29608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat64Sign( a );
29618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0x7FF ) {
2962bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( aSig ) return commonNaNToFloatx80( float64ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
29638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
29648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
29658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0 ) {
29668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
29678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloat64Subnormal( aSig, &aExp, &aSig );
29688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
29698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return
29708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        packFloatx80(
29718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            aSign, aExp + 0x3C00, ( aSig | LIT64( 0x0010000000000000 ) )<<11 );
29728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
29738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
29748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
29758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
29768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
29778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef FLOAT128
29788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
29798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
29808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the double-precision floating-point value
29818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `a' to the quadruple-precision floating-point format.  The conversion is
29828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| performed according to the IEC/IEEE Standard for Binary Floating-Point
29838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Arithmetic.
29848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
29858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
29868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat128 float64_to_float128( float64 a STATUS_PARAM )
29878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
29888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
29898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 aExp;
2990bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig, zSig0, zSig1;
29918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2992bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float64_squash_input_denormal(a STATUS_VAR);
29938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloat64Frac( a );
29948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat64Exp( a );
29958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat64Sign( a );
29968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0x7FF ) {
2997bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( aSig ) return commonNaNToFloat128( float64ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
29988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloat128( aSign, 0x7FFF, 0, 0 );
29998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
30008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0 ) {
30018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 );
30028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloat64Subnormal( aSig, &aExp, &aSig );
30038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        --aExp;
30048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
30058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shift128Right( aSig, 0, 4, &zSig0, &zSig1 );
30068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return packFloat128( aSign, aExp + 0x3C00, zSig0, zSig1 );
30078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
30088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
30098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
30108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
30118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
30128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
30138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Rounds the double-precision floating-point value `a' to an integer, and
30148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| returns the result as a double-precision floating-point value.  The
30158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| operation is performed according to the IEC/IEEE Standard for Binary
30168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Floating-Point Arithmetic.
30178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
30188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
30198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat64 float64_round_to_int( float64 a STATUS_PARAM )
30208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
30218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
30228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 aExp;
3023bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t lastBitMask, roundBitsMask;
30248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8 roundingMode;
3025bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t z;
3026bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float64_squash_input_denormal(a STATUS_VAR);
30278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
30288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat64Exp( a );
30298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( 0x433 <= aExp ) {
30308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ( aExp == 0x7FF ) && extractFloat64Frac( a ) ) {
30318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return propagateFloat64NaN( a, a STATUS_VAR );
30328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
30338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return a;
30348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
30358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp < 0x3FF ) {
3036bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( (uint64_t) ( float64_val(a)<<1 ) == 0 ) return a;
30378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        STATUS(float_exception_flags) |= float_flag_inexact;
30388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSign = extractFloat64Sign( a );
30398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch ( STATUS(float_rounding_mode) ) {
30408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case float_round_nearest_even:
30418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( ( aExp == 0x3FE ) && extractFloat64Frac( a ) ) {
30428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return packFloat64( aSign, 0x3FF, 0 );
30438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
30448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
30458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case float_round_down:
30468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return make_float64(aSign ? LIT64( 0xBFF0000000000000 ) : 0);
30478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case float_round_up:
30488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return make_float64(
30498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            aSign ? LIT64( 0x8000000000000000 ) : LIT64( 0x3FF0000000000000 ));
30508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
30518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloat64( aSign, 0, 0 );
30528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
30538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    lastBitMask = 1;
30548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    lastBitMask <<= 0x433 - aExp;
30558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    roundBitsMask = lastBitMask - 1;
30568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    z = float64_val(a);
30578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    roundingMode = STATUS(float_rounding_mode);
30588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( roundingMode == float_round_nearest_even ) {
30598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        z += lastBitMask>>1;
30608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
30618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
30628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else if ( roundingMode != float_round_to_zero ) {
30638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( extractFloat64Sign( make_float64(z) ) ^ ( roundingMode == float_round_up ) ) {
30648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            z += roundBitsMask;
30658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
30668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
30678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    z &= ~ roundBitsMask;
30688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( z != float64_val(a) )
30698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        STATUS(float_exception_flags) |= float_flag_inexact;
30708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return make_float64(z);
30718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
30728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
30738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
30748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat64 float64_trunc_to_int( float64 a STATUS_PARAM)
30758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
30768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int oldmode;
30778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    float64 res;
30788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    oldmode = STATUS(float_rounding_mode);
30798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    STATUS(float_rounding_mode) = float_round_to_zero;
30808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    res = float64_round_to_int(a STATUS_VAR);
30818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    STATUS(float_rounding_mode) = oldmode;
30828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return res;
30838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
30848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
30858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
30868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of adding the absolute values of the double-precision
30878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| floating-point values `a' and `b'.  If `zSign' is 1, the sum is negated
30888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| before being returned.  `zSign' is ignored if the result is a NaN.
30898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| The addition is performed according to the IEC/IEEE Standard for Binary
30908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Floating-Point Arithmetic.
30918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
30928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
30938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic float64 addFloat64Sigs( float64 a, float64 b, flag zSign STATUS_PARAM )
30948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
30958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 aExp, bExp, zExp;
3096bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig, bSig, zSig;
30978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 expDiff;
30988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
30998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloat64Frac( a );
31008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat64Exp( a );
31018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig = extractFloat64Frac( b );
31028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bExp = extractFloat64Exp( b );
31038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    expDiff = aExp - bExp;
31048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig <<= 9;
31058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig <<= 9;
31068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( 0 < expDiff ) {
31078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aExp == 0x7FF ) {
31088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( aSig ) return propagateFloat64NaN( a, b STATUS_VAR );
31098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return a;
31108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
31118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bExp == 0 ) {
31128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            --expDiff;
31138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
31148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else {
31158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            bSig |= LIT64( 0x2000000000000000 );
31168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
31178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shift64RightJamming( bSig, expDiff, &bSig );
31188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zExp = aExp;
31198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
31208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else if ( expDiff < 0 ) {
31218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bExp == 0x7FF ) {
31228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
31238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return packFloat64( zSign, 0x7FF, 0 );
31248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
31258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aExp == 0 ) {
31268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ++expDiff;
31278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
31288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else {
31298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            aSig |= LIT64( 0x2000000000000000 );
31308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
31318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shift64RightJamming( aSig, - expDiff, &aSig );
31328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zExp = bExp;
31338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
31348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
31358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aExp == 0x7FF ) {
31368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( aSig | bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
31378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return a;
31388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
31395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if ( aExp == 0 ) {
31405285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            if (STATUS(flush_to_zero)) {
31415285864985be9077e58e42235af6582dee72e841David 'Digit' Turner                if (aSig | bSig) {
31425285864985be9077e58e42235af6582dee72e841David 'Digit' Turner                    float_raise(float_flag_output_denormal STATUS_VAR);
31435285864985be9077e58e42235af6582dee72e841David 'Digit' Turner                }
31445285864985be9077e58e42235af6582dee72e841David 'Digit' Turner                return packFloat64(zSign, 0, 0);
31455285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            }
31465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return packFloat64( zSign, 0, ( aSig + bSig )>>9 );
31475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
31488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSig = LIT64( 0x4000000000000000 ) + aSig + bSig;
31498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zExp = aExp;
31508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto roundAndPack;
31518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
31528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig |= LIT64( 0x2000000000000000 );
31538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig = ( aSig + bSig )<<1;
31548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    --zExp;
3155bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( (int64_t) zSig < 0 ) {
31568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSig = aSig + bSig;
31578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ++zExp;
31588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
31598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project roundAndPack:
31608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return roundAndPackFloat64( zSign, zExp, zSig STATUS_VAR );
31618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
31638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
31658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of subtracting the absolute values of the double-
31668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| precision floating-point values `a' and `b'.  If `zSign' is 1, the
31678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| difference is negated before being returned.  `zSign' is ignored if the
31688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| result is a NaN.  The subtraction is performed according to the IEC/IEEE
31698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Standard for Binary Floating-Point Arithmetic.
31708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
31718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic float64 subFloat64Sigs( float64 a, float64 b, flag zSign STATUS_PARAM )
31738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
31748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 aExp, bExp, zExp;
3175bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig, bSig, zSig;
31768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 expDiff;
31778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloat64Frac( a );
31798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat64Exp( a );
31808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig = extractFloat64Frac( b );
31818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bExp = extractFloat64Exp( b );
31828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    expDiff = aExp - bExp;
31838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig <<= 10;
31848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig <<= 10;
31858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( 0 < expDiff ) goto aExpBigger;
31868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( expDiff < 0 ) goto bExpBigger;
31878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0x7FF ) {
31888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig | bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
31898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
31908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return float64_default_nan;
31918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
31928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0 ) {
31938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aExp = 1;
31948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        bExp = 1;
31958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
31968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bSig < aSig ) goto aBigger;
31978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSig < bSig ) goto bBigger;
31988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return packFloat64( STATUS(float_rounding_mode) == float_round_down, 0, 0 );
31998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bExpBigger:
32008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0x7FF ) {
32018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
32028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloat64( zSign ^ 1, 0x7FF, 0 );
32038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
32048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0 ) {
32058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ++expDiff;
32068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
32078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
32088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSig |= LIT64( 0x4000000000000000 );
32098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
32108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shift64RightJamming( aSig, - expDiff, &aSig );
32118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig |= LIT64( 0x4000000000000000 );
32128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bBigger:
32138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig = bSig - aSig;
32148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zExp = bExp;
32158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSign ^= 1;
32168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    goto normalizeRoundAndPack;
32178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project aExpBigger:
32188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0x7FF ) {
32198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig ) return propagateFloat64NaN( a, b STATUS_VAR );
32208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return a;
32218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
32228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0 ) {
32238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        --expDiff;
32248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
32258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
32268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        bSig |= LIT64( 0x4000000000000000 );
32278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
32288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shift64RightJamming( bSig, expDiff, &bSig );
32298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig |= LIT64( 0x4000000000000000 );
32308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project aBigger:
32318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig = aSig - bSig;
32328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zExp = aExp;
32338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project normalizeRoundAndPack:
32348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    --zExp;
32358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return normalizeRoundAndPackFloat64( zSign, zExp, zSig STATUS_VAR );
32368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
32388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
32408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of adding the double-precision floating-point values `a'
32418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| and `b'.  The operation is performed according to the IEC/IEEE Standard for
32428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Binary Floating-Point Arithmetic.
32438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
32448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat64 float64_add( float64 a, float64 b STATUS_PARAM )
32468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
32478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign;
3248bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float64_squash_input_denormal(a STATUS_VAR);
3249bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    b = float64_squash_input_denormal(b STATUS_VAR);
32508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat64Sign( a );
32528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloat64Sign( b );
32538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSign == bSign ) {
32548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return addFloat64Sigs( a, b, aSign STATUS_VAR );
32558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
32568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
32578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return subFloat64Sigs( a, b, aSign STATUS_VAR );
32588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
32598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
32618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
32638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of subtracting the double-precision floating-point values
32648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
32658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| for Binary Floating-Point Arithmetic.
32668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
32678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat64 float64_sub( float64 a, float64 b STATUS_PARAM )
32698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
32708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign;
3271bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float64_squash_input_denormal(a STATUS_VAR);
3272bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    b = float64_squash_input_denormal(b STATUS_VAR);
32738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat64Sign( a );
32758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloat64Sign( b );
32768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSign == bSign ) {
32778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return subFloat64Sigs( a, b, aSign STATUS_VAR );
32788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
32798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
32808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return addFloat64Sigs( a, b, aSign STATUS_VAR );
32818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
32828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
32848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
32868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of multiplying the double-precision floating-point values
32878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
32888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| for Binary Floating-Point Arithmetic.
32898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
32908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat64 float64_mul( float64 a, float64 b STATUS_PARAM )
32928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
32938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign, zSign;
32948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 aExp, bExp, zExp;
3295bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig, bSig, zSig0, zSig1;
3296bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
3297bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float64_squash_input_denormal(a STATUS_VAR);
3298bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    b = float64_squash_input_denormal(b STATUS_VAR);
32998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
33008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloat64Frac( a );
33018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat64Exp( a );
33028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat64Sign( a );
33038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig = extractFloat64Frac( b );
33048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bExp = extractFloat64Exp( b );
33058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloat64Sign( b );
33068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSign = aSign ^ bSign;
33078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0x7FF ) {
33088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
33098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return propagateFloat64NaN( a, b STATUS_VAR );
33108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
33118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ( bExp | bSig ) == 0 ) {
33128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_invalid STATUS_VAR);
33138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return float64_default_nan;
33148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
33158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloat64( zSign, 0x7FF, 0 );
33168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
33178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0x7FF ) {
33188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
33198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ( aExp | aSig ) == 0 ) {
33208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_invalid STATUS_VAR);
33218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return float64_default_nan;
33228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
33238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloat64( zSign, 0x7FF, 0 );
33248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
33258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0 ) {
33268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig == 0 ) return packFloat64( zSign, 0, 0 );
33278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloat64Subnormal( aSig, &aExp, &aSig );
33288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
33298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0 ) {
33308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bSig == 0 ) return packFloat64( zSign, 0, 0 );
33318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloat64Subnormal( bSig, &bExp, &bSig );
33328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
33338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zExp = aExp + bExp - 0x3FF;
33348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10;
33358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
33368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    mul64To128( aSig, bSig, &zSig0, &zSig1 );
33378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig0 |= ( zSig1 != 0 );
3338bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( 0 <= (int64_t) ( zSig0<<1 ) ) {
33398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSig0 <<= 1;
33408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        --zExp;
33418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
33428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return roundAndPackFloat64( zSign, zExp, zSig0 STATUS_VAR );
33438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
33448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
33458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
33468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
33478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of dividing the double-precision floating-point value `a'
33488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| by the corresponding value `b'.  The operation is performed according to
33498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
33508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
33518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
33528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat64 float64_div( float64 a, float64 b STATUS_PARAM )
33538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
33548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign, zSign;
33558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 aExp, bExp, zExp;
3356bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig, bSig, zSig;
3357bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t rem0, rem1;
3358bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t term0, term1;
3359bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float64_squash_input_denormal(a STATUS_VAR);
3360bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    b = float64_squash_input_denormal(b STATUS_VAR);
33618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
33628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloat64Frac( a );
33638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat64Exp( a );
33648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat64Sign( a );
33658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig = extractFloat64Frac( b );
33668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bExp = extractFloat64Exp( b );
33678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloat64Sign( b );
33688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSign = aSign ^ bSign;
33698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0x7FF ) {
33708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig ) return propagateFloat64NaN( a, b STATUS_VAR );
33718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bExp == 0x7FF ) {
33728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
33738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_invalid STATUS_VAR);
33748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return float64_default_nan;
33758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
33768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloat64( zSign, 0x7FF, 0 );
33778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
33788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0x7FF ) {
33798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
33808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloat64( zSign, 0, 0 );
33818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
33828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0 ) {
33838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bSig == 0 ) {
33848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( ( aExp | aSig ) == 0 ) {
33858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                float_raise( float_flag_invalid STATUS_VAR);
33868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return float64_default_nan;
33878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
33888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_divbyzero STATUS_VAR);
33898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return packFloat64( zSign, 0x7FF, 0 );
33908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
33918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloat64Subnormal( bSig, &bExp, &bSig );
33928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
33938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0 ) {
33948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig == 0 ) return packFloat64( zSign, 0, 0 );
33958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloat64Subnormal( aSig, &aExp, &aSig );
33968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
33978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zExp = aExp - bExp + 0x3FD;
33988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10;
33998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
34008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bSig <= ( aSig + aSig ) ) {
34018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSig >>= 1;
34028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ++zExp;
34038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
34048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig = estimateDiv128To64( aSig, 0, bSig );
34058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( ( zSig & 0x1FF ) <= 2 ) {
34068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        mul64To128( bSig, zSig, &term0, &term1 );
34078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sub128( aSig, 0, term0, term1, &rem0, &rem1 );
3408bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        while ( (int64_t) rem0 < 0 ) {
34098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            --zSig;
34108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            add128( rem0, rem1, 0, bSig, &rem0, &rem1 );
34118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
34128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSig |= ( rem1 != 0 );
34138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
34148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return roundAndPackFloat64( zSign, zExp, zSig STATUS_VAR );
34158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
34168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
34178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
34188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
34198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the remainder of the double-precision floating-point value `a'
34208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| with respect to the corresponding value `b'.  The operation is performed
34218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
34228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
34238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
34248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat64 float64_rem( float64 a, float64 b STATUS_PARAM )
34258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
34262738c26579c211c46eedf84a4e61c73243551888David Turner    flag aSign, zSign;
34278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 aExp, bExp, expDiff;
3428bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig, bSig;
3429bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t q, alternateASig;
3430bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    int64_t sigMean;
34318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3432bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float64_squash_input_denormal(a STATUS_VAR);
3433bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    b = float64_squash_input_denormal(b STATUS_VAR);
34348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloat64Frac( a );
34358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat64Exp( a );
34368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat64Sign( a );
34378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig = extractFloat64Frac( b );
34388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bExp = extractFloat64Exp( b );
34398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0x7FF ) {
34408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
34418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return propagateFloat64NaN( a, b STATUS_VAR );
34428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
34438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
34448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return float64_default_nan;
34458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
34468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0x7FF ) {
34478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
34488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return a;
34498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
34508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0 ) {
34518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bSig == 0 ) {
34528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_invalid STATUS_VAR);
34538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return float64_default_nan;
34548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
34558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloat64Subnormal( bSig, &bExp, &bSig );
34568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
34578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0 ) {
34588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig == 0 ) return a;
34598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloat64Subnormal( aSig, &aExp, &aSig );
34608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
34618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    expDiff = aExp - bExp;
34628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<11;
34638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
34648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( expDiff < 0 ) {
34658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( expDiff < -1 ) return a;
34668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSig >>= 1;
34678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
34688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    q = ( bSig <= aSig );
34698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( q ) aSig -= bSig;
34708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    expDiff -= 64;
34718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while ( 0 < expDiff ) {
34728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        q = estimateDiv128To64( aSig, 0, bSig );
34738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        q = ( 2 < q ) ? q - 2 : 0;
34748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSig = - ( ( bSig>>2 ) * q );
34758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        expDiff -= 62;
34768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
34778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    expDiff += 64;
34788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( 0 < expDiff ) {
34798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        q = estimateDiv128To64( aSig, 0, bSig );
34808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        q = ( 2 < q ) ? q - 2 : 0;
34818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        q >>= 64 - expDiff;
34828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        bSig >>= 2;
34838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
34848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
34858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
34868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSig >>= 2;
34878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        bSig >>= 2;
34888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
34898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do {
34908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        alternateASig = aSig;
34918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ++q;
34928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSig -= bSig;
3493bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    } while ( 0 <= (int64_t) aSig );
34948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sigMean = aSig + alternateASig;
34958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {
34968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSig = alternateASig;
34978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3498bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    zSign = ( (int64_t) aSig < 0 );
34998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( zSign ) aSig = - aSig;
35008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return normalizeRoundAndPackFloat64( aSign ^ zSign, bExp, aSig STATUS_VAR );
35018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
35028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
35038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
35048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
35058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the square root of the double-precision floating-point value `a'.
35068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| The operation is performed according to the IEC/IEEE Standard for Binary
35078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Floating-Point Arithmetic.
35088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
35098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
35108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat64 float64_sqrt( float64 a STATUS_PARAM )
35118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
35128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
35138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 aExp, zExp;
3514bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig, zSig, doubleZSig;
3515bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t rem0, rem1, term0, term1;
3516bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float64_squash_input_denormal(a STATUS_VAR);
35178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
35188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloat64Frac( a );
35198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat64Exp( a );
35208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat64Sign( a );
35218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0x7FF ) {
35228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig ) return propagateFloat64NaN( a, a STATUS_VAR );
35238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ! aSign ) return a;
35248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
35258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return float64_default_nan;
35268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
35278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSign ) {
35288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ( aExp | aSig ) == 0 ) return a;
35298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
35308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return float64_default_nan;
35318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
35328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0 ) {
35338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig == 0 ) return float64_zero;
35348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloat64Subnormal( aSig, &aExp, &aSig );
35358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
35368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zExp = ( ( aExp - 0x3FF )>>1 ) + 0x3FE;
35378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig |= LIT64( 0x0010000000000000 );
35388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig = estimateSqrt32( aExp, aSig>>21 );
35398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig <<= 9 - ( aExp & 1 );
35408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig = estimateDiv128To64( aSig, 0, zSig<<32 ) + ( zSig<<30 );
35418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( ( zSig & 0x1FF ) <= 5 ) {
35428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        doubleZSig = zSig<<1;
35438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        mul64To128( zSig, zSig, &term0, &term1 );
35448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sub128( aSig, 0, term0, term1, &rem0, &rem1 );
3545bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        while ( (int64_t) rem0 < 0 ) {
35468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            --zSig;
35478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            doubleZSig -= 2;
35488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            add128( rem0, rem1, zSig>>63, doubleZSig | 1, &rem0, &rem1 );
35498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
35508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSig |= ( ( rem0 | rem1 ) != 0 );
35518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
35528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return roundAndPackFloat64( 0, zExp, zSig STATUS_VAR );
35538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
35548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
35558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
35568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
35575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner| Returns the binary log of the double-precision floating-point value `a'.
35585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner| The operation is performed according to the IEC/IEEE Standard for Binary
35595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner| Floating-Point Arithmetic.
35605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner*----------------------------------------------------------------------------*/
35615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerfloat64 float64_log2( float64 a STATUS_PARAM )
35625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
35635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    flag aSign, zSign;
35645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int16 aExp;
3565bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig, aSig0, aSig1, zSig, i;
3566bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float64_squash_input_denormal(a STATUS_VAR);
35675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
35685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    aSig = extractFloat64Frac( a );
35695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    aExp = extractFloat64Exp( a );
35705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    aSign = extractFloat64Sign( a );
35715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
35725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if ( aExp == 0 ) {
35735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if ( aSig == 0 ) return packFloat64( 1, 0x7FF, 0 );
35745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        normalizeFloat64Subnormal( aSig, &aExp, &aSig );
35755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
35765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if ( aSign ) {
35775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        float_raise( float_flag_invalid STATUS_VAR);
35785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return float64_default_nan;
35795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
35805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if ( aExp == 0x7FF ) {
35815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if ( aSig ) return propagateFloat64NaN( a, float64_zero STATUS_VAR );
35825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return a;
35835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
35845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
35855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    aExp -= 0x3FF;
35865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    aSig |= LIT64( 0x0010000000000000 );
35875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    zSign = aExp < 0;
3588bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    zSig = (uint64_t)aExp << 52;
35895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (i = 1LL << 51; i > 0; i >>= 1) {
35905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        mul64To128( aSig, aSig, &aSig0, &aSig1 );
35915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        aSig = ( aSig0 << 12 ) | ( aSig1 >> 52 );
35925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if ( aSig & LIT64( 0x0020000000000000 ) ) {
35935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            aSig >>= 1;
35945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            zSig |= i;
35955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
35965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
35975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
35985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if ( zSign )
35995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        zSig = -zSig;
36005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return normalizeRoundAndPackFloat64( zSign, 0x408, zSig STATUS_VAR );
36015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
36025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
36035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/*----------------------------------------------------------------------------
36048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns 1 if the double-precision floating-point value `a' is equal to the
3605bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| corresponding value `b', and 0 otherwise.  The invalid exception is raised
3606bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| if either operand is a NaN.  Otherwise, the comparison is performed
36078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
36088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
36098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
36108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint float64_eq( float64 a, float64 b STATUS_PARAM )
36118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3612bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t av, bv;
3613bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float64_squash_input_denormal(a STATUS_VAR);
3614bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    b = float64_squash_input_denormal(b STATUS_VAR);
36158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
36168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
36178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
36188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       ) {
3619bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        float_raise( float_flag_invalid STATUS_VAR);
36208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
36218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
36228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    av = float64_val(a);
36238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bv = float64_val(b);
3624bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    return ( av == bv ) || ( (uint64_t) ( ( av | bv )<<1 ) == 0 );
36258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
36268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
36278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
36288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
36298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns 1 if the double-precision floating-point value `a' is less than or
3630bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| equal to the corresponding value `b', and 0 otherwise.  The invalid
3631bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| exception is raised if either operand is a NaN.  The comparison is performed
3632bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
36338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
36348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
36358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint float64_le( float64 a, float64 b STATUS_PARAM )
36368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
36378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign;
3638bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t av, bv;
3639bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float64_squash_input_denormal(a STATUS_VAR);
3640bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    b = float64_squash_input_denormal(b STATUS_VAR);
36418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
36428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
36438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
36448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       ) {
36458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
36468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
36478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
36488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat64Sign( a );
36498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloat64Sign( b );
36508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    av = float64_val(a);
36518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bv = float64_val(b);
3652bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( aSign != bSign ) return aSign || ( (uint64_t) ( ( av | bv )<<1 ) == 0 );
36538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ( av == bv ) || ( aSign ^ ( av < bv ) );
36548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
36558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
36568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
36578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
36588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns 1 if the double-precision floating-point value `a' is less than
3659bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| the corresponding value `b', and 0 otherwise.  The invalid exception is
3660bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| raised if either operand is a NaN.  The comparison is performed according
3661bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
36628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
36638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
36648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint float64_lt( float64 a, float64 b STATUS_PARAM )
36658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
36668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign;
3667bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t av, bv;
36688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3669bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float64_squash_input_denormal(a STATUS_VAR);
3670bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    b = float64_squash_input_denormal(b STATUS_VAR);
36718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
36728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
36738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       ) {
36748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
36758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
36768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
36778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat64Sign( a );
36788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloat64Sign( b );
36798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    av = float64_val(a);
36808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bv = float64_val(b);
3681bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( aSign != bSign ) return aSign && ( (uint64_t) ( ( av | bv )<<1 ) != 0 );
36828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ( av != bv ) && ( aSign ^ ( av < bv ) );
36838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
36848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
36858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
36868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
3687bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| Returns 1 if the double-precision floating-point values `a' and `b' cannot
3688bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| be compared, and 0 otherwise.  The invalid exception is raised if either
3689bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| operand is a NaN.  The comparison is performed according to the IEC/IEEE
3690bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| Standard for Binary Floating-Point Arithmetic.
36918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
36928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3693bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turnerint float64_unordered( float64 a, float64 b STATUS_PARAM )
36948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3695bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float64_squash_input_denormal(a STATUS_VAR);
3696bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    b = float64_squash_input_denormal(b STATUS_VAR);
36978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
36988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
36998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
37008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       ) {
37018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
3702bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        return 1;
3703bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    }
3704bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    return 0;
3705bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner}
3706bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
3707bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner/*----------------------------------------------------------------------------
3708bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| Returns 1 if the double-precision floating-point value `a' is equal to the
3709bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
3710bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| exception.The comparison is performed according to the IEC/IEEE Standard
3711bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| for Binary Floating-Point Arithmetic.
3712bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner*----------------------------------------------------------------------------*/
3713bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
3714bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turnerint float64_eq_quiet( float64 a, float64 b STATUS_PARAM )
3715bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner{
3716bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t av, bv;
3717bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float64_squash_input_denormal(a STATUS_VAR);
3718bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    b = float64_squash_input_denormal(b STATUS_VAR);
3719bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
3720bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
3721bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
3722bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner       ) {
3723bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
3724bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            float_raise( float_flag_invalid STATUS_VAR);
3725bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        }
37268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
37278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
37288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    av = float64_val(a);
37298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bv = float64_val(b);
3730bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    return ( av == bv ) || ( (uint64_t) ( ( av | bv )<<1 ) == 0 );
37318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
37328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
37338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
37348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
37358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns 1 if the double-precision floating-point value `a' is less than or
37368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs do not
37378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| cause an exception.  Otherwise, the comparison is performed according to the
37388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
37398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
37408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
37418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint float64_le_quiet( float64 a, float64 b STATUS_PARAM )
37428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
37438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign;
3744bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t av, bv;
3745bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float64_squash_input_denormal(a STATUS_VAR);
3746bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    b = float64_squash_input_denormal(b STATUS_VAR);
37478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
37488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
37498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
37508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       ) {
37518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
37528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_invalid STATUS_VAR);
37538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
37548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
37558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
37568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat64Sign( a );
37578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloat64Sign( b );
37588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    av = float64_val(a);
37598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bv = float64_val(b);
3760bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( aSign != bSign ) return aSign || ( (uint64_t) ( ( av | bv )<<1 ) == 0 );
37618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ( av == bv ) || ( aSign ^ ( av < bv ) );
37628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
37638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
37648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
37658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
37668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns 1 if the double-precision floating-point value `a' is less than
37678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
37688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| exception.  Otherwise, the comparison is performed according to the IEC/IEEE
37698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Standard for Binary Floating-Point Arithmetic.
37708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
37718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
37728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint float64_lt_quiet( float64 a, float64 b STATUS_PARAM )
37738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
37748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign;
3775bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t av, bv;
3776bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float64_squash_input_denormal(a STATUS_VAR);
3777bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    b = float64_squash_input_denormal(b STATUS_VAR);
37788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
37798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
37808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
37818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       ) {
37828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
37838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_invalid STATUS_VAR);
37848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
37858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
37868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
37878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat64Sign( a );
37888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloat64Sign( b );
37898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    av = float64_val(a);
37908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bv = float64_val(b);
3791bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( aSign != bSign ) return aSign && ( (uint64_t) ( ( av | bv )<<1 ) != 0 );
37928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ( av != bv ) && ( aSign ^ ( av < bv ) );
37938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
37948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
37958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3796bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner/*----------------------------------------------------------------------------
3797bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| Returns 1 if the double-precision floating-point values `a' and `b' cannot
3798bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| be compared, and 0 otherwise.  Quiet NaNs do not cause an exception.  The
3799bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| comparison is performed according to the IEC/IEEE Standard for Binary
3800bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| Floating-Point Arithmetic.
3801bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner*----------------------------------------------------------------------------*/
3802bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
3803bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turnerint float64_unordered_quiet( float64 a, float64 b STATUS_PARAM )
3804bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner{
3805bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float64_squash_input_denormal(a STATUS_VAR);
3806bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    b = float64_squash_input_denormal(b STATUS_VAR);
3807bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
3808bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
3809bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
3810bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner       ) {
3811bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
3812bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            float_raise( float_flag_invalid STATUS_VAR);
3813bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        }
3814bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        return 1;
3815bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    }
3816bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    return 0;
3817bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner}
3818bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
38198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef FLOATX80
38208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
38218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
38228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the extended double-precision floating-
38238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| point value `a' to the 32-bit two's complement integer format.  The
38248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| conversion is performed according to the IEC/IEEE Standard for Binary
38258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Floating-Point Arithmetic---which means in particular that the conversion
38268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| is rounded according to the current rounding mode.  If `a' is a NaN, the
38278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| largest positive integer is returned.  Otherwise, if the conversion
38288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| overflows, the largest integer with the same sign as `a' is returned.
38298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
38308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
38318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint32 floatx80_to_int32( floatx80 a STATUS_PARAM )
38328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
38338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
38348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 aExp, shiftCount;
3835bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig;
38368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
38378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloatx80Frac( a );
38388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloatx80Exp( a );
38398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloatx80Sign( a );
3840bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( ( aExp == 0x7FFF ) && (uint64_t) ( aSig<<1 ) ) aSign = 0;
38418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shiftCount = 0x4037 - aExp;
38428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( shiftCount <= 0 ) shiftCount = 1;
38438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shift64RightJamming( aSig, shiftCount, &aSig );
38448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return roundAndPackInt32( aSign, aSig STATUS_VAR );
38458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
38468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
38478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
38488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
38498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the extended double-precision floating-
38508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| point value `a' to the 32-bit two's complement integer format.  The
38518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| conversion is performed according to the IEC/IEEE Standard for Binary
38528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Floating-Point Arithmetic, except that the conversion is always rounded
38538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| toward zero.  If `a' is a NaN, the largest positive integer is returned.
38548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Otherwise, if the conversion overflows, the largest integer with the same
38558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| sign as `a' is returned.
38568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
38578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
38588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint32 floatx80_to_int32_round_to_zero( floatx80 a STATUS_PARAM )
38598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
38608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
38618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 aExp, shiftCount;
3862bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig, savedASig;
38638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 z;
38648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
38658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloatx80Frac( a );
38668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloatx80Exp( a );
38678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloatx80Sign( a );
38688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( 0x401E < aExp ) {
3869bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( ( aExp == 0x7FFF ) && (uint64_t) ( aSig<<1 ) ) aSign = 0;
38708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto invalid;
38718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
38728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else if ( aExp < 0x3FFF ) {
38738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aExp || aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
38748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
38758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
38768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shiftCount = 0x403E - aExp;
38778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    savedASig = aSig;
38788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig >>= shiftCount;
38798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    z = aSig;
38808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSign ) z = - z;
38818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( ( z < 0 ) ^ aSign ) {
38828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project invalid:
38838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
3884bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        return aSign ? (int32_t) 0x80000000 : 0x7FFFFFFF;
38858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
38868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( ( aSig<<shiftCount ) != savedASig ) {
38878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        STATUS(float_exception_flags) |= float_flag_inexact;
38888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
38898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return z;
38908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
38918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
38928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
38938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
38948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the extended double-precision floating-
38958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| point value `a' to the 64-bit two's complement integer format.  The
38968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| conversion is performed according to the IEC/IEEE Standard for Binary
38978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Floating-Point Arithmetic---which means in particular that the conversion
38988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| is rounded according to the current rounding mode.  If `a' is a NaN,
38998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| the largest positive integer is returned.  Otherwise, if the conversion
39008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| overflows, the largest integer with the same sign as `a' is returned.
39018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
39028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
39038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint64 floatx80_to_int64( floatx80 a STATUS_PARAM )
39048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
39058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
39068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 aExp, shiftCount;
3907bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig, aSigExtra;
39088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
39098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloatx80Frac( a );
39108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloatx80Exp( a );
39118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloatx80Sign( a );
39128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shiftCount = 0x403E - aExp;
39138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( shiftCount <= 0 ) {
39148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( shiftCount ) {
39158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_invalid STATUS_VAR);
39168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (    ! aSign
39178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 || (    ( aExp == 0x7FFF )
39188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                      && ( aSig != LIT64( 0x8000000000000000 ) ) )
39198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               ) {
39208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return LIT64( 0x7FFFFFFFFFFFFFFF );
39218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
3922bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            return (int64_t) LIT64( 0x8000000000000000 );
39238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
39248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSigExtra = 0;
39258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
39268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
39278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shift64ExtraRightJamming( aSig, 0, shiftCount, &aSig, &aSigExtra );
39288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
39298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return roundAndPackInt64( aSign, aSig, aSigExtra STATUS_VAR );
39308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
39318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
39328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
39338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
39348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the extended double-precision floating-
39358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| point value `a' to the 64-bit two's complement integer format.  The
39368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| conversion is performed according to the IEC/IEEE Standard for Binary
39378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Floating-Point Arithmetic, except that the conversion is always rounded
39388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| toward zero.  If `a' is a NaN, the largest positive integer is returned.
39398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Otherwise, if the conversion overflows, the largest integer with the same
39408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| sign as `a' is returned.
39418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
39428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
39438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint64 floatx80_to_int64_round_to_zero( floatx80 a STATUS_PARAM )
39448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
39458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
39468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 aExp, shiftCount;
3947bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig;
39488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64 z;
39498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
39508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloatx80Frac( a );
39518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloatx80Exp( a );
39528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloatx80Sign( a );
39538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shiftCount = aExp - 0x403E;
39548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( 0 <= shiftCount ) {
39558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSig &= LIT64( 0x7FFFFFFFFFFFFFFF );
39568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ( a.high != 0xC03E ) || aSig ) {
39578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_invalid STATUS_VAR);
39588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( ! aSign || ( ( aExp == 0x7FFF ) && aSig ) ) {
39598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return LIT64( 0x7FFFFFFFFFFFFFFF );
39608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
39618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3962bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        return (int64_t) LIT64( 0x8000000000000000 );
39638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
39648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else if ( aExp < 0x3FFF ) {
39658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aExp | aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
39668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
39678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
39688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    z = aSig>>( - shiftCount );
3969bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( (uint64_t) ( aSig<<( shiftCount & 63 ) ) ) {
39708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        STATUS(float_exception_flags) |= float_flag_inexact;
39718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
39728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSign ) z = - z;
39738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return z;
39748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
39758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
39768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
39778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
39788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the extended double-precision floating-
39798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| point value `a' to the single-precision floating-point format.  The
39808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| conversion is performed according to the IEC/IEEE Standard for Binary
39818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Floating-Point Arithmetic.
39828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
39838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
39848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 floatx80_to_float32( floatx80 a STATUS_PARAM )
39858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
39868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
39878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 aExp;
3988bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig;
39898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
39908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloatx80Frac( a );
39918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloatx80Exp( a );
39928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloatx80Sign( a );
39938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0x7FFF ) {
3994bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( (uint64_t) ( aSig<<1 ) ) {
3995bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            return commonNaNToFloat32( floatx80ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
39968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
39978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloat32( aSign, 0xFF, 0 );
39988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
39998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shift64RightJamming( aSig, 33, &aSig );
40008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp || aSig ) aExp -= 0x3F81;
40018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return roundAndPackFloat32( aSign, aExp, aSig STATUS_VAR );
40028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
40038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
40048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
40058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
40068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the extended double-precision floating-
40078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| point value `a' to the double-precision floating-point format.  The
40088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| conversion is performed according to the IEC/IEEE Standard for Binary
40098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Floating-Point Arithmetic.
40108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
40118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
40128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat64 floatx80_to_float64( floatx80 a STATUS_PARAM )
40138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
40148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
40158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 aExp;
4016bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig, zSig;
40178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
40188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloatx80Frac( a );
40198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloatx80Exp( a );
40208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloatx80Sign( a );
40218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0x7FFF ) {
4022bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( (uint64_t) ( aSig<<1 ) ) {
4023bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            return commonNaNToFloat64( floatx80ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
40248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
40258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloat64( aSign, 0x7FF, 0 );
40268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
40278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shift64RightJamming( aSig, 1, &zSig );
40288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp || aSig ) aExp -= 0x3C01;
40298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return roundAndPackFloat64( aSign, aExp, zSig STATUS_VAR );
40308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
40318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
40328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
40338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef FLOAT128
40348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
40358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
40368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the extended double-precision floating-
40378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| point value `a' to the quadruple-precision floating-point format.  The
40388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| conversion is performed according to the IEC/IEEE Standard for Binary
40398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Floating-Point Arithmetic.
40408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
40418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
40428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat128 floatx80_to_float128( floatx80 a STATUS_PARAM )
40438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
40448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
40458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int16 aExp;
4046bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig, zSig0, zSig1;
40478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
40488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloatx80Frac( a );
40498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloatx80Exp( a );
40508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloatx80Sign( a );
4051bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( ( aExp == 0x7FFF ) && (uint64_t) ( aSig<<1 ) ) {
4052bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        return commonNaNToFloat128( floatx80ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
40538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
40548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shift128Right( aSig<<1, 0, 16, &zSig0, &zSig1 );
40558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return packFloat128( aSign, aExp, zSig0, zSig1 );
40568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
40578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
40588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
40598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
40608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
40618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
40628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Rounds the extended double-precision floating-point value `a' to an integer,
40638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| and returns the result as an extended quadruple-precision floating-point
40648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| value.  The operation is performed according to the IEC/IEEE Standard for
40658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Binary Floating-Point Arithmetic.
40668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
40678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
40688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloatx80 floatx80_round_to_int( floatx80 a STATUS_PARAM )
40698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
40708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
40718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 aExp;
4072bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t lastBitMask, roundBitsMask;
40738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8 roundingMode;
40748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    floatx80 z;
40758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
40768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloatx80Exp( a );
40778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( 0x403E <= aExp ) {
4078bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( ( aExp == 0x7FFF ) && (uint64_t) ( extractFloatx80Frac( a )<<1 ) ) {
40798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return propagateFloatx80NaN( a, a STATUS_VAR );
40808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
40818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return a;
40828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
40838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp < 0x3FFF ) {
40848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (    ( aExp == 0 )
4085bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner             && ( (uint64_t) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) {
40868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return a;
40878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
40888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        STATUS(float_exception_flags) |= float_flag_inexact;
40898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSign = extractFloatx80Sign( a );
40908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch ( STATUS(float_rounding_mode) ) {
40918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case float_round_nearest_even:
4092bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            if ( ( aExp == 0x3FFE ) && (uint64_t) ( extractFloatx80Frac( a )<<1 )
40938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               ) {
40948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return
40958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) );
40968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
40978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
40988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case float_round_down:
40998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return
41008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  aSign ?
41018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                      packFloatx80( 1, 0x3FFF, LIT64( 0x8000000000000000 ) )
41028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                : packFloatx80( 0, 0, 0 );
41038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case float_round_up:
41048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return
41058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  aSign ? packFloatx80( 1, 0, 0 )
41068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                : packFloatx80( 0, 0x3FFF, LIT64( 0x8000000000000000 ) );
41078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
41088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloatx80( aSign, 0, 0 );
41098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
41108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    lastBitMask = 1;
41118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    lastBitMask <<= 0x403E - aExp;
41128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    roundBitsMask = lastBitMask - 1;
41138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    z = a;
41148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    roundingMode = STATUS(float_rounding_mode);
41158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( roundingMode == float_round_nearest_even ) {
41168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        z.low += lastBitMask>>1;
41178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;
41188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
41198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else if ( roundingMode != float_round_to_zero ) {
41208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( extractFloatx80Sign( z ) ^ ( roundingMode == float_round_up ) ) {
41218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            z.low += roundBitsMask;
41228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
41238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
41248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    z.low &= ~ roundBitsMask;
41258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( z.low == 0 ) {
41268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ++z.high;
41278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        z.low = LIT64( 0x8000000000000000 );
41288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
41298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( z.low != a.low ) STATUS(float_exception_flags) |= float_flag_inexact;
41308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return z;
41318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
41328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
41338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
41348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
41358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of adding the absolute values of the extended double-
41368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| precision floating-point values `a' and `b'.  If `zSign' is 1, the sum is
41378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| negated before being returned.  `zSign' is ignored if the result is a NaN.
41388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| The addition is performed according to the IEC/IEEE Standard for Binary
41398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Floating-Point Arithmetic.
41408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
41418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
41428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign STATUS_PARAM)
41438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
41448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 aExp, bExp, zExp;
4145bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig, bSig, zSig0, zSig1;
41468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 expDiff;
41478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
41488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloatx80Frac( a );
41498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloatx80Exp( a );
41508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig = extractFloatx80Frac( b );
41518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bExp = extractFloatx80Exp( b );
41528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    expDiff = aExp - bExp;
41538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( 0 < expDiff ) {
41548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aExp == 0x7FFF ) {
4155bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            if ( (uint64_t) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
41568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return a;
41578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
41588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bExp == 0 ) --expDiff;
41598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shift64ExtraRightJamming( bSig, 0, expDiff, &bSig, &zSig1 );
41608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zExp = aExp;
41618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
41628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else if ( expDiff < 0 ) {
41638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bExp == 0x7FFF ) {
4164bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
41658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
41668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
41678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aExp == 0 ) ++expDiff;
41688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shift64ExtraRightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
41698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zExp = bExp;
41708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
41718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
41728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aExp == 0x7FFF ) {
4173bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            if ( (uint64_t) ( ( aSig | bSig )<<1 ) ) {
41748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return propagateFloatx80NaN( a, b STATUS_VAR );
41758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
41768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return a;
41778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
41788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSig1 = 0;
41798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSig0 = aSig + bSig;
41808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aExp == 0 ) {
41818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            normalizeFloatx80Subnormal( zSig0, &zExp, &zSig0 );
41828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto roundAndPack;
41838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
41848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zExp = aExp;
41858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto shiftRight1;
41868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
41878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig0 = aSig + bSig;
4188bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( (int64_t) zSig0 < 0 ) goto roundAndPack;
41898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project shiftRight1:
41908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shift64ExtraRightJamming( zSig0, zSig1, 1, &zSig0, &zSig1 );
41918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig0 |= LIT64( 0x8000000000000000 );
41928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ++zExp;
41938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project roundAndPack:
41948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return
41958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        roundAndPackFloatx80(
41968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            STATUS(floatx80_rounding_precision), zSign, zExp, zSig0, zSig1 STATUS_VAR );
41978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
41988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
41998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
42008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
42018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of subtracting the absolute values of the extended
42028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| double-precision floating-point values `a' and `b'.  If `zSign' is 1, the
42038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| difference is negated before being returned.  `zSign' is ignored if the
42048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| result is a NaN.  The subtraction is performed according to the IEC/IEEE
42058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Standard for Binary Floating-Point Arithmetic.
42068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
42078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
42088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign STATUS_PARAM )
42098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
42108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 aExp, bExp, zExp;
4211bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig, bSig, zSig0, zSig1;
42128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 expDiff;
42138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    floatx80 z;
42148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
42158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloatx80Frac( a );
42168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloatx80Exp( a );
42178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig = extractFloatx80Frac( b );
42188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bExp = extractFloatx80Exp( b );
42198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    expDiff = aExp - bExp;
42208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( 0 < expDiff ) goto aExpBigger;
42218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( expDiff < 0 ) goto bExpBigger;
42228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0x7FFF ) {
4223bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( (uint64_t) ( ( aSig | bSig )<<1 ) ) {
42248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return propagateFloatx80NaN( a, b STATUS_VAR );
42258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
42268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
42278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        z.low = floatx80_default_nan_low;
42288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        z.high = floatx80_default_nan_high;
42298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return z;
42308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
42318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0 ) {
42328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aExp = 1;
42338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        bExp = 1;
42348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
42358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig1 = 0;
42368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bSig < aSig ) goto aBigger;
42378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSig < bSig ) goto bBigger;
42388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return packFloatx80( STATUS(float_rounding_mode) == float_round_down, 0, 0 );
42398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bExpBigger:
42408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0x7FFF ) {
4241bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
42428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloatx80( zSign ^ 1, 0x7FFF, LIT64( 0x8000000000000000 ) );
42438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
42448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0 ) ++expDiff;
42458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shift128RightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
42468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bBigger:
42478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sub128( bSig, 0, aSig, zSig1, &zSig0, &zSig1 );
42488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zExp = bExp;
42498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSign ^= 1;
42508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    goto normalizeRoundAndPack;
42518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project aExpBigger:
42528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0x7FFF ) {
4253bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( (uint64_t) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
42548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return a;
42558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
42568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0 ) --expDiff;
42578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shift128RightJamming( bSig, 0, expDiff, &bSig, &zSig1 );
42588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project aBigger:
42598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sub128( aSig, 0, bSig, zSig1, &zSig0, &zSig1 );
42608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zExp = aExp;
42618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project normalizeRoundAndPack:
42628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return
42638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeRoundAndPackFloatx80(
42648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            STATUS(floatx80_rounding_precision), zSign, zExp, zSig0, zSig1 STATUS_VAR );
42658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
42668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
42678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
42688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
42698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of adding the extended double-precision floating-point
42708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| values `a' and `b'.  The operation is performed according to the IEC/IEEE
42718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Standard for Binary Floating-Point Arithmetic.
42728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
42738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
42748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloatx80 floatx80_add( floatx80 a, floatx80 b STATUS_PARAM )
42758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
42768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign;
42778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
42788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloatx80Sign( a );
42798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloatx80Sign( b );
42808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSign == bSign ) {
42818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return addFloatx80Sigs( a, b, aSign STATUS_VAR );
42828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
42838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
42848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return subFloatx80Sigs( a, b, aSign STATUS_VAR );
42858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
42868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
42878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
42888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
42898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
42908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of subtracting the extended double-precision floating-
42918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| point values `a' and `b'.  The operation is performed according to the
42928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
42938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
42948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
42958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloatx80 floatx80_sub( floatx80 a, floatx80 b STATUS_PARAM )
42968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
42978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign;
42988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
42998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloatx80Sign( a );
43008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloatx80Sign( b );
43018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSign == bSign ) {
43028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return subFloatx80Sigs( a, b, aSign STATUS_VAR );
43038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
43048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
43058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return addFloatx80Sigs( a, b, aSign STATUS_VAR );
43068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
43078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
43088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
43098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
43108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
43118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of multiplying the extended double-precision floating-
43128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| point values `a' and `b'.  The operation is performed according to the
43138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
43148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
43158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
43168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloatx80 floatx80_mul( floatx80 a, floatx80 b STATUS_PARAM )
43178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
43188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign, zSign;
43198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 aExp, bExp, zExp;
4320bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig, bSig, zSig0, zSig1;
43218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    floatx80 z;
43228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
43238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloatx80Frac( a );
43248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloatx80Exp( a );
43258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloatx80Sign( a );
43268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig = extractFloatx80Frac( b );
43278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bExp = extractFloatx80Exp( b );
43288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloatx80Sign( b );
43298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSign = aSign ^ bSign;
43308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0x7FFF ) {
4331bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if (    (uint64_t) ( aSig<<1 )
4332bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner             || ( ( bExp == 0x7FFF ) && (uint64_t) ( bSig<<1 ) ) ) {
43338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return propagateFloatx80NaN( a, b STATUS_VAR );
43348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
43358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ( bExp | bSig ) == 0 ) goto invalid;
43368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
43378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
43388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0x7FFF ) {
4339bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
43408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ( aExp | aSig ) == 0 ) {
43418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project invalid:
43428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_invalid STATUS_VAR);
43438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            z.low = floatx80_default_nan_low;
43448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            z.high = floatx80_default_nan_high;
43458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return z;
43468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
43478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
43488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
43498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0 ) {
43508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
43518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
43528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
43538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0 ) {
43548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bSig == 0 ) return packFloatx80( zSign, 0, 0 );
43558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
43568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
43578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zExp = aExp + bExp - 0x3FFE;
43588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    mul64To128( aSig, bSig, &zSig0, &zSig1 );
4359bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( 0 < (int64_t) zSig0 ) {
43608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shortShift128Left( zSig0, zSig1, 1, &zSig0, &zSig1 );
43618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        --zExp;
43628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
43638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return
43648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        roundAndPackFloatx80(
43658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            STATUS(floatx80_rounding_precision), zSign, zExp, zSig0, zSig1 STATUS_VAR );
43668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
43678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
43688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
43698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
43708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of dividing the extended double-precision floating-point
43718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| value `a' by the corresponding value `b'.  The operation is performed
43728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
43738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
43748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
43758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloatx80 floatx80_div( floatx80 a, floatx80 b STATUS_PARAM )
43768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
43778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign, zSign;
43788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 aExp, bExp, zExp;
4379bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig, bSig, zSig0, zSig1;
4380bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t rem0, rem1, rem2, term0, term1, term2;
43818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    floatx80 z;
43828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
43838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloatx80Frac( a );
43848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloatx80Exp( a );
43858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloatx80Sign( a );
43868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig = extractFloatx80Frac( b );
43878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bExp = extractFloatx80Exp( b );
43888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloatx80Sign( b );
43898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSign = aSign ^ bSign;
43908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0x7FFF ) {
4391bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( (uint64_t) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
43928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bExp == 0x7FFF ) {
4393bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
43948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto invalid;
43958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
43968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
43978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
43988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0x7FFF ) {
4399bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
44008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloatx80( zSign, 0, 0 );
44018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
44028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0 ) {
44038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bSig == 0 ) {
44048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( ( aExp | aSig ) == 0 ) {
44058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project invalid:
44068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                float_raise( float_flag_invalid STATUS_VAR);
44078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                z.low = floatx80_default_nan_low;
44088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                z.high = floatx80_default_nan_high;
44098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return z;
44108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
44118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_divbyzero STATUS_VAR);
44128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
44138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
44148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
44158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
44168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0 ) {
44178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
44188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
44198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
44208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zExp = aExp - bExp + 0x3FFE;
44218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    rem1 = 0;
44228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bSig <= aSig ) {
44238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shift128Right( aSig, 0, 1, &aSig, &rem1 );
44248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ++zExp;
44258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
44268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig0 = estimateDiv128To64( aSig, rem1, bSig );
44278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    mul64To128( bSig, zSig0, &term0, &term1 );
44288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sub128( aSig, rem1, term0, term1, &rem0, &rem1 );
4429bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    while ( (int64_t) rem0 < 0 ) {
44308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        --zSig0;
44318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        add128( rem0, rem1, 0, bSig, &rem0, &rem1 );
44328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
44338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig1 = estimateDiv128To64( rem1, 0, bSig );
4434bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( (uint64_t) ( zSig1<<1 ) <= 8 ) {
44358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        mul64To128( bSig, zSig1, &term1, &term2 );
44368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sub128( rem1, 0, term1, term2, &rem1, &rem2 );
4437bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        while ( (int64_t) rem1 < 0 ) {
44388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            --zSig1;
44398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            add128( rem1, rem2, 0, bSig, &rem1, &rem2 );
44408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
44418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSig1 |= ( ( rem1 | rem2 ) != 0 );
44428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
44438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return
44448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        roundAndPackFloatx80(
44458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            STATUS(floatx80_rounding_precision), zSign, zExp, zSig0, zSig1 STATUS_VAR );
44468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
44478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
44488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
44498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
44508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the remainder of the extended double-precision floating-point value
44518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `a' with respect to the corresponding value `b'.  The operation is performed
44528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
44538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
44548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
44558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloatx80 floatx80_rem( floatx80 a, floatx80 b STATUS_PARAM )
44568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
44572738c26579c211c46eedf84a4e61c73243551888David Turner    flag aSign, zSign;
44588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 aExp, bExp, expDiff;
4459bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig0, aSig1, bSig;
4460bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t q, term0, term1, alternateASig0, alternateASig1;
44618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    floatx80 z;
44628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
44638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig0 = extractFloatx80Frac( a );
44648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloatx80Exp( a );
44658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloatx80Sign( a );
44668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig = extractFloatx80Frac( b );
44678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bExp = extractFloatx80Exp( b );
44688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0x7FFF ) {
4469bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if (    (uint64_t) ( aSig0<<1 )
4470bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner             || ( ( bExp == 0x7FFF ) && (uint64_t) ( bSig<<1 ) ) ) {
44718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return propagateFloatx80NaN( a, b STATUS_VAR );
44728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
44738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto invalid;
44748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
44758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0x7FFF ) {
4476bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
44778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return a;
44788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
44798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0 ) {
44808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bSig == 0 ) {
44818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project invalid:
44828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_invalid STATUS_VAR);
44838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            z.low = floatx80_default_nan_low;
44848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            z.high = floatx80_default_nan_high;
44858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return z;
44868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
44878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
44888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
44898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0 ) {
4490bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( (uint64_t) ( aSig0<<1 ) == 0 ) return a;
44918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
44928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
44938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig |= LIT64( 0x8000000000000000 );
44948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSign = aSign;
44958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    expDiff = aExp - bExp;
44968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig1 = 0;
44978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( expDiff < 0 ) {
44988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( expDiff < -1 ) return a;
44998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shift128Right( aSig0, 0, 1, &aSig0, &aSig1 );
45008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        expDiff = 0;
45018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
45028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    q = ( bSig <= aSig0 );
45038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( q ) aSig0 -= bSig;
45048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    expDiff -= 64;
45058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while ( 0 < expDiff ) {
45068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        q = estimateDiv128To64( aSig0, aSig1, bSig );
45078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        q = ( 2 < q ) ? q - 2 : 0;
45088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        mul64To128( bSig, q, &term0, &term1 );
45098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
45108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 );
45118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        expDiff -= 62;
45128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
45138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    expDiff += 64;
45148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( 0 < expDiff ) {
45158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        q = estimateDiv128To64( aSig0, aSig1, bSig );
45168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        q = ( 2 < q ) ? q - 2 : 0;
45178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        q >>= 64 - expDiff;
45188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        mul64To128( bSig, q<<( 64 - expDiff ), &term0, &term1 );
45198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
45208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shortShift128Left( 0, bSig, 64 - expDiff, &term0, &term1 );
45218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        while ( le128( term0, term1, aSig0, aSig1 ) ) {
45228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ++q;
45238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
45248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
45258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
45268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
45278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        term1 = 0;
45288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        term0 = bSig;
45298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
45308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 );
45318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (    lt128( alternateASig0, alternateASig1, aSig0, aSig1 )
45328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         || (    eq128( alternateASig0, alternateASig1, aSig0, aSig1 )
45338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              && ( q & 1 ) )
45348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       ) {
45358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSig0 = alternateASig0;
45368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSig1 = alternateASig1;
45378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSign = ! zSign;
45388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
45398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return
45408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeRoundAndPackFloatx80(
45418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            80, zSign, bExp + expDiff, aSig0, aSig1 STATUS_VAR );
45428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
45438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
45448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
45458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
45468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the square root of the extended double-precision floating-point
45478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| value `a'.  The operation is performed according to the IEC/IEEE Standard
45488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| for Binary Floating-Point Arithmetic.
45498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
45508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
45518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloatx80 floatx80_sqrt( floatx80 a STATUS_PARAM )
45528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
45538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
45548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 aExp, zExp;
4555bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig0, aSig1, zSig0, zSig1, doubleZSig0;
4556bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t rem0, rem1, rem2, rem3, term0, term1, term2, term3;
45578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    floatx80 z;
45588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
45598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig0 = extractFloatx80Frac( a );
45608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloatx80Exp( a );
45618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloatx80Sign( a );
45628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0x7FFF ) {
4563bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( (uint64_t) ( aSig0<<1 ) ) return propagateFloatx80NaN( a, a STATUS_VAR );
45648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ! aSign ) return a;
45658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto invalid;
45668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
45678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSign ) {
45688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ( aExp | aSig0 ) == 0 ) return a;
45698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project invalid:
45708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
45718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        z.low = floatx80_default_nan_low;
45728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        z.high = floatx80_default_nan_high;
45738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return z;
45748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
45758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0 ) {
45768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig0 == 0 ) return packFloatx80( 0, 0, 0 );
45778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
45788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
45798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFF;
45808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig0 = estimateSqrt32( aExp, aSig0>>32 );
45818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shift128Right( aSig0, 0, 2 + ( aExp & 1 ), &aSig0, &aSig1 );
45828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 );
45838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    doubleZSig0 = zSig0<<1;
45848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    mul64To128( zSig0, zSig0, &term0, &term1 );
45858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 );
4586bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    while ( (int64_t) rem0 < 0 ) {
45878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        --zSig0;
45888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        doubleZSig0 -= 2;
45898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 );
45908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
45918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 );
45928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( ( zSig1 & LIT64( 0x3FFFFFFFFFFFFFFF ) ) <= 5 ) {
45938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( zSig1 == 0 ) zSig1 = 1;
45948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        mul64To128( doubleZSig0, zSig1, &term1, &term2 );
45958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sub128( rem1, 0, term1, term2, &rem1, &rem2 );
45968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        mul64To128( zSig1, zSig1, &term2, &term3 );
45978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 );
4598bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        while ( (int64_t) rem1 < 0 ) {
45998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            --zSig1;
46008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            shortShift128Left( 0, zSig1, 1, &term2, &term3 );
46018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            term3 |= 1;
46028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            term2 |= doubleZSig0;
46038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 );
46048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
46058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
46068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
46078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shortShift128Left( 0, zSig1, 1, &zSig0, &zSig1 );
46088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig0 |= doubleZSig0;
46098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return
46108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        roundAndPackFloatx80(
46118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            STATUS(floatx80_rounding_precision), 0, zExp, zSig0, zSig1 STATUS_VAR );
46128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
46138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
46148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
46158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
4616bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| Returns 1 if the extended double-precision floating-point value `a' is equal
4617bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| to the corresponding value `b', and 0 otherwise.  The invalid exception is
4618bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| raised if either operand is a NaN.  Otherwise, the comparison is performed
4619bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
46208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
46218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
46228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM )
46238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
46248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
46258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
4626bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner              && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
46278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         || (    ( extractFloatx80Exp( b ) == 0x7FFF )
4628bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner              && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
46298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       ) {
4630bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        float_raise( float_flag_invalid STATUS_VAR);
46318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
46328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
46338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return
46348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           ( a.low == b.low )
46358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        && (    ( a.high == b.high )
46368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             || (    ( a.low == 0 )
4637bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner                  && ( (uint16_t) ( ( a.high | b.high )<<1 ) == 0 ) )
46388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           );
46398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
46408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
46418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
46428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
46438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns 1 if the extended double-precision floating-point value `a' is
46448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| less than or equal to the corresponding value `b', and 0 otherwise.  The
4645bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| invalid exception is raised if either operand is a NaN.  The comparison is
4646bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| performed according to the IEC/IEEE Standard for Binary Floating-Point
4647bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| Arithmetic.
46488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
46498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
46508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint floatx80_le( floatx80 a, floatx80 b STATUS_PARAM )
46518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
46528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign;
46538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
46548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
4655bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner              && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
46568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         || (    ( extractFloatx80Exp( b ) == 0x7FFF )
4657bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner              && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
46588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       ) {
46598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
46608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
46618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
46628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloatx80Sign( a );
46638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloatx80Sign( b );
46648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSign != bSign ) {
46658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return
46668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               aSign
4667bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            || (    ( ( (uint16_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
46688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 == 0 );
46698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
46708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return
46718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          aSign ? le128( b.high, b.low, a.high, a.low )
46728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        : le128( a.high, a.low, b.high, b.low );
46738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
46748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
46758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
46768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
46778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns 1 if the extended double-precision floating-point value `a' is
4678bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| less than the corresponding value `b', and 0 otherwise.  The invalid
4679bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| exception is raised if either operand is a NaN.  The comparison is performed
4680bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
46818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
46828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
46838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM )
46848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
46858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign;
46868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
46878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
4688bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner              && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
46898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         || (    ( extractFloatx80Exp( b ) == 0x7FFF )
4690bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner              && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
46918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       ) {
46928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
46938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
46948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
46958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloatx80Sign( a );
46968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloatx80Sign( b );
46978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSign != bSign ) {
46988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return
46998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               aSign
4700bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            && (    ( ( (uint16_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
47018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 != 0 );
47028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
47038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return
47048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          aSign ? lt128( b.high, b.low, a.high, a.low )
47058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        : lt128( a.high, a.low, b.high, b.low );
47068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
47078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
47088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
47098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
4710bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| Returns 1 if the extended double-precision floating-point values `a' and `b'
4711bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| cannot be compared, and 0 otherwise.  The invalid exception is raised if
4712bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| either operand is a NaN.   The comparison is performed according to the
4713bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
47148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
4715bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turnerint floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM )
4716bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner{
4717bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
4718bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner              && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
4719bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner         || (    ( extractFloatx80Exp( b ) == 0x7FFF )
4720bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner              && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
4721bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner       ) {
4722bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        float_raise( float_flag_invalid STATUS_VAR);
4723bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        return 1;
4724bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    }
4725bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    return 0;
4726bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner}
47278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4728bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner/*----------------------------------------------------------------------------
4729bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| Returns 1 if the extended double-precision floating-point value `a' is
4730bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs do not
4731bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| cause an exception.  The comparison is performed according to the IEC/IEEE
4732bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| Standard for Binary Floating-Point Arithmetic.
4733bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner*----------------------------------------------------------------------------*/
4734bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
4735bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turnerint floatx80_eq_quiet( floatx80 a, floatx80 b STATUS_PARAM )
47368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
47378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
47388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
4739bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner              && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
47408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         || (    ( extractFloatx80Exp( b ) == 0x7FFF )
4741bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner              && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
47428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       ) {
4743bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if (    floatx80_is_signaling_nan( a )
4744bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner             || floatx80_is_signaling_nan( b ) ) {
4745bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            float_raise( float_flag_invalid STATUS_VAR);
4746bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        }
47478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
47488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
47498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return
47508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           ( a.low == b.low )
47518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        && (    ( a.high == b.high )
47528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             || (    ( a.low == 0 )
4753bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner                  && ( (uint16_t) ( ( a.high | b.high )<<1 ) == 0 ) )
47548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           );
47558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
47568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
47578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
47588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
47598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns 1 if the extended double-precision floating-point value `a' is less
47608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| than or equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs
47618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| do not cause an exception.  Otherwise, the comparison is performed according
47628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
47638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
47648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
47658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint floatx80_le_quiet( floatx80 a, floatx80 b STATUS_PARAM )
47668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
47678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign;
47688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
47698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
4770bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner              && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
47718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         || (    ( extractFloatx80Exp( b ) == 0x7FFF )
4772bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner              && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
47738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       ) {
47748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (    floatx80_is_signaling_nan( a )
47758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             || floatx80_is_signaling_nan( b ) ) {
47768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_invalid STATUS_VAR);
47778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
47788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
47798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
47808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloatx80Sign( a );
47818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloatx80Sign( b );
47828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSign != bSign ) {
47838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return
47848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               aSign
4785bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            || (    ( ( (uint16_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
47868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 == 0 );
47878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
47888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return
47898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          aSign ? le128( b.high, b.low, a.high, a.low )
47908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        : le128( a.high, a.low, b.high, b.low );
47918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
47928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
47938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
47948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
47958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns 1 if the extended double-precision floating-point value `a' is less
47968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| than the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause
47978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| an exception.  Otherwise, the comparison is performed according to the
47988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
47998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
48008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
48018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM )
48028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
48038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign;
48048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
48058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
4806bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner              && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
48078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         || (    ( extractFloatx80Exp( b ) == 0x7FFF )
4808bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner              && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
48098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       ) {
48108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (    floatx80_is_signaling_nan( a )
48118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             || floatx80_is_signaling_nan( b ) ) {
48128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_invalid STATUS_VAR);
48138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
48148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
48158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
48168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloatx80Sign( a );
48178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloatx80Sign( b );
48188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSign != bSign ) {
48198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return
48208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               aSign
4821bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            && (    ( ( (uint16_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
48228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 != 0 );
48238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
48248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return
48258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          aSign ? lt128( b.high, b.low, a.high, a.low )
48268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        : lt128( a.high, a.low, b.high, b.low );
48278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
48288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
48298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4830bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner/*----------------------------------------------------------------------------
4831bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| Returns 1 if the extended double-precision floating-point values `a' and `b'
4832bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| cannot be compared, and 0 otherwise.  Quiet NaNs do not cause an exception.
4833bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| The comparison is performed according to the IEC/IEEE Standard for Binary
4834bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| Floating-Point Arithmetic.
4835bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner*----------------------------------------------------------------------------*/
4836bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turnerint floatx80_unordered_quiet( floatx80 a, floatx80 b STATUS_PARAM )
4837bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner{
4838bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
4839bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner              && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
4840bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner         || (    ( extractFloatx80Exp( b ) == 0x7FFF )
4841bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner              && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
4842bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner       ) {
4843bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if (    floatx80_is_signaling_nan( a )
4844bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner             || floatx80_is_signaling_nan( b ) ) {
4845bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            float_raise( float_flag_invalid STATUS_VAR);
4846bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        }
4847bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        return 1;
4848bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    }
4849bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    return 0;
4850bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner}
4851bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
48528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
48538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
48548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef FLOAT128
48558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
48568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
48578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the quadruple-precision floating-point
48588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| value `a' to the 32-bit two's complement integer format.  The conversion
48598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| is performed according to the IEC/IEEE Standard for Binary Floating-Point
48608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Arithmetic---which means in particular that the conversion is rounded
48618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| according to the current rounding mode.  If `a' is a NaN, the largest
48628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| positive integer is returned.  Otherwise, if the conversion overflows, the
48638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| largest integer with the same sign as `a' is returned.
48648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
48658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
48668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint32 float128_to_int32( float128 a STATUS_PARAM )
48678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
48688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
48698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 aExp, shiftCount;
4870bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig0, aSig1;
48718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
48728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig1 = extractFloat128Frac1( a );
48738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig0 = extractFloat128Frac0( a );
48748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat128Exp( a );
48758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat128Sign( a );
48768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( ( aExp == 0x7FFF ) && ( aSig0 | aSig1 ) ) aSign = 0;
48778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 );
48788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig0 |= ( aSig1 != 0 );
48798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shiftCount = 0x4028 - aExp;
48808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( 0 < shiftCount ) shift64RightJamming( aSig0, shiftCount, &aSig0 );
48818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return roundAndPackInt32( aSign, aSig0 STATUS_VAR );
48828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
48838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
48848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
48858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
48868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the quadruple-precision floating-point
48878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| value `a' to the 32-bit two's complement integer format.  The conversion
48888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| is performed according to the IEC/IEEE Standard for Binary Floating-Point
48898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Arithmetic, except that the conversion is always rounded toward zero.  If
48908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `a' is a NaN, the largest positive integer is returned.  Otherwise, if the
48918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| conversion overflows, the largest integer with the same sign as `a' is
48928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| returned.
48938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
48948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
48958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint32 float128_to_int32_round_to_zero( float128 a STATUS_PARAM )
48968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
48978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
48988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 aExp, shiftCount;
4899bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig0, aSig1, savedASig;
49008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 z;
49018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
49028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig1 = extractFloat128Frac1( a );
49038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig0 = extractFloat128Frac0( a );
49048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat128Exp( a );
49058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat128Sign( a );
49068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig0 |= ( aSig1 != 0 );
49078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( 0x401E < aExp ) {
49088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ( aExp == 0x7FFF ) && aSig0 ) aSign = 0;
49098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto invalid;
49108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
49118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else if ( aExp < 0x3FFF ) {
49128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aExp || aSig0 ) STATUS(float_exception_flags) |= float_flag_inexact;
49138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
49148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
49158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig0 |= LIT64( 0x0001000000000000 );
49168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shiftCount = 0x402F - aExp;
49178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    savedASig = aSig0;
49188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig0 >>= shiftCount;
49198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    z = aSig0;
49208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSign ) z = - z;
49218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( ( z < 0 ) ^ aSign ) {
49228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project invalid:
49238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
4924bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        return aSign ? (int32_t) 0x80000000 : 0x7FFFFFFF;
49258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
49268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( ( aSig0<<shiftCount ) != savedASig ) {
49278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        STATUS(float_exception_flags) |= float_flag_inexact;
49288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
49298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return z;
49308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
49318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
49328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
49338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
49348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the quadruple-precision floating-point
49358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| value `a' to the 64-bit two's complement integer format.  The conversion
49368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| is performed according to the IEC/IEEE Standard for Binary Floating-Point
49378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Arithmetic---which means in particular that the conversion is rounded
49388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| according to the current rounding mode.  If `a' is a NaN, the largest
49398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| positive integer is returned.  Otherwise, if the conversion overflows, the
49408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| largest integer with the same sign as `a' is returned.
49418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
49428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
49438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint64 float128_to_int64( float128 a STATUS_PARAM )
49448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
49458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
49468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 aExp, shiftCount;
4947bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig0, aSig1;
49488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
49498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig1 = extractFloat128Frac1( a );
49508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig0 = extractFloat128Frac0( a );
49518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat128Exp( a );
49528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat128Sign( a );
49538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 );
49548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shiftCount = 0x402F - aExp;
49558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( shiftCount <= 0 ) {
49568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( 0x403E < aExp ) {
49578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_invalid STATUS_VAR);
49588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (    ! aSign
49598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 || (    ( aExp == 0x7FFF )
49608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                      && ( aSig1 || ( aSig0 != LIT64( 0x0001000000000000 ) ) )
49618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    )
49628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               ) {
49638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return LIT64( 0x7FFFFFFFFFFFFFFF );
49648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
4965bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            return (int64_t) LIT64( 0x8000000000000000 );
49668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
49678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shortShift128Left( aSig0, aSig1, - shiftCount, &aSig0, &aSig1 );
49688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
49698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
49708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shift64ExtraRightJamming( aSig0, aSig1, shiftCount, &aSig0, &aSig1 );
49718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
49728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return roundAndPackInt64( aSign, aSig0, aSig1 STATUS_VAR );
49738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
49748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
49758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
49768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
49778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the quadruple-precision floating-point
49788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| value `a' to the 64-bit two's complement integer format.  The conversion
49798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| is performed according to the IEC/IEEE Standard for Binary Floating-Point
49808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Arithmetic, except that the conversion is always rounded toward zero.
49818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| If `a' is a NaN, the largest positive integer is returned.  Otherwise, if
49828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| the conversion overflows, the largest integer with the same sign as `a' is
49838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| returned.
49848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
49858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
49868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint64 float128_to_int64_round_to_zero( float128 a STATUS_PARAM )
49878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
49888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
49898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 aExp, shiftCount;
4990bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig0, aSig1;
49918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64 z;
49928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
49938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig1 = extractFloat128Frac1( a );
49948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig0 = extractFloat128Frac0( a );
49958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat128Exp( a );
49968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat128Sign( a );
49978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 );
49988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shiftCount = aExp - 0x402F;
49998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( 0 < shiftCount ) {
50008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( 0x403E <= aExp ) {
50018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            aSig0 &= LIT64( 0x0000FFFFFFFFFFFF );
50028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (    ( a.high == LIT64( 0xC03E000000000000 ) )
50038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 && ( aSig1 < LIT64( 0x0002000000000000 ) ) ) {
50048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if ( aSig1 ) STATUS(float_exception_flags) |= float_flag_inexact;
50058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
50068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else {
50078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                float_raise( float_flag_invalid STATUS_VAR);
50088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if ( ! aSign || ( ( aExp == 0x7FFF ) && ( aSig0 | aSig1 ) ) ) {
50098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    return LIT64( 0x7FFFFFFFFFFFFFFF );
50108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
50118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
5012bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            return (int64_t) LIT64( 0x8000000000000000 );
50138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
50148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        z = ( aSig0<<shiftCount ) | ( aSig1>>( ( - shiftCount ) & 63 ) );
5015bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( (uint64_t) ( aSig1<<shiftCount ) ) {
50168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            STATUS(float_exception_flags) |= float_flag_inexact;
50178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
50188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
50198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
50208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aExp < 0x3FFF ) {
50218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( aExp | aSig0 | aSig1 ) {
50228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                STATUS(float_exception_flags) |= float_flag_inexact;
50238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
50248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 0;
50258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
50268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        z = aSig0>>( - shiftCount );
50278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (    aSig1
5028bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner             || ( shiftCount && (uint64_t) ( aSig0<<( shiftCount & 63 ) ) ) ) {
50298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            STATUS(float_exception_flags) |= float_flag_inexact;
50308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
50318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
50328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSign ) z = - z;
50338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return z;
50348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
50358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
50368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
50378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
50388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the quadruple-precision floating-point
50398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| value `a' to the single-precision floating-point format.  The conversion
50408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| is performed according to the IEC/IEEE Standard for Binary Floating-Point
50418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Arithmetic.
50428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
50438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
50448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 float128_to_float32( float128 a STATUS_PARAM )
50458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
50468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
50478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 aExp;
5048bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig0, aSig1;
5049bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t zSig;
50508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
50518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig1 = extractFloat128Frac1( a );
50528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig0 = extractFloat128Frac0( a );
50538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat128Exp( a );
50548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat128Sign( a );
50558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0x7FFF ) {
50568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig0 | aSig1 ) {
5057bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            return commonNaNToFloat32( float128ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
50588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
50598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloat32( aSign, 0xFF, 0 );
50608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
50618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig0 |= ( aSig1 != 0 );
50628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shift64RightJamming( aSig0, 18, &aSig0 );
50638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig = aSig0;
50648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp || zSig ) {
50658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSig |= 0x40000000;
50668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aExp -= 0x3F81;
50678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
50688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return roundAndPackFloat32( aSign, aExp, zSig STATUS_VAR );
50698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
50708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
50718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
50728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
50738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the quadruple-precision floating-point
50748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| value `a' to the double-precision floating-point format.  The conversion
50758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| is performed according to the IEC/IEEE Standard for Binary Floating-Point
50768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Arithmetic.
50778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
50788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
50798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat64 float128_to_float64( float128 a STATUS_PARAM )
50808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
50818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
50828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 aExp;
5083bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig0, aSig1;
50848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
50858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig1 = extractFloat128Frac1( a );
50868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig0 = extractFloat128Frac0( a );
50878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat128Exp( a );
50888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat128Sign( a );
50898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0x7FFF ) {
50908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig0 | aSig1 ) {
5091bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            return commonNaNToFloat64( float128ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
50928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
50938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloat64( aSign, 0x7FF, 0 );
50948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
50958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 );
50968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig0 |= ( aSig1 != 0 );
50978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp || aSig0 ) {
50988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSig0 |= LIT64( 0x4000000000000000 );
50998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aExp -= 0x3C01;
51008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
51018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return roundAndPackFloat64( aSign, aExp, aSig0 STATUS_VAR );
51028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
51038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
51048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
51058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef FLOATX80
51068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
51078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
51088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of converting the quadruple-precision floating-point
51098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| value `a' to the extended double-precision floating-point format.  The
51108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| conversion is performed according to the IEC/IEEE Standard for Binary
51118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Floating-Point Arithmetic.
51128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
51138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
51148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloatx80 float128_to_floatx80( float128 a STATUS_PARAM )
51158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
51168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
51178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 aExp;
5118bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig0, aSig1;
51198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
51208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig1 = extractFloat128Frac1( a );
51218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig0 = extractFloat128Frac0( a );
51228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat128Exp( a );
51238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat128Sign( a );
51248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0x7FFF ) {
51258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig0 | aSig1 ) {
5126bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            return commonNaNToFloatx80( float128ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
51278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
51288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
51298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
51308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0 ) {
51318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ( aSig0 | aSig1 ) == 0 ) return packFloatx80( aSign, 0, 0 );
51328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
51338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
51348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
51358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSig0 |= LIT64( 0x0001000000000000 );
51368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
51378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shortShift128Left( aSig0, aSig1, 15, &aSig0, &aSig1 );
51388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return roundAndPackFloatx80( 80, aSign, aExp, aSig0, aSig1 STATUS_VAR );
51398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
51408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
51418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
51428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
51438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
51448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
51458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Rounds the quadruple-precision floating-point value `a' to an integer, and
51468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| returns the result as a quadruple-precision floating-point value.  The
51478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| operation is performed according to the IEC/IEEE Standard for Binary
51488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Floating-Point Arithmetic.
51498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
51508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
51518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat128 float128_round_to_int( float128 a STATUS_PARAM )
51528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
51538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
51548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 aExp;
5155bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t lastBitMask, roundBitsMask;
51568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int8 roundingMode;
51578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    float128 z;
51588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
51598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat128Exp( a );
51608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( 0x402F <= aExp ) {
51618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( 0x406F <= aExp ) {
51628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (    ( aExp == 0x7FFF )
51638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) )
51648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               ) {
51658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return propagateFloat128NaN( a, a STATUS_VAR );
51668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
51678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return a;
51688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
51698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        lastBitMask = 1;
51708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        lastBitMask = ( lastBitMask<<( 0x406E - aExp ) )<<1;
51718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        roundBitsMask = lastBitMask - 1;
51728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        z = a;
51738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        roundingMode = STATUS(float_rounding_mode);
51748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( roundingMode == float_round_nearest_even ) {
51758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( lastBitMask ) {
51768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                add128( z.high, z.low, 0, lastBitMask>>1, &z.high, &z.low );
51778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;
51788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
51798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else {
5180bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner                if ( (int64_t) z.low < 0 ) {
51818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    ++z.high;
5182bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner                    if ( (uint64_t) ( z.low<<1 ) == 0 ) z.high &= ~1;
51838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
51848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
51858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
51868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else if ( roundingMode != float_round_to_zero ) {
51878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (   extractFloat128Sign( z )
51888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 ^ ( roundingMode == float_round_up ) ) {
51898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                add128( z.high, z.low, 0, roundBitsMask, &z.high, &z.low );
51908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
51918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
51928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        z.low &= ~ roundBitsMask;
51938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
51948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
51958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aExp < 0x3FFF ) {
5196bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            if ( ( ( (uint64_t) ( a.high<<1 ) ) | a.low ) == 0 ) return a;
51978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            STATUS(float_exception_flags) |= float_flag_inexact;
51988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            aSign = extractFloat128Sign( a );
51998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            switch ( STATUS(float_rounding_mode) ) {
52008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             case float_round_nearest_even:
52018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (    ( aExp == 0x3FFE )
52028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     && (   extractFloat128Frac0( a )
52038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                          | extractFloat128Frac1( a ) )
52048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   ) {
52058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    return packFloat128( aSign, 0x3FFF, 0, 0 );
52068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
52078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
52088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             case float_round_down:
52098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return
52108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                      aSign ? packFloat128( 1, 0x3FFF, 0, 0 )
52118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    : packFloat128( 0, 0, 0, 0 );
52128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             case float_round_up:
52138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return
52148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                      aSign ? packFloat128( 1, 0, 0, 0 )
52158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    : packFloat128( 0, 0x3FFF, 0, 0 );
52168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
52178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return packFloat128( aSign, 0, 0, 0 );
52188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
52198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        lastBitMask = 1;
52208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        lastBitMask <<= 0x402F - aExp;
52218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        roundBitsMask = lastBitMask - 1;
52228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        z.low = 0;
52238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        z.high = a.high;
52248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        roundingMode = STATUS(float_rounding_mode);
52258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( roundingMode == float_round_nearest_even ) {
52268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            z.high += lastBitMask>>1;
52278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( ( ( z.high & roundBitsMask ) | a.low ) == 0 ) {
52288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                z.high &= ~ lastBitMask;
52298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
52308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
52318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else if ( roundingMode != float_round_to_zero ) {
52328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (   extractFloat128Sign( z )
52338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 ^ ( roundingMode == float_round_up ) ) {
52348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                z.high |= ( a.low != 0 );
52358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                z.high += roundBitsMask;
52368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
52378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
52388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        z.high &= ~ roundBitsMask;
52398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
52408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( ( z.low != a.low ) || ( z.high != a.high ) ) {
52418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        STATUS(float_exception_flags) |= float_flag_inexact;
52428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
52438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return z;
52448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
52458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
52468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
52478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
52488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of adding the absolute values of the quadruple-precision
52498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| floating-point values `a' and `b'.  If `zSign' is 1, the sum is negated
52508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| before being returned.  `zSign' is ignored if the result is a NaN.
52518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| The addition is performed according to the IEC/IEEE Standard for Binary
52528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Floating-Point Arithmetic.
52538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
52548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
52558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic float128 addFloat128Sigs( float128 a, float128 b, flag zSign STATUS_PARAM)
52568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
52578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 aExp, bExp, zExp;
5258bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
52598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 expDiff;
52608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
52618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig1 = extractFloat128Frac1( a );
52628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig0 = extractFloat128Frac0( a );
52638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat128Exp( a );
52648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig1 = extractFloat128Frac1( b );
52658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig0 = extractFloat128Frac0( b );
52668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bExp = extractFloat128Exp( b );
52678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    expDiff = aExp - bExp;
52688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( 0 < expDiff ) {
52698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aExp == 0x7FFF ) {
52708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
52718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return a;
52728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
52738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bExp == 0 ) {
52748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            --expDiff;
52758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
52768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else {
52778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            bSig0 |= LIT64( 0x0001000000000000 );
52788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
52798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shift128ExtraRightJamming(
52808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            bSig0, bSig1, 0, expDiff, &bSig0, &bSig1, &zSig2 );
52818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zExp = aExp;
52828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
52838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else if ( expDiff < 0 ) {
52848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bExp == 0x7FFF ) {
52858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
52868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return packFloat128( zSign, 0x7FFF, 0, 0 );
52878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
52888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aExp == 0 ) {
52898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ++expDiff;
52908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
52918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else {
52928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            aSig0 |= LIT64( 0x0001000000000000 );
52938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
52948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shift128ExtraRightJamming(
52958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            aSig0, aSig1, 0, - expDiff, &aSig0, &aSig1, &zSig2 );
52968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zExp = bExp;
52978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
52988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
52998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aExp == 0x7FFF ) {
53008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( aSig0 | aSig1 | bSig0 | bSig1 ) {
53018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return propagateFloat128NaN( a, b STATUS_VAR );
53028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
53038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return a;
53048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
53058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
53065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if ( aExp == 0 ) {
53075285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            if (STATUS(flush_to_zero)) {
53085285864985be9077e58e42235af6582dee72e841David 'Digit' Turner                if (zSig0 | zSig1) {
53095285864985be9077e58e42235af6582dee72e841David 'Digit' Turner                    float_raise(float_flag_output_denormal STATUS_VAR);
53105285864985be9077e58e42235af6582dee72e841David 'Digit' Turner                }
53115285864985be9077e58e42235af6582dee72e841David 'Digit' Turner                return packFloat128(zSign, 0, 0, 0);
53125285864985be9077e58e42235af6582dee72e841David 'Digit' Turner            }
53135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return packFloat128( zSign, 0, zSig0, zSig1 );
53145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
53158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSig2 = 0;
53168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSig0 |= LIT64( 0x0002000000000000 );
53178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zExp = aExp;
53188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto shiftRight1;
53198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
53208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig0 |= LIT64( 0x0001000000000000 );
53218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
53228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    --zExp;
53238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( zSig0 < LIT64( 0x0002000000000000 ) ) goto roundAndPack;
53248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ++zExp;
53258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project shiftRight1:
53268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shift128ExtraRightJamming(
53278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 );
53288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project roundAndPack:
53298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 STATUS_VAR );
53308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
53318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
53328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
53338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
53348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of subtracting the absolute values of the quadruple-
53358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| precision floating-point values `a' and `b'.  If `zSign' is 1, the
53368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| difference is negated before being returned.  `zSign' is ignored if the
53378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| result is a NaN.  The subtraction is performed according to the IEC/IEEE
53388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Standard for Binary Floating-Point Arithmetic.
53398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
53408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
53418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic float128 subFloat128Sigs( float128 a, float128 b, flag zSign STATUS_PARAM)
53428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
53438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 aExp, bExp, zExp;
5344bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig0, aSig1, bSig0, bSig1, zSig0, zSig1;
53458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 expDiff;
53468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    float128 z;
53478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
53488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig1 = extractFloat128Frac1( a );
53498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig0 = extractFloat128Frac0( a );
53508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat128Exp( a );
53518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig1 = extractFloat128Frac1( b );
53528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig0 = extractFloat128Frac0( b );
53538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bExp = extractFloat128Exp( b );
53548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    expDiff = aExp - bExp;
53558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 );
53568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shortShift128Left( bSig0, bSig1, 14, &bSig0, &bSig1 );
53578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( 0 < expDiff ) goto aExpBigger;
53588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( expDiff < 0 ) goto bExpBigger;
53598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0x7FFF ) {
53608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig0 | aSig1 | bSig0 | bSig1 ) {
53618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return propagateFloat128NaN( a, b STATUS_VAR );
53628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
53638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
53648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        z.low = float128_default_nan_low;
53658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        z.high = float128_default_nan_high;
53668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return z;
53678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
53688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0 ) {
53698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aExp = 1;
53708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        bExp = 1;
53718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
53728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bSig0 < aSig0 ) goto aBigger;
53738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSig0 < bSig0 ) goto bBigger;
53748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bSig1 < aSig1 ) goto aBigger;
53758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSig1 < bSig1 ) goto bBigger;
53768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return packFloat128( STATUS(float_rounding_mode) == float_round_down, 0, 0, 0 );
53778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bExpBigger:
53788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0x7FFF ) {
53798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
53808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloat128( zSign ^ 1, 0x7FFF, 0, 0 );
53818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
53828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0 ) {
53838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ++expDiff;
53848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
53858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
53868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSig0 |= LIT64( 0x4000000000000000 );
53878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
53888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shift128RightJamming( aSig0, aSig1, - expDiff, &aSig0, &aSig1 );
53898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig0 |= LIT64( 0x4000000000000000 );
53908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bBigger:
53918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sub128( bSig0, bSig1, aSig0, aSig1, &zSig0, &zSig1 );
53928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zExp = bExp;
53938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSign ^= 1;
53948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    goto normalizeRoundAndPack;
53958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project aExpBigger:
53968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0x7FFF ) {
53978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
53988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return a;
53998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
54008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0 ) {
54018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        --expDiff;
54028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
54038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
54048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        bSig0 |= LIT64( 0x4000000000000000 );
54058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
54068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shift128RightJamming( bSig0, bSig1, expDiff, &bSig0, &bSig1 );
54078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig0 |= LIT64( 0x4000000000000000 );
54088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project aBigger:
54098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sub128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
54108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zExp = aExp;
54118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project normalizeRoundAndPack:
54128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    --zExp;
54138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return normalizeRoundAndPackFloat128( zSign, zExp - 14, zSig0, zSig1 STATUS_VAR );
54148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
54158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
54168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
54178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
54188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of adding the quadruple-precision floating-point values
54198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
54208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| for Binary Floating-Point Arithmetic.
54218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
54228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
54238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat128 float128_add( float128 a, float128 b STATUS_PARAM )
54248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
54258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign;
54268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
54278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat128Sign( a );
54288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloat128Sign( b );
54298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSign == bSign ) {
54308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return addFloat128Sigs( a, b, aSign STATUS_VAR );
54318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
54328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
54338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return subFloat128Sigs( a, b, aSign STATUS_VAR );
54348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
54358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
54368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
54378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
54388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
54398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of subtracting the quadruple-precision floating-point
54408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| values `a' and `b'.  The operation is performed according to the IEC/IEEE
54418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Standard for Binary Floating-Point Arithmetic.
54428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
54438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
54448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat128 float128_sub( float128 a, float128 b STATUS_PARAM )
54458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
54468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign;
54478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
54488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat128Sign( a );
54498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloat128Sign( b );
54508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSign == bSign ) {
54518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return subFloat128Sigs( a, b, aSign STATUS_VAR );
54528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
54538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
54548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return addFloat128Sigs( a, b, aSign STATUS_VAR );
54558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
54568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
54578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
54588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
54598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
54608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of multiplying the quadruple-precision floating-point
54618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| values `a' and `b'.  The operation is performed according to the IEC/IEEE
54628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Standard for Binary Floating-Point Arithmetic.
54638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
54648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
54658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat128 float128_mul( float128 a, float128 b STATUS_PARAM )
54668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
54678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign, zSign;
54688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 aExp, bExp, zExp;
5469bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2, zSig3;
54708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    float128 z;
54718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
54728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig1 = extractFloat128Frac1( a );
54738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig0 = extractFloat128Frac0( a );
54748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat128Exp( a );
54758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat128Sign( a );
54768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig1 = extractFloat128Frac1( b );
54778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig0 = extractFloat128Frac0( b );
54788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bExp = extractFloat128Exp( b );
54798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloat128Sign( b );
54808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSign = aSign ^ bSign;
54818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0x7FFF ) {
54828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (    ( aSig0 | aSig1 )
54838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) {
54848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return propagateFloat128NaN( a, b STATUS_VAR );
54858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
54868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ( bExp | bSig0 | bSig1 ) == 0 ) goto invalid;
54878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloat128( zSign, 0x7FFF, 0, 0 );
54888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
54898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0x7FFF ) {
54908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
54918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ( aExp | aSig0 | aSig1 ) == 0 ) {
54928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project invalid:
54938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_invalid STATUS_VAR);
54948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            z.low = float128_default_nan_low;
54958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            z.high = float128_default_nan_high;
54968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return z;
54978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
54988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloat128( zSign, 0x7FFF, 0, 0 );
54998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
55008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0 ) {
55018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
55028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
55038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
55048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0 ) {
55058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ( bSig0 | bSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
55068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
55078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
55088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zExp = aExp + bExp - 0x4000;
55098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig0 |= LIT64( 0x0001000000000000 );
55108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shortShift128Left( bSig0, bSig1, 16, &bSig0, &bSig1 );
55118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    mul128To256( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1, &zSig2, &zSig3 );
55128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    add128( zSig0, zSig1, aSig0, aSig1, &zSig0, &zSig1 );
55138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig2 |= ( zSig3 != 0 );
55148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( LIT64( 0x0002000000000000 ) <= zSig0 ) {
55158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shift128ExtraRightJamming(
55168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 );
55178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ++zExp;
55188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
55198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 STATUS_VAR );
55208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
55218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
55228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
55238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
55248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the result of dividing the quadruple-precision floating-point value
55258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| `a' by the corresponding value `b'.  The operation is performed according to
55268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
55278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
55288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
55298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat128 float128_div( float128 a, float128 b STATUS_PARAM )
55308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
55318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign, zSign;
55328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 aExp, bExp, zExp;
5533bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
5534bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t rem0, rem1, rem2, rem3, term0, term1, term2, term3;
55358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    float128 z;
55368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
55378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig1 = extractFloat128Frac1( a );
55388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig0 = extractFloat128Frac0( a );
55398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat128Exp( a );
55408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat128Sign( a );
55418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig1 = extractFloat128Frac1( b );
55428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig0 = extractFloat128Frac0( b );
55438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bExp = extractFloat128Exp( b );
55448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloat128Sign( b );
55458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSign = aSign ^ bSign;
55468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0x7FFF ) {
55478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
55488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bExp == 0x7FFF ) {
55498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
55508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto invalid;
55518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
55528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloat128( zSign, 0x7FFF, 0, 0 );
55538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
55548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0x7FFF ) {
55558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
55568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return packFloat128( zSign, 0, 0, 0 );
55578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
55588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0 ) {
55598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ( bSig0 | bSig1 ) == 0 ) {
55608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ( ( aExp | aSig0 | aSig1 ) == 0 ) {
55618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project invalid:
55628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                float_raise( float_flag_invalid STATUS_VAR);
55638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                z.low = float128_default_nan_low;
55648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                z.high = float128_default_nan_high;
55658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return z;
55668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
55678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_divbyzero STATUS_VAR);
55688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return packFloat128( zSign, 0x7FFF, 0, 0 );
55698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
55708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
55718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
55728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0 ) {
55738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
55748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
55758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
55768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zExp = aExp - bExp + 0x3FFD;
55778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shortShift128Left(
55788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSig0 | LIT64( 0x0001000000000000 ), aSig1, 15, &aSig0, &aSig1 );
55798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shortShift128Left(
55808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 );
55818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( le128( bSig0, bSig1, aSig0, aSig1 ) ) {
55828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shift128Right( aSig0, aSig1, 1, &aSig0, &aSig1 );
55838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ++zExp;
55848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
55858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig0 = estimateDiv128To64( aSig0, aSig1, bSig0 );
55868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    mul128By64To192( bSig0, bSig1, zSig0, &term0, &term1, &term2 );
55878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sub192( aSig0, aSig1, 0, term0, term1, term2, &rem0, &rem1, &rem2 );
5588bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    while ( (int64_t) rem0 < 0 ) {
55898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        --zSig0;
55908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        add192( rem0, rem1, rem2, 0, bSig0, bSig1, &rem0, &rem1, &rem2 );
55918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
55928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig1 = estimateDiv128To64( rem1, rem2, bSig0 );
55938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( ( zSig1 & 0x3FFF ) <= 4 ) {
55948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        mul128By64To192( bSig0, bSig1, zSig1, &term1, &term2, &term3 );
55958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sub192( rem1, rem2, 0, term1, term2, term3, &rem1, &rem2, &rem3 );
5596bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        while ( (int64_t) rem1 < 0 ) {
55978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            --zSig1;
55988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            add192( rem1, rem2, rem3, 0, bSig0, bSig1, &rem1, &rem2, &rem3 );
55998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
56008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
56018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
56028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shift128ExtraRightJamming( zSig0, zSig1, 0, 15, &zSig0, &zSig1, &zSig2 );
56038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 STATUS_VAR );
56048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
56058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
56068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
56078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
56088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the remainder of the quadruple-precision floating-point value `a'
56098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| with respect to the corresponding value `b'.  The operation is performed
56108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
56118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
56128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
56138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat128 float128_rem( float128 a, float128 b STATUS_PARAM )
56148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
56152738c26579c211c46eedf84a4e61c73243551888David Turner    flag aSign, zSign;
56168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 aExp, bExp, expDiff;
5617bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig0, aSig1, bSig0, bSig1, q, term0, term1, term2;
5618bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t allZero, alternateASig0, alternateASig1, sigMean1;
5619bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    int64_t sigMean0;
56208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    float128 z;
56218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
56228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig1 = extractFloat128Frac1( a );
56238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig0 = extractFloat128Frac0( a );
56248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat128Exp( a );
56258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat128Sign( a );
56268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig1 = extractFloat128Frac1( b );
56278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSig0 = extractFloat128Frac0( b );
56288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bExp = extractFloat128Exp( b );
56298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0x7FFF ) {
56308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (    ( aSig0 | aSig1 )
56318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) {
56328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return propagateFloat128NaN( a, b STATUS_VAR );
56338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
56348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto invalid;
56358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
56368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0x7FFF ) {
56378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
56388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return a;
56398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
56408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( bExp == 0 ) {
56418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ( bSig0 | bSig1 ) == 0 ) {
56428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project invalid:
56438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_invalid STATUS_VAR);
56448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            z.low = float128_default_nan_low;
56458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            z.high = float128_default_nan_high;
56468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return z;
56478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
56488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
56498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
56508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0 ) {
56518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ( aSig0 | aSig1 ) == 0 ) return a;
56528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
56538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
56548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    expDiff = aExp - bExp;
56558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( expDiff < -1 ) return a;
56568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shortShift128Left(
56578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSig0 | LIT64( 0x0001000000000000 ),
56588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSig1,
56598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        15 - ( expDiff < 0 ),
56608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        &aSig0,
56618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        &aSig1
56628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    );
56638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shortShift128Left(
56648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 );
56658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    q = le128( bSig0, bSig1, aSig0, aSig1 );
56668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( q ) sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 );
56678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    expDiff -= 64;
56688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while ( 0 < expDiff ) {
56698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        q = estimateDiv128To64( aSig0, aSig1, bSig0 );
56708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        q = ( 4 < q ) ? q - 4 : 0;
56718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 );
56728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shortShift192Left( term0, term1, term2, 61, &term1, &term2, &allZero );
56738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shortShift128Left( aSig0, aSig1, 61, &aSig0, &allZero );
56748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sub128( aSig0, 0, term1, term2, &aSig0, &aSig1 );
56758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        expDiff -= 61;
56768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
56778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( -64 < expDiff ) {
56788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        q = estimateDiv128To64( aSig0, aSig1, bSig0 );
56798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        q = ( 4 < q ) ? q - 4 : 0;
56808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        q >>= - expDiff;
56818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 );
56828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        expDiff += 52;
56838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( expDiff < 0 ) {
56848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            shift128Right( aSig0, aSig1, - expDiff, &aSig0, &aSig1 );
56858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
56868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else {
56878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            shortShift128Left( aSig0, aSig1, expDiff, &aSig0, &aSig1 );
56888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
56898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 );
56908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sub128( aSig0, aSig1, term1, term2, &aSig0, &aSig1 );
56918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
56928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
56938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shift128Right( aSig0, aSig1, 12, &aSig0, &aSig1 );
56948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 );
56958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
56968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do {
56978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        alternateASig0 = aSig0;
56988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        alternateASig1 = aSig1;
56998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ++q;
57008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 );
5701bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    } while ( 0 <= (int64_t) aSig0 );
57028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    add128(
5703bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        aSig0, aSig1, alternateASig0, alternateASig1, (uint64_t *)&sigMean0, &sigMean1 );
57048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (    ( sigMean0 < 0 )
57058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         || ( ( ( sigMean0 | sigMean1 ) == 0 ) && ( q & 1 ) ) ) {
57068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSig0 = alternateASig0;
57078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        aSig1 = alternateASig1;
57088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5709bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    zSign = ( (int64_t) aSig0 < 0 );
57108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( zSign ) sub128( 0, 0, aSig0, aSig1, &aSig0, &aSig1 );
57118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return
57128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeRoundAndPackFloat128( aSign ^ zSign, bExp - 4, aSig0, aSig1 STATUS_VAR );
57138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
57148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
57158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
57168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
57178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns the square root of the quadruple-precision floating-point value `a'.
57188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| The operation is performed according to the IEC/IEEE Standard for Binary
57198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Floating-Point Arithmetic.
57208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
57218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
57228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat128 float128_sqrt( float128 a STATUS_PARAM )
57238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
57248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
57258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int32 aExp, zExp;
5726bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig0, aSig1, zSig0, zSig1, zSig2, doubleZSig0;
5727bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t rem0, rem1, rem2, rem3, term0, term1, term2, term3;
57288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    float128 z;
57298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
57308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig1 = extractFloat128Frac1( a );
57318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig0 = extractFloat128Frac0( a );
57328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat128Exp( a );
57338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat128Sign( a );
57348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0x7FFF ) {
57358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, a STATUS_VAR );
57368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ! aSign ) return a;
57378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto invalid;
57388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
57398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSign ) {
57408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ( aExp | aSig0 | aSig1 ) == 0 ) return a;
57418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project invalid:
57428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
57438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        z.low = float128_default_nan_low;
57448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        z.high = float128_default_nan_high;
57458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return z;
57468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
57478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0 ) {
57488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( 0, 0, 0, 0 );
57498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
57508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
57518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFE;
57528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig0 |= LIT64( 0x0001000000000000 );
57538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig0 = estimateSqrt32( aExp, aSig0>>17 );
57548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shortShift128Left( aSig0, aSig1, 13 - ( aExp & 1 ), &aSig0, &aSig1 );
57558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 );
57568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    doubleZSig0 = zSig0<<1;
57578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    mul64To128( zSig0, zSig0, &term0, &term1 );
57588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 );
5759bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    while ( (int64_t) rem0 < 0 ) {
57608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        --zSig0;
57618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        doubleZSig0 -= 2;
57628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 );
57638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
57648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 );
57658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( ( zSig1 & 0x1FFF ) <= 5 ) {
57668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( zSig1 == 0 ) zSig1 = 1;
57678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        mul64To128( doubleZSig0, zSig1, &term1, &term2 );
57688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sub128( rem1, 0, term1, term2, &rem1, &rem2 );
57698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        mul64To128( zSig1, zSig1, &term2, &term3 );
57708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 );
5771bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        while ( (int64_t) rem1 < 0 ) {
57728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            --zSig1;
57738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            shortShift128Left( 0, zSig1, 1, &term2, &term3 );
57748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            term3 |= 1;
57758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            term2 |= doubleZSig0;
57768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 );
57778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
57788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
57798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
57808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    shift128ExtraRightJamming( zSig0, zSig1, 0, 14, &zSig0, &zSig1, &zSig2 );
57818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return roundAndPackFloat128( 0, zExp, zSig0, zSig1, zSig2 STATUS_VAR );
57828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
57838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
57848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
57858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
57868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns 1 if the quadruple-precision floating-point value `a' is equal to
5787bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| the corresponding value `b', and 0 otherwise.  The invalid exception is
5788bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| raised if either operand is a NaN.  Otherwise, the comparison is performed
57898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
57908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
57918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
57928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint float128_eq( float128 a, float128 b STATUS_PARAM )
57938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
57948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
57958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
57968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
57978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         || (    ( extractFloat128Exp( b ) == 0x7FFF )
57988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
57998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       ) {
5800bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        float_raise( float_flag_invalid STATUS_VAR);
58018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
58028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
58038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return
58048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           ( a.low == b.low )
58058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        && (    ( a.high == b.high )
58068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             || (    ( a.low == 0 )
5807bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner                  && ( (uint64_t) ( ( a.high | b.high )<<1 ) == 0 ) )
58088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           );
58098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
58108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
58118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
58128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
58138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns 1 if the quadruple-precision floating-point value `a' is less than
5814bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| or equal to the corresponding value `b', and 0 otherwise.  The invalid
5815bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| exception is raised if either operand is a NaN.  The comparison is performed
5816bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
58178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
58188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
58198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint float128_le( float128 a, float128 b STATUS_PARAM )
58208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
58218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign;
58228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
58238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
58248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
58258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         || (    ( extractFloat128Exp( b ) == 0x7FFF )
58268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
58278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       ) {
58288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
58298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
58308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
58318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat128Sign( a );
58328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloat128Sign( b );
58338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSign != bSign ) {
58348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return
58358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               aSign
5836bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            || (    ( ( (uint64_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
58378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 == 0 );
58388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
58398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return
58408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          aSign ? le128( b.high, b.low, a.high, a.low )
58418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        : le128( a.high, a.low, b.high, b.low );
58428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
58438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
58448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
58458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
58468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns 1 if the quadruple-precision floating-point value `a' is less than
5847bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| the corresponding value `b', and 0 otherwise.  The invalid exception is
5848bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| raised if either operand is a NaN.  The comparison is performed according
5849bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
58508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
58518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
58528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint float128_lt( float128 a, float128 b STATUS_PARAM )
58538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
58548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign;
58558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
58568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
58578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
58588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         || (    ( extractFloat128Exp( b ) == 0x7FFF )
58598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
58608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       ) {
58618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
58628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
58638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
58648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat128Sign( a );
58658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloat128Sign( b );
58668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSign != bSign ) {
58678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return
58688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               aSign
5869bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            && (    ( ( (uint64_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
58708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 != 0 );
58718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
58728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return
58738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          aSign ? lt128( b.high, b.low, a.high, a.low )
58748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        : lt128( a.high, a.low, b.high, b.low );
58758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
58768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
58778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
58788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
5879bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| Returns 1 if the quadruple-precision floating-point values `a' and `b' cannot
5880bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| be compared, and 0 otherwise.  The invalid exception is raised if either
5881bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| operand is a NaN. The comparison is performed according to the IEC/IEEE
5882bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| Standard for Binary Floating-Point Arithmetic.
5883bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner*----------------------------------------------------------------------------*/
5884bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
5885bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turnerint float128_unordered( float128 a, float128 b STATUS_PARAM )
5886bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner{
5887bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
5888bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
5889bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner         || (    ( extractFloat128Exp( b ) == 0x7FFF )
5890bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
5891bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner       ) {
5892bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        float_raise( float_flag_invalid STATUS_VAR);
5893bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        return 1;
5894bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    }
5895bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    return 0;
5896bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner}
5897bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
5898bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner/*----------------------------------------------------------------------------
58998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns 1 if the quadruple-precision floating-point value `a' is equal to
5900bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
5901bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| exception.  The comparison is performed according to the IEC/IEEE Standard
5902bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| for Binary Floating-Point Arithmetic.
59038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
59048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5905bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turnerint float128_eq_quiet( float128 a, float128 b STATUS_PARAM )
59068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
59078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
59088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
59098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
59108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         || (    ( extractFloat128Exp( b ) == 0x7FFF )
59118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
59128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       ) {
5913bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if (    float128_is_signaling_nan( a )
5914bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner             || float128_is_signaling_nan( b ) ) {
5915bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            float_raise( float_flag_invalid STATUS_VAR);
5916bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        }
59178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
59188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
59198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return
59208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           ( a.low == b.low )
59218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        && (    ( a.high == b.high )
59228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             || (    ( a.low == 0 )
5923bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner                  && ( (uint64_t) ( ( a.high | b.high )<<1 ) == 0 ) )
59248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           );
59258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
59268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
59278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
59288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
59298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns 1 if the quadruple-precision floating-point value `a' is less than
59308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| or equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs do not
59318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| cause an exception.  Otherwise, the comparison is performed according to the
59328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| IEC/IEEE Standard for Binary Floating-Point Arithmetic.
59338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
59348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
59358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint float128_le_quiet( float128 a, float128 b STATUS_PARAM )
59368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
59378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign;
59388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
59398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
59408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
59418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         || (    ( extractFloat128Exp( b ) == 0x7FFF )
59428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
59438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       ) {
59448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (    float128_is_signaling_nan( a )
59458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             || float128_is_signaling_nan( b ) ) {
59468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_invalid STATUS_VAR);
59478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
59488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
59498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
59508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat128Sign( a );
59518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloat128Sign( b );
59528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSign != bSign ) {
59538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return
59548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               aSign
5955bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            || (    ( ( (uint64_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
59568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 == 0 );
59578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
59588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return
59598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          aSign ? le128( b.high, b.low, a.high, a.low )
59608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        : le128( a.high, a.low, b.high, b.low );
59618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
59628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
59638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
59648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*----------------------------------------------------------------------------
59658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Returns 1 if the quadruple-precision floating-point value `a' is less than
59668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
59678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| exception.  Otherwise, the comparison is performed according to the IEC/IEEE
59688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project| Standard for Binary Floating-Point Arithmetic.
59698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*----------------------------------------------------------------------------*/
59708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
59718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint float128_lt_quiet( float128 a, float128 b STATUS_PARAM )
59728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
59738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign;
59748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
59758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
59768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
59778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         || (    ( extractFloat128Exp( b ) == 0x7FFF )
59788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
59798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       ) {
59808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (    float128_is_signaling_nan( a )
59818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             || float128_is_signaling_nan( b ) ) {
59828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_invalid STATUS_VAR);
59838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
59848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
59858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
59868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat128Sign( a );
59878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloat128Sign( b );
59888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSign != bSign ) {
59898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return
59908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               aSign
5991bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            && (    ( ( (uint64_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
59928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 != 0 );
59938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
59948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return
59958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          aSign ? lt128( b.high, b.low, a.high, a.low )
59968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        : lt128( a.high, a.low, b.high, b.low );
59978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
59988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
59998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6000bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner/*----------------------------------------------------------------------------
6001bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| Returns 1 if the quadruple-precision floating-point values `a' and `b' cannot
6002bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| be compared, and 0 otherwise.  Quiet NaNs do not cause an exception.  The
6003bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| comparison is performed according to the IEC/IEEE Standard for Binary
6004bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner| Floating-Point Arithmetic.
6005bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner*----------------------------------------------------------------------------*/
6006bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
6007bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turnerint float128_unordered_quiet( float128 a, float128 b STATUS_PARAM )
6008bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner{
6009bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
6010bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
6011bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner         || (    ( extractFloat128Exp( b ) == 0x7FFF )
6012bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
6013bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner       ) {
6014bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if (    float128_is_signaling_nan( a )
6015bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner             || float128_is_signaling_nan( b ) ) {
6016bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            float_raise( float_flag_invalid STATUS_VAR);
6017bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        }
6018bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        return 1;
6019bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    }
6020bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    return 0;
6021bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner}
6022bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
60238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
60248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
60258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* misc functions */
60268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 uint32_to_float32( unsigned int a STATUS_PARAM )
60278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
60288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return int64_to_float32(a STATUS_VAR);
60298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
60308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
60318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat64 uint32_to_float64( unsigned int a STATUS_PARAM )
60328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
60338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return int64_to_float64(a STATUS_VAR);
60348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
60358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
60368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectunsigned int float32_to_uint32( float32 a STATUS_PARAM )
60378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
60388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64_t v;
60398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned int res;
60408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
60418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    v = float32_to_int64(a STATUS_VAR);
60428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (v < 0) {
60438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        res = 0;
60448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
60458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (v > 0xffffffff) {
60468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        res = 0xffffffff;
60478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
60488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
60498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        res = v;
60508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
60518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return res;
60528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
60538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
60548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectunsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM )
60558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
60568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64_t v;
60578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned int res;
60588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
60598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    v = float32_to_int64_round_to_zero(a STATUS_VAR);
60608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (v < 0) {
60618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        res = 0;
60628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
60638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (v > 0xffffffff) {
60648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        res = 0xffffffff;
60658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
60668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
60678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        res = v;
60688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
60698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return res;
60708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
60718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6072bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turnerunsigned int float32_to_uint16_round_to_zero( float32 a STATUS_PARAM )
6073bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner{
6074bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    int64_t v;
6075bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    unsigned int res;
6076bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
6077bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    v = float32_to_int64_round_to_zero(a STATUS_VAR);
6078bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if (v < 0) {
6079bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        res = 0;
6080bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        float_raise( float_flag_invalid STATUS_VAR);
6081bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    } else if (v > 0xffff) {
6082bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        res = 0xffff;
6083bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        float_raise( float_flag_invalid STATUS_VAR);
6084bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    } else {
6085bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        res = v;
6086bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    }
6087bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    return res;
6088bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner}
6089bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
60908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectunsigned int float64_to_uint32( float64 a STATUS_PARAM )
60918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
60928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64_t v;
60938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned int res;
60948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
60958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    v = float64_to_int64(a STATUS_VAR);
60968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (v < 0) {
60978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        res = 0;
60988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
60998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (v > 0xffffffff) {
61008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        res = 0xffffffff;
61018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
61028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
61038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        res = v;
61048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
61058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return res;
61068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
61078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
61088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectunsigned int float64_to_uint32_round_to_zero( float64 a STATUS_PARAM )
61098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
61108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64_t v;
61118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned int res;
61128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
61138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    v = float64_to_int64_round_to_zero(a STATUS_VAR);
61148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (v < 0) {
61158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        res = 0;
61168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
61178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else if (v > 0xffffffff) {
61188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        res = 0xffffffff;
61198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        float_raise( float_flag_invalid STATUS_VAR);
61208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
61218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        res = v;
61228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
61238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return res;
61248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
61258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6126bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turnerunsigned int float64_to_uint16_round_to_zero( float64 a STATUS_PARAM )
6127bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner{
6128bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    int64_t v;
6129bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    unsigned int res;
6130bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
6131bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    v = float64_to_int64_round_to_zero(a STATUS_VAR);
6132bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if (v < 0) {
6133bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        res = 0;
6134bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        float_raise( float_flag_invalid STATUS_VAR);
6135bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    } else if (v > 0xffff) {
6136bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        res = 0xffff;
6137bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        float_raise( float_flag_invalid STATUS_VAR);
6138bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    } else {
6139bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        res = v;
6140bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    }
6141bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    return res;
6142bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner}
6143bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
61448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* FIXME: This looks broken.  */
61458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t float64_to_uint64 (float64 a STATUS_PARAM)
61468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
61478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64_t v;
61488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
61498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    v = float64_val(int64_to_float64(INT64_MIN STATUS_VAR));
61508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    v += float64_val(a);
61518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    v = float64_to_int64(make_float64(v) STATUS_VAR);
61528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
61538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return v - INT64_MIN;
61548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
61558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
61568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM)
61578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
61588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int64_t v;
61598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
61608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    v = float64_val(int64_to_float64(INT64_MIN STATUS_VAR));
61618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    v += float64_val(a);
61628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    v = float64_to_int64_round_to_zero(make_float64(v) STATUS_VAR);
61638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
61648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return v - INT64_MIN;
61658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
61668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
61678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define COMPARE(s, nan_exp)                                                  \
61688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectINLINE int float ## s ## _compare_internal( float ## s a, float ## s b,      \
61698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                      int is_quiet STATUS_PARAM )            \
61708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{                                                                            \
61718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign;                                                       \
6172bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint ## s ## _t av, bv;                                                  \
6173bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float ## s ## _squash_input_denormal(a STATUS_VAR);                  \
6174bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    b = float ## s ## _squash_input_denormal(b STATUS_VAR);                  \
61758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                                                             \
61768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (( ( extractFloat ## s ## Exp( a ) == nan_exp ) &&                    \
61778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         extractFloat ## s ## Frac( a ) ) ||                                 \
61788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ( ( extractFloat ## s ## Exp( b ) == nan_exp ) &&                    \
61798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          extractFloat ## s ## Frac( b ) )) {                                \
61808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (!is_quiet ||                                                     \
61818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float ## s ## _is_signaling_nan( a ) ||                          \
61828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float ## s ## _is_signaling_nan( b ) ) {                         \
61838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_invalid STATUS_VAR);                     \
61848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }                                                                    \
61858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return float_relation_unordered;                                     \
61868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }                                                                        \
61878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat ## s ## Sign( a );                                  \
61888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloat ## s ## Sign( b );                                  \
61898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    av = float ## s ## _val(a);                                              \
61908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bv = float ## s ## _val(b);                                              \
61918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSign != bSign ) {                                                  \
6192bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( (uint ## s ## _t) ( ( av | bv )<<1 ) == 0 ) {                   \
61938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* zero case */                                                  \
61948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return float_relation_equal;                                     \
61958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {                                                             \
61968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 1 - (2 * aSign);                                          \
61978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }                                                                    \
61988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {                                                                 \
61998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (av == bv) {                                                      \
62008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return float_relation_equal;                                     \
62018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {                                                             \
62028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 1 - 2 * (aSign ^ ( av < bv ));                            \
62038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }                                                                    \
62048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }                                                                        \
62058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}                                                                            \
62068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                                                             \
62078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint float ## s ## _compare( float ## s a, float ## s b STATUS_PARAM )        \
62088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{                                                                            \
62098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return float ## s ## _compare_internal(a, b, 0 STATUS_VAR);              \
62108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}                                                                            \
62118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                                                             \
62128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint float ## s ## _compare_quiet( float ## s a, float ## s b STATUS_PARAM )  \
62138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{                                                                            \
62148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return float ## s ## _compare_internal(a, b, 1 STATUS_VAR);              \
62158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
62168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
62178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectCOMPARE(32, 0xff)
62188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectCOMPARE(64, 0x7ff)
62198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6220bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' TurnerINLINE int floatx80_compare_internal( floatx80 a, floatx80 b,
6221bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner                                      int is_quiet STATUS_PARAM )
6222bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner{
6223bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    flag aSign, bSign;
6224bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
6225bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if (( ( extractFloatx80Exp( a ) == 0x7fff ) &&
6226bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner          ( extractFloatx80Frac( a )<<1 ) ) ||
6227bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        ( ( extractFloatx80Exp( b ) == 0x7fff ) &&
6228bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner          ( extractFloatx80Frac( b )<<1 ) )) {
6229bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if (!is_quiet ||
6230bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            floatx80_is_signaling_nan( a ) ||
6231bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            floatx80_is_signaling_nan( b ) ) {
6232bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            float_raise( float_flag_invalid STATUS_VAR);
6233bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        }
6234bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        return float_relation_unordered;
6235bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    }
6236bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    aSign = extractFloatx80Sign( a );
6237bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    bSign = extractFloatx80Sign( b );
6238bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( aSign != bSign ) {
6239bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
6240bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( ( ( (uint16_t) ( ( a.high | b.high ) << 1 ) ) == 0) &&
6241bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner             ( ( a.low | b.low ) == 0 ) ) {
6242bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            /* zero case */
6243bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            return float_relation_equal;
6244bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        } else {
6245bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            return 1 - (2 * aSign);
6246bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        }
6247bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    } else {
6248bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if (a.low == b.low && a.high == b.high) {
6249bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            return float_relation_equal;
6250bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        } else {
6251bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            return 1 - 2 * (aSign ^ ( lt128( a.high, a.low, b.high, b.low ) ));
6252bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        }
6253bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    }
6254bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner}
6255bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
6256bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turnerint floatx80_compare( floatx80 a, floatx80 b STATUS_PARAM )
6257bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner{
6258bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    return floatx80_compare_internal(a, b, 0 STATUS_VAR);
6259bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner}
6260bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
6261bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turnerint floatx80_compare_quiet( floatx80 a, floatx80 b STATUS_PARAM )
6262bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner{
6263bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    return floatx80_compare_internal(a, b, 1 STATUS_VAR);
6264bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner}
6265bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
62668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectINLINE int float128_compare_internal( float128 a, float128 b,
62678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                      int is_quiet STATUS_PARAM )
62688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
62698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign, bSign;
62708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
62718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (( ( extractFloat128Exp( a ) == 0x7fff ) &&
62728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) ||
62738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ( ( extractFloat128Exp( b ) == 0x7fff ) &&
62748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )) {
62758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (!is_quiet ||
62768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float128_is_signaling_nan( a ) ||
62778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float128_is_signaling_nan( b ) ) {
62788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            float_raise( float_flag_invalid STATUS_VAR);
62798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
62808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return float_relation_unordered;
62818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
62828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat128Sign( a );
62838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bSign = extractFloat128Sign( b );
62848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aSign != bSign ) {
62858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( ( ( ( a.high | b.high )<<1 ) | a.low | b.low ) == 0 ) {
62868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* zero case */
62878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return float_relation_equal;
62888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
62898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 1 - (2 * aSign);
62908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
62918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
62928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (a.low == b.low && a.high == b.high) {
62938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return float_relation_equal;
62948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
62958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return 1 - 2 * (aSign ^ ( lt128( a.high, a.low, b.high, b.low ) ));
62968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
62978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
62988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
62998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
63008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint float128_compare( float128 a, float128 b STATUS_PARAM )
63018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
63028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return float128_compare_internal(a, b, 0 STATUS_VAR);
63038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
63048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
63058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint float128_compare_quiet( float128 a, float128 b STATUS_PARAM )
63068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
63078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return float128_compare_internal(a, b, 1 STATUS_VAR);
63088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
63098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6310bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner/* min() and max() functions. These can't be implemented as
6311bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner * 'compare and pick one input' because that would mishandle
6312bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner * NaNs and +0 vs -0.
6313bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner */
6314bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner#define MINMAX(s, nan_exp)                                              \
6315bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' TurnerINLINE float ## s float ## s ## _minmax(float ## s a, float ## s b,     \
6316bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner                                        int ismin STATUS_PARAM )        \
6317bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner{                                                                       \
6318bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    flag aSign, bSign;                                                  \
6319bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint ## s ## _t av, bv;                                             \
6320bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float ## s ## _squash_input_denormal(a STATUS_VAR);             \
6321bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    b = float ## s ## _squash_input_denormal(b STATUS_VAR);             \
6322bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if (float ## s ## _is_any_nan(a) ||                                 \
6323bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        float ## s ## _is_any_nan(b)) {                                 \
6324bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        return propagateFloat ## s ## NaN(a, b STATUS_VAR);             \
6325bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    }                                                                   \
6326bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    aSign = extractFloat ## s ## Sign(a);                               \
6327bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    bSign = extractFloat ## s ## Sign(b);                               \
6328bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    av = float ## s ## _val(a);                                         \
6329bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    bv = float ## s ## _val(b);                                         \
6330bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if (aSign != bSign) {                                               \
6331bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if (ismin) {                                                    \
6332bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            return aSign ? a : b;                                       \
6333bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        } else {                                                        \
6334bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            return aSign ? b : a;                                       \
6335bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        }                                                               \
6336bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    } else {                                                            \
6337bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if (ismin) {                                                    \
6338bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            return (aSign ^ (av < bv)) ? a : b;                         \
6339bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        } else {                                                        \
6340bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            return (aSign ^ (av < bv)) ? b : a;                         \
6341bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        }                                                               \
6342bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    }                                                                   \
6343bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner}                                                                       \
6344bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner                                                                        \
6345bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turnerfloat ## s float ## s ## _min(float ## s a, float ## s b STATUS_PARAM)  \
6346bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner{                                                                       \
6347bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    return float ## s ## _minmax(a, b, 1 STATUS_VAR);                   \
6348bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner}                                                                       \
6349bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner                                                                        \
6350bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turnerfloat ## s float ## s ## _max(float ## s a, float ## s b STATUS_PARAM)  \
6351bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner{                                                                       \
6352bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    return float ## s ## _minmax(a, b, 0 STATUS_VAR);                   \
6353bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner}
6354bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
6355bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' TurnerMINMAX(32, 0xff)
6356bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' TurnerMINMAX(64, 0x7ff)
6357bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
6358bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
63598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Multiply A by 2 raised to the power N.  */
63608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat32 float32_scalbn( float32 a, int n STATUS_PARAM )
63618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
63628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
6363bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    int16_t aExp;
6364bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint32_t aSig;
63658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6366bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float32_squash_input_denormal(a STATUS_VAR);
63678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloat32Frac( a );
63688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat32Exp( a );
63698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat32Sign( a );
63708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
63718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0xFF ) {
6372bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( aSig ) {
6373bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            return propagateFloat32NaN( a, a STATUS_VAR );
6374bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        }
63758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return a;
63768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
63775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if ( aExp != 0 )
63785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        aSig |= 0x00800000;
63795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else if ( aSig == 0 )
63805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return a;
63815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6382bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if (n > 0x200) {
6383bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        n = 0x200;
6384bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    } else if (n < -0x200) {
6385bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        n = -0x200;
6386bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    }
6387bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
63885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    aExp += n - 1;
63895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    aSig <<= 7;
63905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return normalizeRoundAndPackFloat32( aSign, aExp, aSig STATUS_VAR );
63918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
63928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
63938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat64 float64_scalbn( float64 a, int n STATUS_PARAM )
63948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
63958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
6396bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    int16_t aExp;
6397bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig;
63988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6399bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    a = float64_squash_input_denormal(a STATUS_VAR);
64008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloat64Frac( a );
64018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat64Exp( a );
64028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat64Sign( a );
64038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
64048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0x7FF ) {
6405bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( aSig ) {
6406bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            return propagateFloat64NaN( a, a STATUS_VAR );
6407bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        }
64088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return a;
64098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
64105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if ( aExp != 0 )
64115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        aSig |= LIT64( 0x0010000000000000 );
64125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else if ( aSig == 0 )
64135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return a;
64145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6415bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if (n > 0x1000) {
6416bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        n = 0x1000;
6417bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    } else if (n < -0x1000) {
6418bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        n = -0x1000;
6419bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    }
6420bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
64215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    aExp += n - 1;
64225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    aSig <<= 10;
64235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return normalizeRoundAndPackFloat64( aSign, aExp, aSig STATUS_VAR );
64248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
64258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
64268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef FLOATX80
64278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloatx80 floatx80_scalbn( floatx80 a, int n STATUS_PARAM )
64288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
64298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
6430bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    int32_t aExp;
6431bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig;
64328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
64338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig = extractFloatx80Frac( a );
64348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloatx80Exp( a );
64358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloatx80Sign( a );
64368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6437bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if ( aExp == 0x7FFF ) {
6438bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( aSig<<1 ) {
6439bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            return propagateFloatx80NaN( a, a STATUS_VAR );
6440bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        }
64418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return a;
64428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6443bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
64445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (aExp == 0 && aSig == 0)
64455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return a;
64465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6447bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if (n > 0x10000) {
6448bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        n = 0x10000;
6449bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    } else if (n < -0x10000) {
6450bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        n = -0x10000;
6451bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    }
6452bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
64538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp += n;
64545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return normalizeRoundAndPackFloatx80( STATUS(floatx80_rounding_precision),
64555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                          aSign, aExp, aSig, 0 STATUS_VAR );
64568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
64578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
64588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
64598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef FLOAT128
64608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectfloat128 float128_scalbn( float128 a, int n STATUS_PARAM )
64618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
64628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flag aSign;
6463bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    int32_t aExp;
6464bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    uint64_t aSig0, aSig1;
64658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
64668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig1 = extractFloat128Frac1( a );
64678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSig0 = extractFloat128Frac0( a );
64688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aExp = extractFloat128Exp( a );
64698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    aSign = extractFloat128Sign( a );
64708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( aExp == 0x7FFF ) {
6471bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        if ( aSig0 | aSig1 ) {
6472bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner            return propagateFloat128NaN( a, a STATUS_VAR );
6473bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        }
64748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return a;
64758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
64765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if ( aExp != 0 )
64775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        aSig0 |= LIT64( 0x0001000000000000 );
64785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else if ( aSig0 == 0 && aSig1 == 0 )
64795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return a;
64805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
6481bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    if (n > 0x10000) {
6482bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        n = 0x10000;
6483bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    } else if (n < -0x10000) {
6484bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner        n = -0x10000;
6485bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner    }
6486bfec547677ddf2164ffd49a34c3ace2a41c938adDavid 'Digit' Turner
64875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    aExp += n - 1;
64885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return normalizeRoundAndPackFloat128( aSign, aExp, aSig0, aSig1
64895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                          STATUS_VAR );
64908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
64918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
64928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
6493