softfloat-specialize revision 1.1
11.1Sross/* $NetBSD: softfloat-specialize,v 1.1 2001/03/13 07:25:02 ross Exp $ */ 21.1Sross 31.1Sross/* This is a derivative work. */ 41.1Sross 51.1Sross/*- 61.1Sross * Copyright (c) 2001 The NetBSD Foundation, Inc. 71.1Sross * All rights reserved. 81.1Sross * 91.1Sross * This code is derived from software contributed to The NetBSD Foundation 101.1Sross * by Ross Harvey. 111.1Sross * 121.1Sross * Redistribution and use in source and binary forms, with or without 131.1Sross * modification, are permitted provided that the following conditions 141.1Sross * are met: 151.1Sross * 1. Redistributions of source code must retain the above copyright 161.1Sross * notice, this list of conditions and the following disclaimer. 171.1Sross * 2. Redistributions in binary form must reproduce the above copyright 181.1Sross * notice, this list of conditions and the following disclaimer in the 191.1Sross * documentation and/or other materials provided with the distribution. 201.1Sross * 3. All advertising materials mentioning features or use of this software 211.1Sross * must display the following acknowledgement: 221.1Sross * This product includes software developed by the NetBSD 231.1Sross * Foundation, Inc. and its contributors. 241.1Sross * 4. Neither the name of The NetBSD Foundation nor the names of its 251.1Sross * contributors may be used to endorse or promote products derived 261.1Sross * from this software without specific prior written permission. 271.1Sross * 281.1Sross * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 291.1Sross * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 301.1Sross * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 311.1Sross * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 321.1Sross * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 331.1Sross * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 341.1Sross * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 351.1Sross * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 361.1Sross * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 371.1Sross * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 381.1Sross * POSSIBILITY OF SUCH DAMAGE. 391.1Sross */ 401.1Sross 411.1Sross/* 421.1Sross=============================================================================== 431.1Sross 441.1SrossThis C source fragment is part of the SoftFloat IEC/IEEE Floating-point 451.1SrossArithmetic Package, Release 2a. 461.1Sross 471.1SrossWritten by John R. Hauser. This work was made possible in part by the 481.1SrossInternational Computer Science Institute, located at Suite 600, 1947 Center 491.1SrossStreet, Berkeley, California 94704. Funding was partially provided by the 501.1SrossNational Science Foundation under grant MIP-9311980. The original version 511.1Srossof this code was written as part of a project to build a fixed-point vector 521.1Srossprocessor in collaboration with the University of California at Berkeley, 531.1Srossoverseen by Profs. Nelson Morgan and John Wawrzynek. More information 541.1Srossis available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ 551.1Srossarithmetic/SoftFloat.html'. 561.1Sross 571.1SrossTHIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort 581.1Srosshas been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT 591.1SrossTIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO 601.1SrossPERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY 611.1SrossAND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. 621.1Sross 631.1SrossDerivative works are acceptable, even for commercial purposes, so long as 641.1Sross(1) they include prominent notice that the work is derivative, and (2) they 651.1Srossinclude prominent notice akin to these four paragraphs for those parts of 661.1Srossthis code that are retained. 671.1Sross 681.1Sross=============================================================================== 691.1Sross*/ 701.1Sross 711.1Sross/* 721.1Sross------------------------------------------------------------------------------- 731.1SrossUnderflow tininess-detection mode, statically initialized to default value. 741.1Sross------------------------------------------------------------------------------- 751.1Sross*/ 761.1Srossint float_detect_tininess = float_tininess_after_rounding; 771.1Sross 781.1Sross/* 791.1Sross------------------------------------------------------------------------------- 801.1SrossRaises the exceptions specified by `flags'. Floating-point traps can be 811.1Srossdefined here if desired. It is currently not possible for such a trap 821.1Srossto substitute a result value. If traps are not implemented, this routine 831.1Srossshould be simply `float_exception_flags |= flags;'. 841.1Sross------------------------------------------------------------------------------- 851.1Sross*/ 861.1Srossvoid float_raise( int flags ) 871.1Sross{ 881.1Sross 891.1Sross float_exception_flags |= flags; 901.1Sross 911.1Sross} 921.1Sross 931.1Sross/* 941.1Sross------------------------------------------------------------------------------- 951.1SrossInternal canonical NaN format. 961.1Sross------------------------------------------------------------------------------- 971.1Sross*/ 981.1Srosstypedef struct { 991.1Sross flag sign; 1001.1Sross bits64 high, low; 1011.1Sross} commonNaNT; 1021.1Sross 1031.1Sross/* 1041.1Sross------------------------------------------------------------------------------- 1051.1SrossThe pattern for a default generated single-precision NaN. 1061.1Sross------------------------------------------------------------------------------- 1071.1Sross*/ 1081.1Sross#define float32_default_nan 0xFFC00000 1091.1Sross 1101.1Sross/* 1111.1Sross------------------------------------------------------------------------------- 1121.1SrossReturns 1 if the single-precision floating-point value `a' is a NaN; 1131.1Srossotherwise returns 0. 1141.1Sross------------------------------------------------------------------------------- 1151.1Sross*/ 1161.1Srossstatic flag float32_is_nan( float32 a ) 1171.1Sross{ 1181.1Sross 1191.1Sross return ( 0xFF000000 < (bits32) ( a<<1 ) ); 1201.1Sross 1211.1Sross} 1221.1Sross 1231.1Sross/* 1241.1Sross------------------------------------------------------------------------------- 1251.1SrossReturns 1 if the single-precision floating-point value `a' is a signaling 1261.1SrossNaN; otherwise returns 0. 1271.1Sross------------------------------------------------------------------------------- 1281.1Sross*/ 1291.1Srossflag float32_is_signaling_nan( float32 a ) 1301.1Sross{ 1311.1Sross 1321.1Sross return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); 1331.1Sross 1341.1Sross} 1351.1Sross 1361.1Sross/* 1371.1Sross------------------------------------------------------------------------------- 1381.1SrossReturns the result of converting the single-precision floating-point NaN 1391.1Sross`a' to the canonical NaN format. If `a' is a signaling NaN, the invalid 1401.1Srossexception is raised. 1411.1Sross------------------------------------------------------------------------------- 1421.1Sross*/ 1431.1Srossstatic commonNaNT float32ToCommonNaN( float32 a ) 1441.1Sross{ 1451.1Sross commonNaNT z; 1461.1Sross 1471.1Sross if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); 1481.1Sross z.sign = a>>31; 1491.1Sross z.low = 0; 1501.1Sross z.high = ( (bits64) a )<<41; 1511.1Sross return z; 1521.1Sross 1531.1Sross} 1541.1Sross 1551.1Sross/* 1561.1Sross------------------------------------------------------------------------------- 1571.1SrossReturns the result of converting the canonical NaN `a' to the single- 1581.1Srossprecision floating-point format. 1591.1Sross------------------------------------------------------------------------------- 1601.1Sross*/ 1611.1Srossstatic float32 commonNaNToFloat32( commonNaNT a ) 1621.1Sross{ 1631.1Sross 1641.1Sross return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 ); 1651.1Sross 1661.1Sross} 1671.1Sross 1681.1Sross/* 1691.1Sross------------------------------------------------------------------------------- 1701.1SrossTakes two single-precision floating-point values `a' and `b', one of which 1711.1Srossis a NaN, and returns the appropriate NaN result. If either `a' or `b' is a 1721.1Srosssignaling NaN, the invalid exception is raised. 1731.1Sross------------------------------------------------------------------------------- 1741.1Sross*/ 1751.1Srossstatic float32 propagateFloat32NaN( float32 a, float32 b ) 1761.1Sross{ 1771.1Sross flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 1781.1Sross 1791.1Sross aIsNaN = float32_is_nan( a ); 1801.1Sross aIsSignalingNaN = float32_is_signaling_nan( a ); 1811.1Sross bIsNaN = float32_is_nan( b ); 1821.1Sross bIsSignalingNaN = float32_is_signaling_nan( b ); 1831.1Sross a |= 0x00400000; 1841.1Sross b |= 0x00400000; 1851.1Sross if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); 1861.1Sross if ( aIsSignalingNaN ) { 1871.1Sross if ( bIsSignalingNaN ) goto returnLargerSignificand; 1881.1Sross return bIsNaN ? b : a; 1891.1Sross } 1901.1Sross else if ( aIsNaN ) { 1911.1Sross if ( bIsSignalingNaN | ! bIsNaN ) return a; 1921.1Sross returnLargerSignificand: 1931.1Sross if ( (bits32) ( a<<1 ) < (bits32) ( b<<1 ) ) return b; 1941.1Sross if ( (bits32) ( b<<1 ) < (bits32) ( a<<1 ) ) return a; 1951.1Sross return ( a < b ) ? a : b; 1961.1Sross } 1971.1Sross else { 1981.1Sross return b; 1991.1Sross } 2001.1Sross 2011.1Sross} 2021.1Sross 2031.1Sross/* 2041.1Sross------------------------------------------------------------------------------- 2051.1SrossThe pattern for a default generated double-precision NaN. 2061.1Sross------------------------------------------------------------------------------- 2071.1Sross*/ 2081.1Sross#define float64_default_nan LIT64( 0xFFF8000000000000 ) 2091.1Sross 2101.1Sross/* 2111.1Sross------------------------------------------------------------------------------- 2121.1SrossReturns 1 if the double-precision floating-point value `a' is a NaN; 2131.1Srossotherwise returns 0. 2141.1Sross------------------------------------------------------------------------------- 2151.1Sross*/ 2161.1Srossstatic flag float64_is_nan( float64 a ) 2171.1Sross{ 2181.1Sross 2191.1Sross return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) ); 2201.1Sross 2211.1Sross} 2221.1Sross 2231.1Sross/* 2241.1Sross------------------------------------------------------------------------------- 2251.1SrossReturns 1 if the double-precision floating-point value `a' is a signaling 2261.1SrossNaN; otherwise returns 0. 2271.1Sross------------------------------------------------------------------------------- 2281.1Sross*/ 2291.1Srossflag float64_is_signaling_nan( float64 a ) 2301.1Sross{ 2311.1Sross 2321.1Sross return 2331.1Sross ( ( ( a>>51 ) & 0xFFF ) == 0xFFE ) 2341.1Sross && ( a & LIT64( 0x0007FFFFFFFFFFFF ) ); 2351.1Sross 2361.1Sross} 2371.1Sross 2381.1Sross/* 2391.1Sross------------------------------------------------------------------------------- 2401.1SrossReturns the result of converting the double-precision floating-point NaN 2411.1Sross`a' to the canonical NaN format. If `a' is a signaling NaN, the invalid 2421.1Srossexception is raised. 2431.1Sross------------------------------------------------------------------------------- 2441.1Sross*/ 2451.1Srossstatic commonNaNT float64ToCommonNaN( float64 a ) 2461.1Sross{ 2471.1Sross commonNaNT z; 2481.1Sross 2491.1Sross if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); 2501.1Sross z.sign = a>>63; 2511.1Sross z.low = 0; 2521.1Sross z.high = a<<12; 2531.1Sross return z; 2541.1Sross 2551.1Sross} 2561.1Sross 2571.1Sross/* 2581.1Sross------------------------------------------------------------------------------- 2591.1SrossReturns the result of converting the canonical NaN `a' to the double- 2601.1Srossprecision floating-point format. 2611.1Sross------------------------------------------------------------------------------- 2621.1Sross*/ 2631.1Srossstatic float64 commonNaNToFloat64( commonNaNT a ) 2641.1Sross{ 2651.1Sross 2661.1Sross return 2671.1Sross ( ( (bits64) a.sign )<<63 ) 2681.1Sross | LIT64( 0x7FF8000000000000 ) 2691.1Sross | ( a.high>>12 ); 2701.1Sross 2711.1Sross} 2721.1Sross 2731.1Sross/* 2741.1Sross------------------------------------------------------------------------------- 2751.1SrossTakes two double-precision floating-point values `a' and `b', one of which 2761.1Srossis a NaN, and returns the appropriate NaN result. If either `a' or `b' is a 2771.1Srosssignaling NaN, the invalid exception is raised. 2781.1Sross------------------------------------------------------------------------------- 2791.1Sross*/ 2801.1Srossstatic float64 propagateFloat64NaN( float64 a, float64 b ) 2811.1Sross{ 2821.1Sross flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 2831.1Sross 2841.1Sross aIsNaN = float64_is_nan( a ); 2851.1Sross aIsSignalingNaN = float64_is_signaling_nan( a ); 2861.1Sross bIsNaN = float64_is_nan( b ); 2871.1Sross bIsSignalingNaN = float64_is_signaling_nan( b ); 2881.1Sross a |= LIT64( 0x0008000000000000 ); 2891.1Sross b |= LIT64( 0x0008000000000000 ); 2901.1Sross if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); 2911.1Sross if ( aIsSignalingNaN ) { 2921.1Sross if ( bIsSignalingNaN ) goto returnLargerSignificand; 2931.1Sross return bIsNaN ? b : a; 2941.1Sross } 2951.1Sross else if ( aIsNaN ) { 2961.1Sross if ( bIsSignalingNaN | ! bIsNaN ) return a; 2971.1Sross returnLargerSignificand: 2981.1Sross if ( (bits64) ( a<<1 ) < (bits64) ( b<<1 ) ) return b; 2991.1Sross if ( (bits64) ( b<<1 ) < (bits64) ( a<<1 ) ) return a; 3001.1Sross return ( a < b ) ? a : b; 3011.1Sross } 3021.1Sross else { 3031.1Sross return b; 3041.1Sross } 3051.1Sross 3061.1Sross} 3071.1Sross 3081.1Sross#ifdef FLOATX80 3091.1Sross 3101.1Sross/* 3111.1Sross------------------------------------------------------------------------------- 3121.1SrossThe pattern for a default generated extended double-precision NaN. The 3131.1Sross`high' and `low' values hold the most- and least-significant bits, 3141.1Srossrespectively. 3151.1Sross------------------------------------------------------------------------------- 3161.1Sross*/ 3171.1Sross#define floatx80_default_nan_high 0xFFFF 3181.1Sross#define floatx80_default_nan_low LIT64( 0xC000000000000000 ) 3191.1Sross 3201.1Sross/* 3211.1Sross------------------------------------------------------------------------------- 3221.1SrossReturns 1 if the extended double-precision floating-point value `a' is a 3231.1SrossNaN; otherwise returns 0. 3241.1Sross------------------------------------------------------------------------------- 3251.1Sross*/ 3261.1Srossstatic flag floatx80_is_nan( floatx80 a ) 3271.1Sross{ 3281.1Sross 3291.1Sross return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 ); 3301.1Sross 3311.1Sross} 3321.1Sross 3331.1Sross/* 3341.1Sross------------------------------------------------------------------------------- 3351.1SrossReturns 1 if the extended double-precision floating-point value `a' is a 3361.1Srosssignaling NaN; otherwise returns 0. 3371.1Sross------------------------------------------------------------------------------- 3381.1Sross*/ 3391.1Srossflag floatx80_is_signaling_nan( floatx80 a ) 3401.1Sross{ 3411.1Sross bits64 aLow; 3421.1Sross 3431.1Sross aLow = a.low & ~ LIT64( 0x4000000000000000 ); 3441.1Sross return 3451.1Sross ( ( a.high & 0x7FFF ) == 0x7FFF ) 3461.1Sross && (bits64) ( aLow<<1 ) 3471.1Sross && ( a.low == aLow ); 3481.1Sross 3491.1Sross} 3501.1Sross 3511.1Sross/* 3521.1Sross------------------------------------------------------------------------------- 3531.1SrossReturns the result of converting the extended double-precision floating- 3541.1Srosspoint NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the 3551.1Srossinvalid exception is raised. 3561.1Sross------------------------------------------------------------------------------- 3571.1Sross*/ 3581.1Srossstatic commonNaNT floatx80ToCommonNaN( floatx80 a ) 3591.1Sross{ 3601.1Sross commonNaNT z; 3611.1Sross 3621.1Sross if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); 3631.1Sross z.sign = a.high>>15; 3641.1Sross z.low = 0; 3651.1Sross z.high = a.low<<1; 3661.1Sross return z; 3671.1Sross 3681.1Sross} 3691.1Sross 3701.1Sross/* 3711.1Sross------------------------------------------------------------------------------- 3721.1SrossReturns the result of converting the canonical NaN `a' to the extended 3731.1Srossdouble-precision floating-point format. 3741.1Sross------------------------------------------------------------------------------- 3751.1Sross*/ 3761.1Srossstatic floatx80 commonNaNToFloatx80( commonNaNT a ) 3771.1Sross{ 3781.1Sross floatx80 z; 3791.1Sross 3801.1Sross z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 ); 3811.1Sross z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF; 3821.1Sross return z; 3831.1Sross 3841.1Sross} 3851.1Sross 3861.1Sross/* 3871.1Sross------------------------------------------------------------------------------- 3881.1SrossTakes two extended double-precision floating-point values `a' and `b', one 3891.1Srossof which is a NaN, and returns the appropriate NaN result. If either `a' or 3901.1Sross`b' is a signaling NaN, the invalid exception is raised. 3911.1Sross------------------------------------------------------------------------------- 3921.1Sross*/ 3931.1Srossstatic floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b ) 3941.1Sross{ 3951.1Sross flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 3961.1Sross 3971.1Sross aIsNaN = floatx80_is_nan( a ); 3981.1Sross aIsSignalingNaN = floatx80_is_signaling_nan( a ); 3991.1Sross bIsNaN = floatx80_is_nan( b ); 4001.1Sross bIsSignalingNaN = floatx80_is_signaling_nan( b ); 4011.1Sross a.low |= LIT64( 0xC000000000000000 ); 4021.1Sross b.low |= LIT64( 0xC000000000000000 ); 4031.1Sross if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); 4041.1Sross if ( aIsSignalingNaN ) { 4051.1Sross if ( bIsSignalingNaN ) goto returnLargerSignificand; 4061.1Sross return bIsNaN ? b : a; 4071.1Sross } 4081.1Sross else if ( aIsNaN ) { 4091.1Sross if ( bIsSignalingNaN | ! bIsNaN ) return a; 4101.1Sross returnLargerSignificand: 4111.1Sross if ( a.low < b.low ) return b; 4121.1Sross if ( b.low < a.low ) return a; 4131.1Sross return ( a.high < b.high ) ? a : b; 4141.1Sross } 4151.1Sross else { 4161.1Sross return b; 4171.1Sross } 4181.1Sross 4191.1Sross} 4201.1Sross 4211.1Sross#endif 4221.1Sross 4231.1Sross#ifdef FLOAT128 4241.1Sross 4251.1Sross/* 4261.1Sross------------------------------------------------------------------------------- 4271.1SrossThe pattern for a default generated quadruple-precision NaN. The `high' and 4281.1Sross`low' values hold the most- and least-significant bits, respectively. 4291.1Sross------------------------------------------------------------------------------- 4301.1Sross*/ 4311.1Sross#define float128_default_nan_high LIT64( 0xFFFF800000000000 ) 4321.1Sross#define float128_default_nan_low LIT64( 0x0000000000000000 ) 4331.1Sross 4341.1Sross/* 4351.1Sross------------------------------------------------------------------------------- 4361.1SrossReturns 1 if the quadruple-precision floating-point value `a' is a NaN; 4371.1Srossotherwise returns 0. 4381.1Sross------------------------------------------------------------------------------- 4391.1Sross*/ 4401.1Srossflag float128_is_nan( float128 a ) 4411.1Sross{ 4421.1Sross 4431.1Sross return 4441.1Sross ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) ) 4451.1Sross && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) ); 4461.1Sross 4471.1Sross} 4481.1Sross 4491.1Sross/* 4501.1Sross------------------------------------------------------------------------------- 4511.1SrossReturns 1 if the quadruple-precision floating-point value `a' is a 4521.1Srosssignaling NaN; otherwise returns 0. 4531.1Sross------------------------------------------------------------------------------- 4541.1Sross*/ 4551.1Srossflag float128_is_signaling_nan( float128 a ) 4561.1Sross{ 4571.1Sross 4581.1Sross return 4591.1Sross ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE ) 4601.1Sross && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) ); 4611.1Sross 4621.1Sross} 4631.1Sross 4641.1Sross/* 4651.1Sross------------------------------------------------------------------------------- 4661.1SrossReturns the result of converting the quadruple-precision floating-point NaN 4671.1Sross`a' to the canonical NaN format. If `a' is a signaling NaN, the invalid 4681.1Srossexception is raised. 4691.1Sross------------------------------------------------------------------------------- 4701.1Sross*/ 4711.1Srossstatic commonNaNT float128ToCommonNaN( float128 a ) 4721.1Sross{ 4731.1Sross commonNaNT z; 4741.1Sross 4751.1Sross if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); 4761.1Sross z.sign = a.high>>63; 4771.1Sross shortShift128Left( a.high, a.low, 16, &z.high, &z.low ); 4781.1Sross return z; 4791.1Sross 4801.1Sross} 4811.1Sross 4821.1Sross/* 4831.1Sross------------------------------------------------------------------------------- 4841.1SrossReturns the result of converting the canonical NaN `a' to the quadruple- 4851.1Srossprecision floating-point format. 4861.1Sross------------------------------------------------------------------------------- 4871.1Sross*/ 4881.1Srossstatic float128 commonNaNToFloat128( commonNaNT a ) 4891.1Sross{ 4901.1Sross float128 z; 4911.1Sross 4921.1Sross shift128Right( a.high, a.low, 16, &z.high, &z.low ); 4931.1Sross z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 ); 4941.1Sross return z; 4951.1Sross 4961.1Sross} 4971.1Sross 4981.1Sross/* 4991.1Sross------------------------------------------------------------------------------- 5001.1SrossTakes two quadruple-precision floating-point values `a' and `b', one of 5011.1Srosswhich is a NaN, and returns the appropriate NaN result. If either `a' or 5021.1Sross`b' is a signaling NaN, the invalid exception is raised. 5031.1Sross------------------------------------------------------------------------------- 5041.1Sross*/ 5051.1Srossstatic float128 propagateFloat128NaN( float128 a, float128 b ) 5061.1Sross{ 5071.1Sross flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 5081.1Sross 5091.1Sross aIsNaN = float128_is_nan( a ); 5101.1Sross aIsSignalingNaN = float128_is_signaling_nan( a ); 5111.1Sross bIsNaN = float128_is_nan( b ); 5121.1Sross bIsSignalingNaN = float128_is_signaling_nan( b ); 5131.1Sross a.high |= LIT64( 0x0000800000000000 ); 5141.1Sross b.high |= LIT64( 0x0000800000000000 ); 5151.1Sross if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); 5161.1Sross if ( aIsSignalingNaN ) { 5171.1Sross if ( bIsSignalingNaN ) goto returnLargerSignificand; 5181.1Sross return bIsNaN ? b : a; 5191.1Sross } 5201.1Sross else if ( aIsNaN ) { 5211.1Sross if ( bIsSignalingNaN | ! bIsNaN ) return a; 5221.1Sross returnLargerSignificand: 5231.1Sross if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b; 5241.1Sross if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a; 5251.1Sross return ( a.high < b.high ) ? a : b; 5261.1Sross } 5271.1Sross else { 5281.1Sross return b; 5291.1Sross } 5301.1Sross 5311.1Sross} 5321.1Sross 5331.1Sross#endif 5341.1Sross 535