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