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