1*547b3a3bSmatt/* $NetBSD: softfloat-specialize,v 1.9 2014/08/10 05:57:31 matt Exp $ */ 2010758bfSbjh21 3010758bfSbjh21/* This is a derivative work. */ 425540ecaSbjh21 525540ecaSbjh21/* 625540ecaSbjh21=============================================================================== 725540ecaSbjh21 825540ecaSbjh21This C source fragment is part of the SoftFloat IEC/IEEE Floating-point 925540ecaSbjh21Arithmetic Package, Release 2a. 1025540ecaSbjh21 1125540ecaSbjh21Written by John R. Hauser. This work was made possible in part by the 1225540ecaSbjh21International Computer Science Institute, located at Suite 600, 1947 Center 1325540ecaSbjh21Street, Berkeley, California 94704. Funding was partially provided by the 1425540ecaSbjh21National Science Foundation under grant MIP-9311980. The original version 1525540ecaSbjh21of this code was written as part of a project to build a fixed-point vector 1625540ecaSbjh21processor in collaboration with the University of California at Berkeley, 1725540ecaSbjh21overseen by Profs. Nelson Morgan and John Wawrzynek. More information 1825540ecaSbjh21is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ 1925540ecaSbjh21arithmetic/SoftFloat.html'. 2025540ecaSbjh21 2125540ecaSbjh21THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort 2225540ecaSbjh21has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT 2325540ecaSbjh21TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO 2425540ecaSbjh21PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY 2525540ecaSbjh21AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. 2625540ecaSbjh21 2725540ecaSbjh21Derivative works are acceptable, even for commercial purposes, so long as 2825540ecaSbjh21(1) they include prominent notice that the work is derivative, and (2) they 2925540ecaSbjh21include prominent notice akin to these four paragraphs for those parts of 3025540ecaSbjh21this code that are retained. 3125540ecaSbjh21 3225540ecaSbjh21=============================================================================== 3325540ecaSbjh21*/ 3425540ecaSbjh21 35010758bfSbjh21#include <signal.h> 36a5ad4202Smartin#include <string.h> 37a5ad4202Smartin#include <unistd.h> 38010758bfSbjh21 3925540ecaSbjh21/* 4025540ecaSbjh21------------------------------------------------------------------------------- 4125540ecaSbjh21Underflow tininess-detection mode, statically initialized to default value. 4225540ecaSbjh21(The declaration in `softfloat.h' must match the `int8' type here.) 4325540ecaSbjh21------------------------------------------------------------------------------- 4425540ecaSbjh21*/ 4525540ecaSbjh21#ifdef SOFTFLOAT_FOR_GCC 4625540ecaSbjh21static 4725540ecaSbjh21#endif 4825540ecaSbjh21int8 float_detect_tininess = float_tininess_after_rounding; 4925540ecaSbjh21 5025540ecaSbjh21/* 5125540ecaSbjh21------------------------------------------------------------------------------- 5225540ecaSbjh21Raises the exceptions specified by `flags'. Floating-point traps can be 5325540ecaSbjh21defined here if desired. It is currently not possible for such a trap to 5425540ecaSbjh21substitute a result value. If traps are not implemented, this routine 5525540ecaSbjh21should be simply `float_exception_flags |= flags;'. 5625540ecaSbjh21------------------------------------------------------------------------------- 5725540ecaSbjh21*/ 58598174ebSmartin#ifdef SOFTFLOAT_FOR_GCC 59536ad833Smatt#ifndef set_float_exception_mask 60598174ebSmartin#define float_exception_mask _softfloat_float_exception_mask 61598174ebSmartin#endif 62536ad833Smatt#endif 63536ad833Smatt#ifndef set_float_exception_mask 64010758bfSbjh21fp_except float_exception_mask = 0; 65536ad833Smatt#endif 66536ad833Smattvoid 67536ad833Smattfloat_raise( fp_except flags ) 6825540ecaSbjh21{ 69a5ad4202Smartin siginfo_t info; 70536ad833Smatt fp_except mask = float_exception_mask; 7125540ecaSbjh21 72536ad833Smatt#ifdef set_float_exception_mask 73536ad833Smatt flags |= set_float_exception_flags(flags, 0); 74536ad833Smatt#else 7525540ecaSbjh21 float_exception_flags |= flags; 76536ad833Smatt flags = float_exception_flags; 77536ad833Smatt#endif 7825540ecaSbjh21 79536ad833Smatt flags &= mask; 80536ad833Smatt if ( flags ) { 81a5ad4202Smartin memset(&info, 0, sizeof info); 82a5ad4202Smartin info.si_signo = SIGFPE; 83a5ad4202Smartin info.si_pid = getpid(); 84a5ad4202Smartin info.si_uid = geteuid(); 85a5ad4202Smartin if (flags & float_flag_underflow) 86a5ad4202Smartin info.si_code = FPE_FLTUND; 87a5ad4202Smartin else if (flags & float_flag_overflow) 88a5ad4202Smartin info.si_code = FPE_FLTOVF; 89a5ad4202Smartin else if (flags & float_flag_divbyzero) 90a5ad4202Smartin info.si_code = FPE_FLTDIV; 91a5ad4202Smartin else if (flags & float_flag_invalid) 92a5ad4202Smartin info.si_code = FPE_FLTINV; 93a5ad4202Smartin else if (flags & float_flag_inexact) 94a5ad4202Smartin info.si_code = FPE_FLTRES; 95a5ad4202Smartin sigqueueinfo(getpid(), &info); 96010758bfSbjh21 } 9725540ecaSbjh21} 98598174ebSmartin#undef float_exception_mask 9925540ecaSbjh21 10025540ecaSbjh21/* 10125540ecaSbjh21------------------------------------------------------------------------------- 10225540ecaSbjh21Internal canonical NaN format. 10325540ecaSbjh21------------------------------------------------------------------------------- 10425540ecaSbjh21*/ 10525540ecaSbjh21typedef struct { 10625540ecaSbjh21 flag sign; 10725540ecaSbjh21 bits64 high, low; 10825540ecaSbjh21} commonNaNT; 10925540ecaSbjh21 11025540ecaSbjh21/* 11125540ecaSbjh21------------------------------------------------------------------------------- 11225540ecaSbjh21The pattern for a default generated single-precision NaN. 11325540ecaSbjh21------------------------------------------------------------------------------- 11425540ecaSbjh21*/ 11525540ecaSbjh21#define float32_default_nan 0xFFFFFFFF 11625540ecaSbjh21 11725540ecaSbjh21/* 11825540ecaSbjh21------------------------------------------------------------------------------- 11925540ecaSbjh21Returns 1 if the single-precision floating-point value `a' is a NaN; 12025540ecaSbjh21otherwise returns 0. 12125540ecaSbjh21------------------------------------------------------------------------------- 12225540ecaSbjh21*/ 12325540ecaSbjh21#ifdef SOFTFLOAT_FOR_GCC 12425540ecaSbjh21static 12525540ecaSbjh21#endif 12625540ecaSbjh21flag float32_is_nan( float32 a ) 12725540ecaSbjh21{ 12825540ecaSbjh21 12939052f3bSchristos return ( (bits32)0xFF000000 < (bits32) ( a<<1 ) ); 13025540ecaSbjh21 13125540ecaSbjh21} 13225540ecaSbjh21 13325540ecaSbjh21/* 13425540ecaSbjh21------------------------------------------------------------------------------- 13525540ecaSbjh21Returns 1 if the single-precision floating-point value `a' is a signaling 13625540ecaSbjh21NaN; otherwise returns 0. 13725540ecaSbjh21------------------------------------------------------------------------------- 13825540ecaSbjh21*/ 139*547b3a3bSmatt#if defined(SOFTFLOAT_FOR_GCC) \ 140*547b3a3bSmatt && !defined(SOFTFLOATAARCH64_FOR_GCC) \ 141*547b3a3bSmatt && !defined(SOFTFLOATSPARC64_FOR_GCC) \ 142*547b3a3bSmatt && !defined(SOFTFLOATM68K_FOR_GCC) 14325540ecaSbjh21static 14425540ecaSbjh21#endif 14525540ecaSbjh21flag float32_is_signaling_nan( float32 a ) 14625540ecaSbjh21{ 14725540ecaSbjh21 14825540ecaSbjh21 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); 14925540ecaSbjh21 15025540ecaSbjh21} 15125540ecaSbjh21 15225540ecaSbjh21/* 15325540ecaSbjh21------------------------------------------------------------------------------- 15425540ecaSbjh21Returns the result of converting the single-precision floating-point NaN 15525540ecaSbjh21`a' to the canonical NaN format. If `a' is a signaling NaN, the invalid 15625540ecaSbjh21exception is raised. 15725540ecaSbjh21------------------------------------------------------------------------------- 15825540ecaSbjh21*/ 15925540ecaSbjh21static commonNaNT float32ToCommonNaN( float32 a ) 16025540ecaSbjh21{ 16125540ecaSbjh21 commonNaNT z; 16225540ecaSbjh21 16325540ecaSbjh21 if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); 16425540ecaSbjh21 z.sign = a>>31; 16525540ecaSbjh21 z.low = 0; 16625540ecaSbjh21 z.high = ( (bits64) a )<<41; 16725540ecaSbjh21 return z; 16825540ecaSbjh21 16925540ecaSbjh21} 17025540ecaSbjh21 17125540ecaSbjh21/* 17225540ecaSbjh21------------------------------------------------------------------------------- 17325540ecaSbjh21Returns the result of converting the canonical NaN `a' to the single- 17425540ecaSbjh21precision floating-point format. 17525540ecaSbjh21------------------------------------------------------------------------------- 17625540ecaSbjh21*/ 17725540ecaSbjh21static float32 commonNaNToFloat32( commonNaNT a ) 17825540ecaSbjh21{ 17925540ecaSbjh21 18039052f3bSchristos return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | (bits32)( a.high>>41 ); 18125540ecaSbjh21 18225540ecaSbjh21} 18325540ecaSbjh21 18425540ecaSbjh21/* 18525540ecaSbjh21------------------------------------------------------------------------------- 18625540ecaSbjh21Takes two single-precision floating-point values `a' and `b', one of which 18725540ecaSbjh21is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a 18825540ecaSbjh21signaling NaN, the invalid exception is raised. 18925540ecaSbjh21------------------------------------------------------------------------------- 19025540ecaSbjh21*/ 19125540ecaSbjh21static float32 propagateFloat32NaN( float32 a, float32 b ) 19225540ecaSbjh21{ 19325540ecaSbjh21 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 19425540ecaSbjh21 19525540ecaSbjh21 aIsNaN = float32_is_nan( a ); 19625540ecaSbjh21 aIsSignalingNaN = float32_is_signaling_nan( a ); 19725540ecaSbjh21 bIsNaN = float32_is_nan( b ); 19825540ecaSbjh21 bIsSignalingNaN = float32_is_signaling_nan( b ); 19925540ecaSbjh21 a |= 0x00400000; 20025540ecaSbjh21 b |= 0x00400000; 20125540ecaSbjh21 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); 20225540ecaSbjh21 if ( aIsNaN ) { 20325540ecaSbjh21 return ( aIsSignalingNaN & bIsNaN ) ? b : a; 20425540ecaSbjh21 } 20525540ecaSbjh21 else { 20625540ecaSbjh21 return b; 20725540ecaSbjh21 } 20825540ecaSbjh21 20925540ecaSbjh21} 21025540ecaSbjh21 21125540ecaSbjh21/* 21225540ecaSbjh21------------------------------------------------------------------------------- 21325540ecaSbjh21The pattern for a default generated double-precision NaN. 21425540ecaSbjh21------------------------------------------------------------------------------- 21525540ecaSbjh21*/ 21625540ecaSbjh21#define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF ) 21725540ecaSbjh21 21825540ecaSbjh21/* 21925540ecaSbjh21------------------------------------------------------------------------------- 22025540ecaSbjh21Returns 1 if the double-precision floating-point value `a' is a NaN; 22125540ecaSbjh21otherwise returns 0. 22225540ecaSbjh21------------------------------------------------------------------------------- 22325540ecaSbjh21*/ 22425540ecaSbjh21#ifdef SOFTFLOAT_FOR_GCC 22525540ecaSbjh21static 22625540ecaSbjh21#endif 22725540ecaSbjh21flag float64_is_nan( float64 a ) 22825540ecaSbjh21{ 22925540ecaSbjh21 23039052f3bSchristos return ( (bits64)LIT64( 0xFFE0000000000000 ) < 23125540ecaSbjh21 (bits64) ( FLOAT64_DEMANGLE(a)<<1 ) ); 23225540ecaSbjh21 23325540ecaSbjh21} 23425540ecaSbjh21 23525540ecaSbjh21/* 23625540ecaSbjh21------------------------------------------------------------------------------- 23725540ecaSbjh21Returns 1 if the double-precision floating-point value `a' is a signaling 23825540ecaSbjh21NaN; otherwise returns 0. 23925540ecaSbjh21------------------------------------------------------------------------------- 24025540ecaSbjh21*/ 241*547b3a3bSmatt#if defined(SOFTFLOAT_FOR_GCC) \ 242*547b3a3bSmatt && !defined(SOFTFLOATAARCH64_FOR_GCC) \ 243*547b3a3bSmatt && !defined(SOFTFLOATSPARC64_FOR_GCC) \ 244*547b3a3bSmatt && !defined(SOFTFLOATM68K_FOR_GCC) 24525540ecaSbjh21static 24625540ecaSbjh21#endif 24725540ecaSbjh21flag float64_is_signaling_nan( float64 a ) 24825540ecaSbjh21{ 24925540ecaSbjh21 25025540ecaSbjh21 return 25125540ecaSbjh21 ( ( ( FLOAT64_DEMANGLE(a)>>51 ) & 0xFFF ) == 0xFFE ) 25225540ecaSbjh21 && ( FLOAT64_DEMANGLE(a) & LIT64( 0x0007FFFFFFFFFFFF ) ); 25325540ecaSbjh21 25425540ecaSbjh21} 25525540ecaSbjh21 25625540ecaSbjh21/* 25725540ecaSbjh21------------------------------------------------------------------------------- 25825540ecaSbjh21Returns the result of converting the double-precision floating-point NaN 25925540ecaSbjh21`a' to the canonical NaN format. If `a' is a signaling NaN, the invalid 26025540ecaSbjh21exception is raised. 26125540ecaSbjh21------------------------------------------------------------------------------- 26225540ecaSbjh21*/ 26325540ecaSbjh21static commonNaNT float64ToCommonNaN( float64 a ) 26425540ecaSbjh21{ 26525540ecaSbjh21 commonNaNT z; 26625540ecaSbjh21 26725540ecaSbjh21 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); 26839052f3bSchristos z.sign = (flag)(FLOAT64_DEMANGLE(a)>>63); 26925540ecaSbjh21 z.low = 0; 27025540ecaSbjh21 z.high = FLOAT64_DEMANGLE(a)<<12; 27125540ecaSbjh21 return z; 27225540ecaSbjh21 27325540ecaSbjh21} 27425540ecaSbjh21 27525540ecaSbjh21/* 27625540ecaSbjh21------------------------------------------------------------------------------- 27725540ecaSbjh21Returns the result of converting the canonical NaN `a' to the double- 27825540ecaSbjh21precision floating-point format. 27925540ecaSbjh21------------------------------------------------------------------------------- 28025540ecaSbjh21*/ 28125540ecaSbjh21static float64 commonNaNToFloat64( commonNaNT a ) 28225540ecaSbjh21{ 28325540ecaSbjh21 28425540ecaSbjh21 return FLOAT64_MANGLE( 28525540ecaSbjh21 ( ( (bits64) a.sign )<<63 ) 28625540ecaSbjh21 | LIT64( 0x7FF8000000000000 ) 28725540ecaSbjh21 | ( a.high>>12 ) ); 28825540ecaSbjh21 28925540ecaSbjh21} 29025540ecaSbjh21 29125540ecaSbjh21/* 29225540ecaSbjh21------------------------------------------------------------------------------- 29325540ecaSbjh21Takes two double-precision floating-point values `a' and `b', one of which 29425540ecaSbjh21is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a 29525540ecaSbjh21signaling NaN, the invalid exception is raised. 29625540ecaSbjh21------------------------------------------------------------------------------- 29725540ecaSbjh21*/ 29825540ecaSbjh21static float64 propagateFloat64NaN( float64 a, float64 b ) 29925540ecaSbjh21{ 30025540ecaSbjh21 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 30125540ecaSbjh21 30225540ecaSbjh21 aIsNaN = float64_is_nan( a ); 30325540ecaSbjh21 aIsSignalingNaN = float64_is_signaling_nan( a ); 30425540ecaSbjh21 bIsNaN = float64_is_nan( b ); 30525540ecaSbjh21 bIsSignalingNaN = float64_is_signaling_nan( b ); 30625540ecaSbjh21 a |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 )); 30725540ecaSbjh21 b |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 )); 30825540ecaSbjh21 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); 30925540ecaSbjh21 if ( aIsNaN ) { 31025540ecaSbjh21 return ( aIsSignalingNaN & bIsNaN ) ? b : a; 31125540ecaSbjh21 } 31225540ecaSbjh21 else { 31325540ecaSbjh21 return b; 31425540ecaSbjh21 } 31525540ecaSbjh21 31625540ecaSbjh21} 31725540ecaSbjh21 31825540ecaSbjh21#ifdef FLOATX80 31925540ecaSbjh21 32025540ecaSbjh21/* 32125540ecaSbjh21------------------------------------------------------------------------------- 32225540ecaSbjh21The pattern for a default generated extended double-precision NaN. The 32325540ecaSbjh21`high' and `low' values hold the most- and least-significant bits, 32425540ecaSbjh21respectively. 32525540ecaSbjh21------------------------------------------------------------------------------- 32625540ecaSbjh21*/ 32725540ecaSbjh21#define floatx80_default_nan_high 0xFFFF 32825540ecaSbjh21#define floatx80_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF ) 32925540ecaSbjh21 33025540ecaSbjh21/* 33125540ecaSbjh21------------------------------------------------------------------------------- 33225540ecaSbjh21Returns 1 if the extended double-precision floating-point value `a' is a 33325540ecaSbjh21NaN; otherwise returns 0. 33425540ecaSbjh21------------------------------------------------------------------------------- 33525540ecaSbjh21*/ 33625540ecaSbjh21flag floatx80_is_nan( floatx80 a ) 33725540ecaSbjh21{ 33825540ecaSbjh21 33925540ecaSbjh21 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 ); 34025540ecaSbjh21 34125540ecaSbjh21} 34225540ecaSbjh21 34325540ecaSbjh21/* 34425540ecaSbjh21------------------------------------------------------------------------------- 34525540ecaSbjh21Returns 1 if the extended double-precision floating-point value `a' is a 34625540ecaSbjh21signaling NaN; otherwise returns 0. 34725540ecaSbjh21------------------------------------------------------------------------------- 34825540ecaSbjh21*/ 34925540ecaSbjh21flag floatx80_is_signaling_nan( floatx80 a ) 35025540ecaSbjh21{ 35125540ecaSbjh21 bits64 aLow; 35225540ecaSbjh21 35325540ecaSbjh21 aLow = a.low & ~ LIT64( 0x4000000000000000 ); 35425540ecaSbjh21 return 35525540ecaSbjh21 ( ( a.high & 0x7FFF ) == 0x7FFF ) 35625540ecaSbjh21 && (bits64) ( aLow<<1 ) 35725540ecaSbjh21 && ( a.low == aLow ); 35825540ecaSbjh21 35925540ecaSbjh21} 36025540ecaSbjh21 36125540ecaSbjh21/* 36225540ecaSbjh21------------------------------------------------------------------------------- 36325540ecaSbjh21Returns the result of converting the extended double-precision floating- 36425540ecaSbjh21point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the 36525540ecaSbjh21invalid exception is raised. 36625540ecaSbjh21------------------------------------------------------------------------------- 36725540ecaSbjh21*/ 36825540ecaSbjh21static commonNaNT floatx80ToCommonNaN( floatx80 a ) 36925540ecaSbjh21{ 37025540ecaSbjh21 commonNaNT z; 37125540ecaSbjh21 37225540ecaSbjh21 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); 37325540ecaSbjh21 z.sign = a.high>>15; 37425540ecaSbjh21 z.low = 0; 37525540ecaSbjh21 z.high = a.low<<1; 37625540ecaSbjh21 return z; 37725540ecaSbjh21 37825540ecaSbjh21} 37925540ecaSbjh21 38025540ecaSbjh21/* 38125540ecaSbjh21------------------------------------------------------------------------------- 38225540ecaSbjh21Returns the result of converting the canonical NaN `a' to the extended 38325540ecaSbjh21double-precision floating-point format. 38425540ecaSbjh21------------------------------------------------------------------------------- 38525540ecaSbjh21*/ 38625540ecaSbjh21static floatx80 commonNaNToFloatx80( commonNaNT a ) 38725540ecaSbjh21{ 38825540ecaSbjh21 floatx80 z; 38925540ecaSbjh21 39025540ecaSbjh21 z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 ); 39125540ecaSbjh21 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF; 39225540ecaSbjh21 return z; 39325540ecaSbjh21 39425540ecaSbjh21} 39525540ecaSbjh21 39625540ecaSbjh21/* 39725540ecaSbjh21------------------------------------------------------------------------------- 39825540ecaSbjh21Takes two extended double-precision floating-point values `a' and `b', one 39925540ecaSbjh21of which is a NaN, and returns the appropriate NaN result. If either `a' or 40025540ecaSbjh21`b' is a signaling NaN, the invalid exception is raised. 40125540ecaSbjh21------------------------------------------------------------------------------- 40225540ecaSbjh21*/ 40325540ecaSbjh21static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b ) 40425540ecaSbjh21{ 40525540ecaSbjh21 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 40625540ecaSbjh21 40725540ecaSbjh21 aIsNaN = floatx80_is_nan( a ); 40825540ecaSbjh21 aIsSignalingNaN = floatx80_is_signaling_nan( a ); 40925540ecaSbjh21 bIsNaN = floatx80_is_nan( b ); 41025540ecaSbjh21 bIsSignalingNaN = floatx80_is_signaling_nan( b ); 41125540ecaSbjh21 a.low |= LIT64( 0xC000000000000000 ); 41225540ecaSbjh21 b.low |= LIT64( 0xC000000000000000 ); 41325540ecaSbjh21 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); 41425540ecaSbjh21 if ( aIsNaN ) { 41525540ecaSbjh21 return ( aIsSignalingNaN & bIsNaN ) ? b : a; 41625540ecaSbjh21 } 41725540ecaSbjh21 else { 41825540ecaSbjh21 return b; 41925540ecaSbjh21 } 42025540ecaSbjh21 42125540ecaSbjh21} 42225540ecaSbjh21 42325540ecaSbjh21#endif 42425540ecaSbjh21 42525540ecaSbjh21#ifdef FLOAT128 42625540ecaSbjh21 42725540ecaSbjh21/* 42825540ecaSbjh21------------------------------------------------------------------------------- 42925540ecaSbjh21The pattern for a default generated quadruple-precision NaN. The `high' and 43025540ecaSbjh21`low' values hold the most- and least-significant bits, respectively. 43125540ecaSbjh21------------------------------------------------------------------------------- 43225540ecaSbjh21*/ 43325540ecaSbjh21#define float128_default_nan_high LIT64( 0xFFFFFFFFFFFFFFFF ) 43425540ecaSbjh21#define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF ) 43525540ecaSbjh21 43625540ecaSbjh21/* 43725540ecaSbjh21------------------------------------------------------------------------------- 43825540ecaSbjh21Returns 1 if the quadruple-precision floating-point value `a' is a NaN; 43925540ecaSbjh21otherwise returns 0. 44025540ecaSbjh21------------------------------------------------------------------------------- 44125540ecaSbjh21*/ 44225540ecaSbjh21flag float128_is_nan( float128 a ) 44325540ecaSbjh21{ 44425540ecaSbjh21 44525540ecaSbjh21 return 44639052f3bSchristos ( (bits64)LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) ) 44725540ecaSbjh21 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) ); 44825540ecaSbjh21 44925540ecaSbjh21} 45025540ecaSbjh21 45125540ecaSbjh21/* 45225540ecaSbjh21------------------------------------------------------------------------------- 45325540ecaSbjh21Returns 1 if the quadruple-precision floating-point value `a' is a 45425540ecaSbjh21signaling NaN; otherwise returns 0. 45525540ecaSbjh21------------------------------------------------------------------------------- 45625540ecaSbjh21*/ 45725540ecaSbjh21flag float128_is_signaling_nan( float128 a ) 45825540ecaSbjh21{ 45925540ecaSbjh21 46025540ecaSbjh21 return 46125540ecaSbjh21 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE ) 46225540ecaSbjh21 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) ); 46325540ecaSbjh21 46425540ecaSbjh21} 46525540ecaSbjh21 46625540ecaSbjh21/* 46725540ecaSbjh21------------------------------------------------------------------------------- 46825540ecaSbjh21Returns the result of converting the quadruple-precision floating-point NaN 46925540ecaSbjh21`a' to the canonical NaN format. If `a' is a signaling NaN, the invalid 47025540ecaSbjh21exception is raised. 47125540ecaSbjh21------------------------------------------------------------------------------- 47225540ecaSbjh21*/ 47325540ecaSbjh21static commonNaNT float128ToCommonNaN( float128 a ) 47425540ecaSbjh21{ 47525540ecaSbjh21 commonNaNT z; 47625540ecaSbjh21 47725540ecaSbjh21 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); 47839052f3bSchristos z.sign = (flag)(a.high>>63); 47925540ecaSbjh21 shortShift128Left( a.high, a.low, 16, &z.high, &z.low ); 48025540ecaSbjh21 return z; 48125540ecaSbjh21 48225540ecaSbjh21} 48325540ecaSbjh21 48425540ecaSbjh21/* 48525540ecaSbjh21------------------------------------------------------------------------------- 48625540ecaSbjh21Returns the result of converting the canonical NaN `a' to the quadruple- 48725540ecaSbjh21precision floating-point format. 48825540ecaSbjh21------------------------------------------------------------------------------- 48925540ecaSbjh21*/ 49025540ecaSbjh21static float128 commonNaNToFloat128( commonNaNT a ) 49125540ecaSbjh21{ 49225540ecaSbjh21 float128 z; 49325540ecaSbjh21 49425540ecaSbjh21 shift128Right( a.high, a.low, 16, &z.high, &z.low ); 49525540ecaSbjh21 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 ); 49625540ecaSbjh21 return z; 49725540ecaSbjh21 49825540ecaSbjh21} 49925540ecaSbjh21 50025540ecaSbjh21/* 50125540ecaSbjh21------------------------------------------------------------------------------- 50225540ecaSbjh21Takes two quadruple-precision floating-point values `a' and `b', one of 50325540ecaSbjh21which is a NaN, and returns the appropriate NaN result. If either `a' or 50425540ecaSbjh21`b' is a signaling NaN, the invalid exception is raised. 50525540ecaSbjh21------------------------------------------------------------------------------- 50625540ecaSbjh21*/ 50725540ecaSbjh21static float128 propagateFloat128NaN( float128 a, float128 b ) 50825540ecaSbjh21{ 50925540ecaSbjh21 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 51025540ecaSbjh21 51125540ecaSbjh21 aIsNaN = float128_is_nan( a ); 51225540ecaSbjh21 aIsSignalingNaN = float128_is_signaling_nan( a ); 51325540ecaSbjh21 bIsNaN = float128_is_nan( b ); 51425540ecaSbjh21 bIsSignalingNaN = float128_is_signaling_nan( b ); 51525540ecaSbjh21 a.high |= LIT64( 0x0000800000000000 ); 51625540ecaSbjh21 b.high |= LIT64( 0x0000800000000000 ); 51725540ecaSbjh21 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); 51825540ecaSbjh21 if ( aIsNaN ) { 51925540ecaSbjh21 return ( aIsSignalingNaN & bIsNaN ) ? b : a; 52025540ecaSbjh21 } 52125540ecaSbjh21 else { 52225540ecaSbjh21 return b; 52325540ecaSbjh21 } 52425540ecaSbjh21 52525540ecaSbjh21} 52625540ecaSbjh21 52725540ecaSbjh21#endif 52825540ecaSbjh21 529