18c2ecf20Sopenharmony_ci
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci===============================================================================
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ciThis C source fragment is part of the SoftFloat IEC/IEEE Floating-point
68c2ecf20Sopenharmony_ciArithmetic Package, Release 2.
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ciWritten by John R. Hauser.  This work was made possible in part by the
98c2ecf20Sopenharmony_ciInternational Computer Science Institute, located at Suite 600, 1947 Center
108c2ecf20Sopenharmony_ciStreet, Berkeley, California 94704.  Funding was partially provided by the
118c2ecf20Sopenharmony_ciNational Science Foundation under grant MIP-9311980.  The original version
128c2ecf20Sopenharmony_ciof this code was written as part of a project to build a fixed-point vector
138c2ecf20Sopenharmony_ciprocessor in collaboration with the University of California at Berkeley,
148c2ecf20Sopenharmony_cioverseen by Profs. Nelson Morgan and John Wawrzynek.  More information
158c2ecf20Sopenharmony_ciis available through the Web page
168c2ecf20Sopenharmony_cihttp://www.jhauser.us/arithmetic/SoftFloat-2b/SoftFloat-source.txt
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ciTHIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
198c2ecf20Sopenharmony_cihas been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
208c2ecf20Sopenharmony_ciTIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
218c2ecf20Sopenharmony_ciPERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
228c2ecf20Sopenharmony_ciAND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ciDerivative works are acceptable, even for commercial purposes, so long as
258c2ecf20Sopenharmony_ci(1) they include prominent notice that the work is derivative, and (2) they
268c2ecf20Sopenharmony_ciinclude prominent notice akin to these three paragraphs for those parts of
278c2ecf20Sopenharmony_cithis code that are retained.
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci===============================================================================
308c2ecf20Sopenharmony_ci*/
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci/*
338c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
348c2ecf20Sopenharmony_ciUnderflow tininess-detection mode, statically initialized to default value.
358c2ecf20Sopenharmony_ci(The declaration in `softfloat.h' must match the `int8' type here.)
368c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
378c2ecf20Sopenharmony_ci*/
388c2ecf20Sopenharmony_ciint8 float_detect_tininess = float_tininess_after_rounding;
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci/*
418c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
428c2ecf20Sopenharmony_ciRaises the exceptions specified by `flags'.  Floating-point traps can be
438c2ecf20Sopenharmony_cidefined here if desired.  It is currently not possible for such a trap to
448c2ecf20Sopenharmony_cisubstitute a result value.  If traps are not implemented, this routine
458c2ecf20Sopenharmony_cishould be simply `float_exception_flags |= flags;'.
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ciScottB:  November 4, 1998
488c2ecf20Sopenharmony_ciMoved this function out of softfloat-specialize into fpmodule.c.
498c2ecf20Sopenharmony_ciThis effectively isolates all the changes required for integrating with the
508c2ecf20Sopenharmony_ciLinux kernel into fpmodule.c.  Porting to NetBSD should only require modifying
518c2ecf20Sopenharmony_cifpmodule.c to integrate with the NetBSD kernel (I hope!).
528c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
538c2ecf20Sopenharmony_civoid float_raise( int8 flags )
548c2ecf20Sopenharmony_ci{
558c2ecf20Sopenharmony_ci    float_exception_flags |= flags;
568c2ecf20Sopenharmony_ci}
578c2ecf20Sopenharmony_ci*/
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci/*
608c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
618c2ecf20Sopenharmony_ciInternal canonical NaN format.
628c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
638c2ecf20Sopenharmony_ci*/
648c2ecf20Sopenharmony_citypedef struct {
658c2ecf20Sopenharmony_ci    flag sign;
668c2ecf20Sopenharmony_ci    bits64 high, low;
678c2ecf20Sopenharmony_ci} commonNaNT;
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci/*
708c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
718c2ecf20Sopenharmony_ciThe pattern for a default generated single-precision NaN.
728c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
738c2ecf20Sopenharmony_ci*/
748c2ecf20Sopenharmony_ci#define float32_default_nan 0xFFFFFFFF
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci/*
778c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
788c2ecf20Sopenharmony_ciReturns 1 if the single-precision floating-point value `a' is a NaN;
798c2ecf20Sopenharmony_ciotherwise returns 0.
808c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
818c2ecf20Sopenharmony_ci*/
828c2ecf20Sopenharmony_ciflag float32_is_nan( float32 a )
838c2ecf20Sopenharmony_ci{
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci    return ( 0xFF000000 < (bits32) ( a<<1 ) );
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci}
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci/*
908c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
918c2ecf20Sopenharmony_ciReturns 1 if the single-precision floating-point value `a' is a signaling
928c2ecf20Sopenharmony_ciNaN; otherwise returns 0.
938c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
948c2ecf20Sopenharmony_ci*/
958c2ecf20Sopenharmony_ciflag float32_is_signaling_nan( float32 a )
968c2ecf20Sopenharmony_ci{
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ci    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci}
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci/*
1038c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
1048c2ecf20Sopenharmony_ciReturns the result of converting the single-precision floating-point NaN
1058c2ecf20Sopenharmony_ci`a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
1068c2ecf20Sopenharmony_ciexception is raised.
1078c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
1088c2ecf20Sopenharmony_ci*/
1098c2ecf20Sopenharmony_cistatic commonNaNT float32ToCommonNaN( float32 a )
1108c2ecf20Sopenharmony_ci{
1118c2ecf20Sopenharmony_ci    commonNaNT z;
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_ci    if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
1148c2ecf20Sopenharmony_ci    z.sign = a>>31;
1158c2ecf20Sopenharmony_ci    z.low = 0;
1168c2ecf20Sopenharmony_ci    z.high = ( (bits64) a )<<41;
1178c2ecf20Sopenharmony_ci    return z;
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci}
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_ci/*
1228c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
1238c2ecf20Sopenharmony_ciReturns the result of converting the canonical NaN `a' to the single-
1248c2ecf20Sopenharmony_ciprecision floating-point format.
1258c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
1268c2ecf20Sopenharmony_ci*/
1278c2ecf20Sopenharmony_cistatic float32 commonNaNToFloat32( commonNaNT a )
1288c2ecf20Sopenharmony_ci{
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ci    return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
1318c2ecf20Sopenharmony_ci
1328c2ecf20Sopenharmony_ci}
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ci/*
1358c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
1368c2ecf20Sopenharmony_ciTakes two single-precision floating-point values `a' and `b', one of which
1378c2ecf20Sopenharmony_ciis a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
1388c2ecf20Sopenharmony_cisignaling NaN, the invalid exception is raised.
1398c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
1408c2ecf20Sopenharmony_ci*/
1418c2ecf20Sopenharmony_cistatic float32 propagateFloat32NaN( float32 a, float32 b )
1428c2ecf20Sopenharmony_ci{
1438c2ecf20Sopenharmony_ci    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_ci    aIsNaN = float32_is_nan( a );
1468c2ecf20Sopenharmony_ci    aIsSignalingNaN = float32_is_signaling_nan( a );
1478c2ecf20Sopenharmony_ci    bIsNaN = float32_is_nan( b );
1488c2ecf20Sopenharmony_ci    bIsSignalingNaN = float32_is_signaling_nan( b );
1498c2ecf20Sopenharmony_ci    a |= 0x00400000;
1508c2ecf20Sopenharmony_ci    b |= 0x00400000;
1518c2ecf20Sopenharmony_ci    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
1528c2ecf20Sopenharmony_ci    if ( aIsNaN ) {
1538c2ecf20Sopenharmony_ci        return ( aIsSignalingNaN & bIsNaN ) ? b : a;
1548c2ecf20Sopenharmony_ci    }
1558c2ecf20Sopenharmony_ci    else {
1568c2ecf20Sopenharmony_ci        return b;
1578c2ecf20Sopenharmony_ci    }
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci}
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_ci/*
1628c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
1638c2ecf20Sopenharmony_ciThe pattern for a default generated double-precision NaN.
1648c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
1658c2ecf20Sopenharmony_ci*/
1668c2ecf20Sopenharmony_ci#define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF )
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_ci/*
1698c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
1708c2ecf20Sopenharmony_ciReturns 1 if the double-precision floating-point value `a' is a NaN;
1718c2ecf20Sopenharmony_ciotherwise returns 0.
1728c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
1738c2ecf20Sopenharmony_ci*/
1748c2ecf20Sopenharmony_ciflag float64_is_nan( float64 a )
1758c2ecf20Sopenharmony_ci{
1768c2ecf20Sopenharmony_ci
1778c2ecf20Sopenharmony_ci    return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) );
1788c2ecf20Sopenharmony_ci
1798c2ecf20Sopenharmony_ci}
1808c2ecf20Sopenharmony_ci
1818c2ecf20Sopenharmony_ci/*
1828c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
1838c2ecf20Sopenharmony_ciReturns 1 if the double-precision floating-point value `a' is a signaling
1848c2ecf20Sopenharmony_ciNaN; otherwise returns 0.
1858c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
1868c2ecf20Sopenharmony_ci*/
1878c2ecf20Sopenharmony_ciflag float64_is_signaling_nan( float64 a )
1888c2ecf20Sopenharmony_ci{
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_ci    return
1918c2ecf20Sopenharmony_ci           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
1928c2ecf20Sopenharmony_ci        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
1938c2ecf20Sopenharmony_ci
1948c2ecf20Sopenharmony_ci}
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_ci/*
1978c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
1988c2ecf20Sopenharmony_ciReturns the result of converting the double-precision floating-point NaN
1998c2ecf20Sopenharmony_ci`a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
2008c2ecf20Sopenharmony_ciexception is raised.
2018c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
2028c2ecf20Sopenharmony_ci*/
2038c2ecf20Sopenharmony_cistatic commonNaNT float64ToCommonNaN( float64 a )
2048c2ecf20Sopenharmony_ci{
2058c2ecf20Sopenharmony_ci    commonNaNT z;
2068c2ecf20Sopenharmony_ci
2078c2ecf20Sopenharmony_ci    if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
2088c2ecf20Sopenharmony_ci    z.sign = a>>63;
2098c2ecf20Sopenharmony_ci    z.low = 0;
2108c2ecf20Sopenharmony_ci    z.high = a<<12;
2118c2ecf20Sopenharmony_ci    return z;
2128c2ecf20Sopenharmony_ci
2138c2ecf20Sopenharmony_ci}
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_ci/*
2168c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
2178c2ecf20Sopenharmony_ciReturns the result of converting the canonical NaN `a' to the double-
2188c2ecf20Sopenharmony_ciprecision floating-point format.
2198c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
2208c2ecf20Sopenharmony_ci*/
2218c2ecf20Sopenharmony_cistatic float64 commonNaNToFloat64( commonNaNT a )
2228c2ecf20Sopenharmony_ci{
2238c2ecf20Sopenharmony_ci
2248c2ecf20Sopenharmony_ci    return
2258c2ecf20Sopenharmony_ci          ( ( (bits64) a.sign )<<63 )
2268c2ecf20Sopenharmony_ci        | LIT64( 0x7FF8000000000000 )
2278c2ecf20Sopenharmony_ci        | ( a.high>>12 );
2288c2ecf20Sopenharmony_ci
2298c2ecf20Sopenharmony_ci}
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_ci/*
2328c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
2338c2ecf20Sopenharmony_ciTakes two double-precision floating-point values `a' and `b', one of which
2348c2ecf20Sopenharmony_ciis a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
2358c2ecf20Sopenharmony_cisignaling NaN, the invalid exception is raised.
2368c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
2378c2ecf20Sopenharmony_ci*/
2388c2ecf20Sopenharmony_cistatic float64 propagateFloat64NaN( float64 a, float64 b )
2398c2ecf20Sopenharmony_ci{
2408c2ecf20Sopenharmony_ci    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
2418c2ecf20Sopenharmony_ci
2428c2ecf20Sopenharmony_ci    aIsNaN = float64_is_nan( a );
2438c2ecf20Sopenharmony_ci    aIsSignalingNaN = float64_is_signaling_nan( a );
2448c2ecf20Sopenharmony_ci    bIsNaN = float64_is_nan( b );
2458c2ecf20Sopenharmony_ci    bIsSignalingNaN = float64_is_signaling_nan( b );
2468c2ecf20Sopenharmony_ci    a |= LIT64( 0x0008000000000000 );
2478c2ecf20Sopenharmony_ci    b |= LIT64( 0x0008000000000000 );
2488c2ecf20Sopenharmony_ci    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
2498c2ecf20Sopenharmony_ci    if ( aIsNaN ) {
2508c2ecf20Sopenharmony_ci        return ( aIsSignalingNaN & bIsNaN ) ? b : a;
2518c2ecf20Sopenharmony_ci    }
2528c2ecf20Sopenharmony_ci    else {
2538c2ecf20Sopenharmony_ci        return b;
2548c2ecf20Sopenharmony_ci    }
2558c2ecf20Sopenharmony_ci
2568c2ecf20Sopenharmony_ci}
2578c2ecf20Sopenharmony_ci
2588c2ecf20Sopenharmony_ci#ifdef FLOATX80
2598c2ecf20Sopenharmony_ci
2608c2ecf20Sopenharmony_ci/*
2618c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
2628c2ecf20Sopenharmony_ciThe pattern for a default generated extended double-precision NaN.  The
2638c2ecf20Sopenharmony_ci`high' and `low' values hold the most- and least-significant bits,
2648c2ecf20Sopenharmony_cirespectively.
2658c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
2668c2ecf20Sopenharmony_ci*/
2678c2ecf20Sopenharmony_ci#define floatx80_default_nan_high 0xFFFF
2688c2ecf20Sopenharmony_ci#define floatx80_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
2698c2ecf20Sopenharmony_ci
2708c2ecf20Sopenharmony_ci/*
2718c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
2728c2ecf20Sopenharmony_ciReturns 1 if the extended double-precision floating-point value `a' is a
2738c2ecf20Sopenharmony_ciNaN; otherwise returns 0.
2748c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
2758c2ecf20Sopenharmony_ci*/
2768c2ecf20Sopenharmony_ciflag floatx80_is_nan( floatx80 a )
2778c2ecf20Sopenharmony_ci{
2788c2ecf20Sopenharmony_ci
2798c2ecf20Sopenharmony_ci    return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
2808c2ecf20Sopenharmony_ci
2818c2ecf20Sopenharmony_ci}
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_ci/*
2848c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
2858c2ecf20Sopenharmony_ciReturns 1 if the extended double-precision floating-point value `a' is a
2868c2ecf20Sopenharmony_cisignaling NaN; otherwise returns 0.
2878c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
2888c2ecf20Sopenharmony_ci*/
2898c2ecf20Sopenharmony_ciflag floatx80_is_signaling_nan( floatx80 a )
2908c2ecf20Sopenharmony_ci{
2918c2ecf20Sopenharmony_ci    //register int lr;
2928c2ecf20Sopenharmony_ci    bits64 aLow;
2938c2ecf20Sopenharmony_ci
2948c2ecf20Sopenharmony_ci    //__asm__("mov %0, lr" : : "g" (lr));
2958c2ecf20Sopenharmony_ci    //fp_printk("floatx80_is_signalling_nan() called from 0x%08x\n",lr);
2968c2ecf20Sopenharmony_ci    aLow = a.low & ~ LIT64( 0x4000000000000000 );
2978c2ecf20Sopenharmony_ci    return
2988c2ecf20Sopenharmony_ci           ( ( a.high & 0x7FFF ) == 0x7FFF )
2998c2ecf20Sopenharmony_ci        && (bits64) ( aLow<<1 )
3008c2ecf20Sopenharmony_ci        && ( a.low == aLow );
3018c2ecf20Sopenharmony_ci
3028c2ecf20Sopenharmony_ci}
3038c2ecf20Sopenharmony_ci
3048c2ecf20Sopenharmony_ci/*
3058c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
3068c2ecf20Sopenharmony_ciReturns the result of converting the extended double-precision floating-
3078c2ecf20Sopenharmony_cipoint NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
3088c2ecf20Sopenharmony_ciinvalid exception is raised.
3098c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
3108c2ecf20Sopenharmony_ci*/
3118c2ecf20Sopenharmony_cistatic commonNaNT floatx80ToCommonNaN( floatx80 a )
3128c2ecf20Sopenharmony_ci{
3138c2ecf20Sopenharmony_ci    commonNaNT z;
3148c2ecf20Sopenharmony_ci
3158c2ecf20Sopenharmony_ci    if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
3168c2ecf20Sopenharmony_ci    z.sign = a.high>>15;
3178c2ecf20Sopenharmony_ci    z.low = 0;
3188c2ecf20Sopenharmony_ci    z.high = a.low<<1;
3198c2ecf20Sopenharmony_ci    return z;
3208c2ecf20Sopenharmony_ci
3218c2ecf20Sopenharmony_ci}
3228c2ecf20Sopenharmony_ci
3238c2ecf20Sopenharmony_ci/*
3248c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
3258c2ecf20Sopenharmony_ciReturns the result of converting the canonical NaN `a' to the extended
3268c2ecf20Sopenharmony_cidouble-precision floating-point format.
3278c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
3288c2ecf20Sopenharmony_ci*/
3298c2ecf20Sopenharmony_cistatic floatx80 commonNaNToFloatx80( commonNaNT a )
3308c2ecf20Sopenharmony_ci{
3318c2ecf20Sopenharmony_ci    floatx80 z;
3328c2ecf20Sopenharmony_ci
3338c2ecf20Sopenharmony_ci    z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
3348c2ecf20Sopenharmony_ci    z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
3358c2ecf20Sopenharmony_ci    z.__padding = 0;
3368c2ecf20Sopenharmony_ci    return z;
3378c2ecf20Sopenharmony_ci
3388c2ecf20Sopenharmony_ci}
3398c2ecf20Sopenharmony_ci
3408c2ecf20Sopenharmony_ci/*
3418c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
3428c2ecf20Sopenharmony_ciTakes two extended double-precision floating-point values `a' and `b', one
3438c2ecf20Sopenharmony_ciof which is a NaN, and returns the appropriate NaN result.  If either `a' or
3448c2ecf20Sopenharmony_ci`b' is a signaling NaN, the invalid exception is raised.
3458c2ecf20Sopenharmony_ci-------------------------------------------------------------------------------
3468c2ecf20Sopenharmony_ci*/
3478c2ecf20Sopenharmony_cistatic floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
3488c2ecf20Sopenharmony_ci{
3498c2ecf20Sopenharmony_ci    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
3508c2ecf20Sopenharmony_ci
3518c2ecf20Sopenharmony_ci    aIsNaN = floatx80_is_nan( a );
3528c2ecf20Sopenharmony_ci    aIsSignalingNaN = floatx80_is_signaling_nan( a );
3538c2ecf20Sopenharmony_ci    bIsNaN = floatx80_is_nan( b );
3548c2ecf20Sopenharmony_ci    bIsSignalingNaN = floatx80_is_signaling_nan( b );
3558c2ecf20Sopenharmony_ci    a.low |= LIT64( 0xC000000000000000 );
3568c2ecf20Sopenharmony_ci    b.low |= LIT64( 0xC000000000000000 );
3578c2ecf20Sopenharmony_ci    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
3588c2ecf20Sopenharmony_ci    if ( aIsNaN ) {
3598c2ecf20Sopenharmony_ci        return ( aIsSignalingNaN & bIsNaN ) ? b : a;
3608c2ecf20Sopenharmony_ci    }
3618c2ecf20Sopenharmony_ci    else {
3628c2ecf20Sopenharmony_ci        return b;
3638c2ecf20Sopenharmony_ci    }
3648c2ecf20Sopenharmony_ci
3658c2ecf20Sopenharmony_ci}
3668c2ecf20Sopenharmony_ci
3678c2ecf20Sopenharmony_ci#endif
368