1*2fe8fb19SBen Gras 2*2fe8fb19SBen Gras/* 3*2fe8fb19SBen Gras=============================================================================== 4*2fe8fb19SBen Gras 5*2fe8fb19SBen GrasThis C source fragment is part of the SoftFloat IEC/IEEE Floating-point 6*2fe8fb19SBen GrasArithmetic Package, Release 2a. 7*2fe8fb19SBen Gras 8*2fe8fb19SBen GrasWritten by John R. Hauser. This work was made possible in part by the 9*2fe8fb19SBen GrasInternational Computer Science Institute, located at Suite 600, 1947 Center 10*2fe8fb19SBen GrasStreet, Berkeley, California 94704. Funding was partially provided by the 11*2fe8fb19SBen GrasNational Science Foundation under grant MIP-9311980. The original version 12*2fe8fb19SBen Grasof this code was written as part of a project to build a fixed-point vector 13*2fe8fb19SBen Grasprocessor in collaboration with the University of California at Berkeley, 14*2fe8fb19SBen Grasoverseen by Profs. Nelson Morgan and John Wawrzynek. More information 15*2fe8fb19SBen Grasis available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ 16*2fe8fb19SBen Grasarithmetic/SoftFloat.html'. 17*2fe8fb19SBen Gras 18*2fe8fb19SBen GrasTHIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort 19*2fe8fb19SBen Grashas been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT 20*2fe8fb19SBen GrasTIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO 21*2fe8fb19SBen GrasPERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY 22*2fe8fb19SBen GrasAND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. 23*2fe8fb19SBen Gras 24*2fe8fb19SBen GrasDerivative works are acceptable, even for commercial purposes, so long as 25*2fe8fb19SBen Gras(1) they include prominent notice that the work is derivative, and (2) they 26*2fe8fb19SBen Grasinclude prominent notice akin to these four paragraphs for those parts of 27*2fe8fb19SBen Grasthis code that are retained. 28*2fe8fb19SBen Gras 29*2fe8fb19SBen Gras=============================================================================== 30*2fe8fb19SBen Gras*/ 31*2fe8fb19SBen Gras 32*2fe8fb19SBen Gras/* 33*2fe8fb19SBen Gras------------------------------------------------------------------------------- 34*2fe8fb19SBen GrasUnderflow tininess-detection mode, statically initialized to default value. 35*2fe8fb19SBen Gras(The declaration in `softfloat.h' must match the `int8' type here.) 36*2fe8fb19SBen Gras------------------------------------------------------------------------------- 37*2fe8fb19SBen Gras*/ 38*2fe8fb19SBen Grasint8 float_detect_tininess = float_tininess_after_rounding; 39*2fe8fb19SBen Gras 40*2fe8fb19SBen Gras/* 41*2fe8fb19SBen Gras------------------------------------------------------------------------------- 42*2fe8fb19SBen GrasRaises the exceptions specified by `flags'. Floating-point traps can be 43*2fe8fb19SBen Grasdefined here if desired. It is currently not possible for such a trap to 44*2fe8fb19SBen Grassubstitute a result value. If traps are not implemented, this routine 45*2fe8fb19SBen Grasshould be simply `float_exception_flags |= flags;'. 46*2fe8fb19SBen Gras------------------------------------------------------------------------------- 47*2fe8fb19SBen Gras*/ 48*2fe8fb19SBen Grasvoid float_raise( int8 flags ) 49*2fe8fb19SBen Gras{ 50*2fe8fb19SBen Gras 51*2fe8fb19SBen Gras float_exception_flags |= flags; 52*2fe8fb19SBen Gras 53*2fe8fb19SBen Gras} 54*2fe8fb19SBen Gras 55*2fe8fb19SBen Gras/* 56*2fe8fb19SBen Gras------------------------------------------------------------------------------- 57*2fe8fb19SBen GrasInternal canonical NaN format. 58*2fe8fb19SBen Gras------------------------------------------------------------------------------- 59*2fe8fb19SBen Gras*/ 60*2fe8fb19SBen Grastypedef struct { 61*2fe8fb19SBen Gras flag sign; 62*2fe8fb19SBen Gras bits64 high, low; 63*2fe8fb19SBen Gras} commonNaNT; 64*2fe8fb19SBen Gras 65*2fe8fb19SBen Gras/* 66*2fe8fb19SBen Gras------------------------------------------------------------------------------- 67*2fe8fb19SBen GrasThe pattern for a default generated single-precision NaN. 68*2fe8fb19SBen Gras------------------------------------------------------------------------------- 69*2fe8fb19SBen Gras*/ 70*2fe8fb19SBen Gras#define float32_default_nan 0xFFFFFFFF 71*2fe8fb19SBen Gras 72*2fe8fb19SBen Gras/* 73*2fe8fb19SBen Gras------------------------------------------------------------------------------- 74*2fe8fb19SBen GrasReturns 1 if the single-precision floating-point value `a' is a NaN; 75*2fe8fb19SBen Grasotherwise returns 0. 76*2fe8fb19SBen Gras------------------------------------------------------------------------------- 77*2fe8fb19SBen Gras*/ 78*2fe8fb19SBen Grasflag float32_is_nan( float32 a ) 79*2fe8fb19SBen Gras{ 80*2fe8fb19SBen Gras 81*2fe8fb19SBen Gras return ( 0xFF000000 < (bits32) ( a<<1 ) ); 82*2fe8fb19SBen Gras 83*2fe8fb19SBen Gras} 84*2fe8fb19SBen Gras 85*2fe8fb19SBen Gras/* 86*2fe8fb19SBen Gras------------------------------------------------------------------------------- 87*2fe8fb19SBen GrasReturns 1 if the single-precision floating-point value `a' is a signaling 88*2fe8fb19SBen GrasNaN; otherwise returns 0. 89*2fe8fb19SBen Gras------------------------------------------------------------------------------- 90*2fe8fb19SBen Gras*/ 91*2fe8fb19SBen Grasflag float32_is_signaling_nan( float32 a ) 92*2fe8fb19SBen Gras{ 93*2fe8fb19SBen Gras 94*2fe8fb19SBen Gras return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); 95*2fe8fb19SBen Gras 96*2fe8fb19SBen Gras} 97*2fe8fb19SBen Gras 98*2fe8fb19SBen Gras/* 99*2fe8fb19SBen Gras------------------------------------------------------------------------------- 100*2fe8fb19SBen GrasReturns the result of converting the single-precision floating-point NaN 101*2fe8fb19SBen Gras`a' to the canonical NaN format. If `a' is a signaling NaN, the invalid 102*2fe8fb19SBen Grasexception is raised. 103*2fe8fb19SBen Gras------------------------------------------------------------------------------- 104*2fe8fb19SBen Gras*/ 105*2fe8fb19SBen Grasstatic commonNaNT float32ToCommonNaN( float32 a ) 106*2fe8fb19SBen Gras{ 107*2fe8fb19SBen Gras commonNaNT z; 108*2fe8fb19SBen Gras 109*2fe8fb19SBen Gras if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); 110*2fe8fb19SBen Gras z.sign = a>>31; 111*2fe8fb19SBen Gras z.low = 0; 112*2fe8fb19SBen Gras z.high = ( (bits64) a )<<41; 113*2fe8fb19SBen Gras return z; 114*2fe8fb19SBen Gras 115*2fe8fb19SBen Gras} 116*2fe8fb19SBen Gras 117*2fe8fb19SBen Gras/* 118*2fe8fb19SBen Gras------------------------------------------------------------------------------- 119*2fe8fb19SBen GrasReturns the result of converting the canonical NaN `a' to the single- 120*2fe8fb19SBen Grasprecision floating-point format. 121*2fe8fb19SBen Gras------------------------------------------------------------------------------- 122*2fe8fb19SBen Gras*/ 123*2fe8fb19SBen Grasstatic float32 commonNaNToFloat32( commonNaNT a ) 124*2fe8fb19SBen Gras{ 125*2fe8fb19SBen Gras 126*2fe8fb19SBen Gras return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 ); 127*2fe8fb19SBen Gras 128*2fe8fb19SBen Gras} 129*2fe8fb19SBen Gras 130*2fe8fb19SBen Gras/* 131*2fe8fb19SBen Gras------------------------------------------------------------------------------- 132*2fe8fb19SBen GrasTakes two single-precision floating-point values `a' and `b', one of which 133*2fe8fb19SBen Grasis a NaN, and returns the appropriate NaN result. If either `a' or `b' is a 134*2fe8fb19SBen Grassignaling NaN, the invalid exception is raised. 135*2fe8fb19SBen Gras------------------------------------------------------------------------------- 136*2fe8fb19SBen Gras*/ 137*2fe8fb19SBen Grasstatic float32 propagateFloat32NaN( float32 a, float32 b ) 138*2fe8fb19SBen Gras{ 139*2fe8fb19SBen Gras flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 140*2fe8fb19SBen Gras 141*2fe8fb19SBen Gras aIsNaN = float32_is_nan( a ); 142*2fe8fb19SBen Gras aIsSignalingNaN = float32_is_signaling_nan( a ); 143*2fe8fb19SBen Gras bIsNaN = float32_is_nan( b ); 144*2fe8fb19SBen Gras bIsSignalingNaN = float32_is_signaling_nan( b ); 145*2fe8fb19SBen Gras a |= 0x00400000; 146*2fe8fb19SBen Gras b |= 0x00400000; 147*2fe8fb19SBen Gras if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); 148*2fe8fb19SBen Gras if ( aIsNaN ) { 149*2fe8fb19SBen Gras return ( aIsSignalingNaN & bIsNaN ) ? b : a; 150*2fe8fb19SBen Gras } 151*2fe8fb19SBen Gras else { 152*2fe8fb19SBen Gras return b; 153*2fe8fb19SBen Gras } 154*2fe8fb19SBen Gras 155*2fe8fb19SBen Gras} 156*2fe8fb19SBen Gras 157*2fe8fb19SBen Gras/* 158*2fe8fb19SBen Gras------------------------------------------------------------------------------- 159*2fe8fb19SBen GrasThe pattern for a default generated double-precision NaN. 160*2fe8fb19SBen Gras------------------------------------------------------------------------------- 161*2fe8fb19SBen Gras*/ 162*2fe8fb19SBen Gras#define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF ) 163*2fe8fb19SBen Gras 164*2fe8fb19SBen Gras/* 165*2fe8fb19SBen Gras------------------------------------------------------------------------------- 166*2fe8fb19SBen GrasReturns 1 if the double-precision floating-point value `a' is a NaN; 167*2fe8fb19SBen Grasotherwise returns 0. 168*2fe8fb19SBen Gras------------------------------------------------------------------------------- 169*2fe8fb19SBen Gras*/ 170*2fe8fb19SBen Grasflag float64_is_nan( float64 a ) 171*2fe8fb19SBen Gras{ 172*2fe8fb19SBen Gras 173*2fe8fb19SBen Gras return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) ); 174*2fe8fb19SBen Gras 175*2fe8fb19SBen Gras} 176*2fe8fb19SBen Gras 177*2fe8fb19SBen Gras/* 178*2fe8fb19SBen Gras------------------------------------------------------------------------------- 179*2fe8fb19SBen GrasReturns 1 if the double-precision floating-point value `a' is a signaling 180*2fe8fb19SBen GrasNaN; otherwise returns 0. 181*2fe8fb19SBen Gras------------------------------------------------------------------------------- 182*2fe8fb19SBen Gras*/ 183*2fe8fb19SBen Grasflag float64_is_signaling_nan( float64 a ) 184*2fe8fb19SBen Gras{ 185*2fe8fb19SBen Gras 186*2fe8fb19SBen Gras return 187*2fe8fb19SBen Gras ( ( ( a>>51 ) & 0xFFF ) == 0xFFE ) 188*2fe8fb19SBen Gras && ( a & LIT64( 0x0007FFFFFFFFFFFF ) ); 189*2fe8fb19SBen Gras 190*2fe8fb19SBen Gras} 191*2fe8fb19SBen Gras 192*2fe8fb19SBen Gras/* 193*2fe8fb19SBen Gras------------------------------------------------------------------------------- 194*2fe8fb19SBen GrasReturns the result of converting the double-precision floating-point NaN 195*2fe8fb19SBen Gras`a' to the canonical NaN format. If `a' is a signaling NaN, the invalid 196*2fe8fb19SBen Grasexception is raised. 197*2fe8fb19SBen Gras------------------------------------------------------------------------------- 198*2fe8fb19SBen Gras*/ 199*2fe8fb19SBen Grasstatic commonNaNT float64ToCommonNaN( float64 a ) 200*2fe8fb19SBen Gras{ 201*2fe8fb19SBen Gras commonNaNT z; 202*2fe8fb19SBen Gras 203*2fe8fb19SBen Gras if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); 204*2fe8fb19SBen Gras z.sign = a>>63; 205*2fe8fb19SBen Gras z.low = 0; 206*2fe8fb19SBen Gras z.high = a<<12; 207*2fe8fb19SBen Gras return z; 208*2fe8fb19SBen Gras 209*2fe8fb19SBen Gras} 210*2fe8fb19SBen Gras 211*2fe8fb19SBen Gras/* 212*2fe8fb19SBen Gras------------------------------------------------------------------------------- 213*2fe8fb19SBen GrasReturns the result of converting the canonical NaN `a' to the double- 214*2fe8fb19SBen Grasprecision floating-point format. 215*2fe8fb19SBen Gras------------------------------------------------------------------------------- 216*2fe8fb19SBen Gras*/ 217*2fe8fb19SBen Grasstatic float64 commonNaNToFloat64( commonNaNT a ) 218*2fe8fb19SBen Gras{ 219*2fe8fb19SBen Gras 220*2fe8fb19SBen Gras return 221*2fe8fb19SBen Gras ( ( (bits64) a.sign )<<63 ) 222*2fe8fb19SBen Gras | LIT64( 0x7FF8000000000000 ) 223*2fe8fb19SBen Gras | ( a.high>>12 ); 224*2fe8fb19SBen Gras 225*2fe8fb19SBen Gras} 226*2fe8fb19SBen Gras 227*2fe8fb19SBen Gras/* 228*2fe8fb19SBen Gras------------------------------------------------------------------------------- 229*2fe8fb19SBen GrasTakes two double-precision floating-point values `a' and `b', one of which 230*2fe8fb19SBen Grasis a NaN, and returns the appropriate NaN result. If either `a' or `b' is a 231*2fe8fb19SBen Grassignaling NaN, the invalid exception is raised. 232*2fe8fb19SBen Gras------------------------------------------------------------------------------- 233*2fe8fb19SBen Gras*/ 234*2fe8fb19SBen Grasstatic float64 propagateFloat64NaN( float64 a, float64 b ) 235*2fe8fb19SBen Gras{ 236*2fe8fb19SBen Gras flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 237*2fe8fb19SBen Gras 238*2fe8fb19SBen Gras aIsNaN = float64_is_nan( a ); 239*2fe8fb19SBen Gras aIsSignalingNaN = float64_is_signaling_nan( a ); 240*2fe8fb19SBen Gras bIsNaN = float64_is_nan( b ); 241*2fe8fb19SBen Gras bIsSignalingNaN = float64_is_signaling_nan( b ); 242*2fe8fb19SBen Gras a |= LIT64( 0x0008000000000000 ); 243*2fe8fb19SBen Gras b |= LIT64( 0x0008000000000000 ); 244*2fe8fb19SBen Gras if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); 245*2fe8fb19SBen Gras if ( aIsNaN ) { 246*2fe8fb19SBen Gras return ( aIsSignalingNaN & bIsNaN ) ? b : a; 247*2fe8fb19SBen Gras } 248*2fe8fb19SBen Gras else { 249*2fe8fb19SBen Gras return b; 250*2fe8fb19SBen Gras } 251*2fe8fb19SBen Gras 252*2fe8fb19SBen Gras} 253*2fe8fb19SBen Gras 254*2fe8fb19SBen Gras#ifdef FLOATX80 255*2fe8fb19SBen Gras 256*2fe8fb19SBen Gras/* 257*2fe8fb19SBen Gras------------------------------------------------------------------------------- 258*2fe8fb19SBen GrasThe pattern for a default generated extended double-precision NaN. The 259*2fe8fb19SBen Gras`high' and `low' values hold the most- and least-significant bits, 260*2fe8fb19SBen Grasrespectively. 261*2fe8fb19SBen Gras------------------------------------------------------------------------------- 262*2fe8fb19SBen Gras*/ 263*2fe8fb19SBen Gras#define floatx80_default_nan_high 0xFFFF 264*2fe8fb19SBen Gras#define floatx80_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF ) 265*2fe8fb19SBen Gras 266*2fe8fb19SBen Gras/* 267*2fe8fb19SBen Gras------------------------------------------------------------------------------- 268*2fe8fb19SBen GrasReturns 1 if the extended double-precision floating-point value `a' is a 269*2fe8fb19SBen GrasNaN; otherwise returns 0. 270*2fe8fb19SBen Gras------------------------------------------------------------------------------- 271*2fe8fb19SBen Gras*/ 272*2fe8fb19SBen Grasflag floatx80_is_nan( floatx80 a ) 273*2fe8fb19SBen Gras{ 274*2fe8fb19SBen Gras 275*2fe8fb19SBen Gras return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 ); 276*2fe8fb19SBen Gras 277*2fe8fb19SBen Gras} 278*2fe8fb19SBen Gras 279*2fe8fb19SBen Gras/* 280*2fe8fb19SBen Gras------------------------------------------------------------------------------- 281*2fe8fb19SBen GrasReturns 1 if the extended double-precision floating-point value `a' is a 282*2fe8fb19SBen Grassignaling NaN; otherwise returns 0. 283*2fe8fb19SBen Gras------------------------------------------------------------------------------- 284*2fe8fb19SBen Gras*/ 285*2fe8fb19SBen Grasflag floatx80_is_signaling_nan( floatx80 a ) 286*2fe8fb19SBen Gras{ 287*2fe8fb19SBen Gras bits64 aLow; 288*2fe8fb19SBen Gras 289*2fe8fb19SBen Gras aLow = a.low & ~ LIT64( 0x4000000000000000 ); 290*2fe8fb19SBen Gras return 291*2fe8fb19SBen Gras ( ( a.high & 0x7FFF ) == 0x7FFF ) 292*2fe8fb19SBen Gras && (bits64) ( aLow<<1 ) 293*2fe8fb19SBen Gras && ( a.low == aLow ); 294*2fe8fb19SBen Gras 295*2fe8fb19SBen Gras} 296*2fe8fb19SBen Gras 297*2fe8fb19SBen Gras/* 298*2fe8fb19SBen Gras------------------------------------------------------------------------------- 299*2fe8fb19SBen GrasReturns the result of converting the extended double-precision floating- 300*2fe8fb19SBen Graspoint NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the 301*2fe8fb19SBen Grasinvalid exception is raised. 302*2fe8fb19SBen Gras------------------------------------------------------------------------------- 303*2fe8fb19SBen Gras*/ 304*2fe8fb19SBen Grasstatic commonNaNT floatx80ToCommonNaN( floatx80 a ) 305*2fe8fb19SBen Gras{ 306*2fe8fb19SBen Gras commonNaNT z; 307*2fe8fb19SBen Gras 308*2fe8fb19SBen Gras if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); 309*2fe8fb19SBen Gras z.sign = a.high>>15; 310*2fe8fb19SBen Gras z.low = 0; 311*2fe8fb19SBen Gras z.high = a.low<<1; 312*2fe8fb19SBen Gras return z; 313*2fe8fb19SBen Gras 314*2fe8fb19SBen Gras} 315*2fe8fb19SBen Gras 316*2fe8fb19SBen Gras/* 317*2fe8fb19SBen Gras------------------------------------------------------------------------------- 318*2fe8fb19SBen GrasReturns the result of converting the canonical NaN `a' to the extended 319*2fe8fb19SBen Grasdouble-precision floating-point format. 320*2fe8fb19SBen Gras------------------------------------------------------------------------------- 321*2fe8fb19SBen Gras*/ 322*2fe8fb19SBen Grasstatic floatx80 commonNaNToFloatx80( commonNaNT a ) 323*2fe8fb19SBen Gras{ 324*2fe8fb19SBen Gras floatx80 z; 325*2fe8fb19SBen Gras 326*2fe8fb19SBen Gras z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 ); 327*2fe8fb19SBen Gras z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF; 328*2fe8fb19SBen Gras return z; 329*2fe8fb19SBen Gras 330*2fe8fb19SBen Gras} 331*2fe8fb19SBen Gras 332*2fe8fb19SBen Gras/* 333*2fe8fb19SBen Gras------------------------------------------------------------------------------- 334*2fe8fb19SBen GrasTakes two extended double-precision floating-point values `a' and `b', one 335*2fe8fb19SBen Grasof which is a NaN, and returns the appropriate NaN result. If either `a' or 336*2fe8fb19SBen Gras`b' is a signaling NaN, the invalid exception is raised. 337*2fe8fb19SBen Gras------------------------------------------------------------------------------- 338*2fe8fb19SBen Gras*/ 339*2fe8fb19SBen Grasstatic floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b ) 340*2fe8fb19SBen Gras{ 341*2fe8fb19SBen Gras flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 342*2fe8fb19SBen Gras 343*2fe8fb19SBen Gras aIsNaN = floatx80_is_nan( a ); 344*2fe8fb19SBen Gras aIsSignalingNaN = floatx80_is_signaling_nan( a ); 345*2fe8fb19SBen Gras bIsNaN = floatx80_is_nan( b ); 346*2fe8fb19SBen Gras bIsSignalingNaN = floatx80_is_signaling_nan( b ); 347*2fe8fb19SBen Gras a.low |= LIT64( 0xC000000000000000 ); 348*2fe8fb19SBen Gras b.low |= LIT64( 0xC000000000000000 ); 349*2fe8fb19SBen Gras if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); 350*2fe8fb19SBen Gras if ( aIsNaN ) { 351*2fe8fb19SBen Gras return ( aIsSignalingNaN & bIsNaN ) ? b : a; 352*2fe8fb19SBen Gras } 353*2fe8fb19SBen Gras else { 354*2fe8fb19SBen Gras return b; 355*2fe8fb19SBen Gras } 356*2fe8fb19SBen Gras 357*2fe8fb19SBen Gras} 358*2fe8fb19SBen Gras 359*2fe8fb19SBen Gras#endif 360*2fe8fb19SBen Gras 361*2fe8fb19SBen Gras#ifdef FLOAT128 362*2fe8fb19SBen Gras 363*2fe8fb19SBen Gras/* 364*2fe8fb19SBen Gras------------------------------------------------------------------------------- 365*2fe8fb19SBen GrasThe pattern for a default generated quadruple-precision NaN. The `high' and 366*2fe8fb19SBen Gras`low' values hold the most- and least-significant bits, respectively. 367*2fe8fb19SBen Gras------------------------------------------------------------------------------- 368*2fe8fb19SBen Gras*/ 369*2fe8fb19SBen Gras#define float128_default_nan_high LIT64( 0xFFFFFFFFFFFFFFFF ) 370*2fe8fb19SBen Gras#define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF ) 371*2fe8fb19SBen Gras 372*2fe8fb19SBen Gras/* 373*2fe8fb19SBen Gras------------------------------------------------------------------------------- 374*2fe8fb19SBen GrasReturns 1 if the quadruple-precision floating-point value `a' is a NaN; 375*2fe8fb19SBen Grasotherwise returns 0. 376*2fe8fb19SBen Gras------------------------------------------------------------------------------- 377*2fe8fb19SBen Gras*/ 378*2fe8fb19SBen Grasflag float128_is_nan( float128 a ) 379*2fe8fb19SBen Gras{ 380*2fe8fb19SBen Gras 381*2fe8fb19SBen Gras return 382*2fe8fb19SBen Gras ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) ) 383*2fe8fb19SBen Gras && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) ); 384*2fe8fb19SBen Gras 385*2fe8fb19SBen Gras} 386*2fe8fb19SBen Gras 387*2fe8fb19SBen Gras/* 388*2fe8fb19SBen Gras------------------------------------------------------------------------------- 389*2fe8fb19SBen GrasReturns 1 if the quadruple-precision floating-point value `a' is a 390*2fe8fb19SBen Grassignaling NaN; otherwise returns 0. 391*2fe8fb19SBen Gras------------------------------------------------------------------------------- 392*2fe8fb19SBen Gras*/ 393*2fe8fb19SBen Grasflag float128_is_signaling_nan( float128 a ) 394*2fe8fb19SBen Gras{ 395*2fe8fb19SBen Gras 396*2fe8fb19SBen Gras return 397*2fe8fb19SBen Gras ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE ) 398*2fe8fb19SBen Gras && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) ); 399*2fe8fb19SBen Gras 400*2fe8fb19SBen Gras} 401*2fe8fb19SBen Gras 402*2fe8fb19SBen Gras/* 403*2fe8fb19SBen Gras------------------------------------------------------------------------------- 404*2fe8fb19SBen GrasReturns the result of converting the quadruple-precision floating-point NaN 405*2fe8fb19SBen Gras`a' to the canonical NaN format. If `a' is a signaling NaN, the invalid 406*2fe8fb19SBen Grasexception is raised. 407*2fe8fb19SBen Gras------------------------------------------------------------------------------- 408*2fe8fb19SBen Gras*/ 409*2fe8fb19SBen Grasstatic commonNaNT float128ToCommonNaN( float128 a ) 410*2fe8fb19SBen Gras{ 411*2fe8fb19SBen Gras commonNaNT z; 412*2fe8fb19SBen Gras 413*2fe8fb19SBen Gras if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); 414*2fe8fb19SBen Gras z.sign = a.high>>63; 415*2fe8fb19SBen Gras shortShift128Left( a.high, a.low, 16, &z.high, &z.low ); 416*2fe8fb19SBen Gras return z; 417*2fe8fb19SBen Gras 418*2fe8fb19SBen Gras} 419*2fe8fb19SBen Gras 420*2fe8fb19SBen Gras/* 421*2fe8fb19SBen Gras------------------------------------------------------------------------------- 422*2fe8fb19SBen GrasReturns the result of converting the canonical NaN `a' to the quadruple- 423*2fe8fb19SBen Grasprecision floating-point format. 424*2fe8fb19SBen Gras------------------------------------------------------------------------------- 425*2fe8fb19SBen Gras*/ 426*2fe8fb19SBen Grasstatic float128 commonNaNToFloat128( commonNaNT a ) 427*2fe8fb19SBen Gras{ 428*2fe8fb19SBen Gras float128 z; 429*2fe8fb19SBen Gras 430*2fe8fb19SBen Gras shift128Right( a.high, a.low, 16, &z.high, &z.low ); 431*2fe8fb19SBen Gras z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 ); 432*2fe8fb19SBen Gras return z; 433*2fe8fb19SBen Gras 434*2fe8fb19SBen Gras} 435*2fe8fb19SBen Gras 436*2fe8fb19SBen Gras/* 437*2fe8fb19SBen Gras------------------------------------------------------------------------------- 438*2fe8fb19SBen GrasTakes two quadruple-precision floating-point values `a' and `b', one of 439*2fe8fb19SBen Graswhich is a NaN, and returns the appropriate NaN result. If either `a' or 440*2fe8fb19SBen Gras`b' is a signaling NaN, the invalid exception is raised. 441*2fe8fb19SBen Gras------------------------------------------------------------------------------- 442*2fe8fb19SBen Gras*/ 443*2fe8fb19SBen Grasstatic float128 propagateFloat128NaN( float128 a, float128 b ) 444*2fe8fb19SBen Gras{ 445*2fe8fb19SBen Gras flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 446*2fe8fb19SBen Gras 447*2fe8fb19SBen Gras aIsNaN = float128_is_nan( a ); 448*2fe8fb19SBen Gras aIsSignalingNaN = float128_is_signaling_nan( a ); 449*2fe8fb19SBen Gras bIsNaN = float128_is_nan( b ); 450*2fe8fb19SBen Gras bIsSignalingNaN = float128_is_signaling_nan( b ); 451*2fe8fb19SBen Gras a.high |= LIT64( 0x0000800000000000 ); 452*2fe8fb19SBen Gras b.high |= LIT64( 0x0000800000000000 ); 453*2fe8fb19SBen Gras if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); 454*2fe8fb19SBen Gras if ( aIsNaN ) { 455*2fe8fb19SBen Gras return ( aIsSignalingNaN & bIsNaN ) ? b : a; 456*2fe8fb19SBen Gras } 457*2fe8fb19SBen Gras else { 458*2fe8fb19SBen Gras return b; 459*2fe8fb19SBen Gras } 460*2fe8fb19SBen Gras 461*2fe8fb19SBen Gras} 462*2fe8fb19SBen Gras 463*2fe8fb19SBen Gras#endif 464*2fe8fb19SBen Gras 465