1 /* 2 * QEMU float support 3 * 4 * Derived from SoftFloat. 5 */ 6 7 /*============================================================================ 8 9 This C source fragment is part of the SoftFloat IEC/IEEE Floating-point 10 Arithmetic Package, Release 2b. 11 12 Written by John R. Hauser. This work was made possible in part by the 13 International Computer Science Institute, located at Suite 600, 1947 Center 14 Street, Berkeley, California 94704. Funding was partially provided by the 15 National Science Foundation under grant MIP-9311980. The original version 16 of this code was written as part of a project to build a fixed-point vector 17 processor in collaboration with the University of California at Berkeley, 18 overseen by Profs. Nelson Morgan and John Wawrzynek. More information 19 is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ 20 arithmetic/SoftFloat.html'. 21 22 THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has 23 been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES 24 RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS 25 AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, 26 COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE 27 EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE 28 INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR 29 OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. 30 31 Derivative works are acceptable, even for commercial purposes, so long as 32 (1) the source code for the derivative work includes prominent notice that 33 the work is derivative, and (2) the source code includes prominent notice with 34 these four paragraphs for those parts of this code that are retained. 35 36 =============================================================================*/ 37 38 /*---------------------------------------------------------------------------- 39 | Raises the exceptions specified by `flags'. Floating-point traps can be 40 | defined here if desired. It is currently not possible for such a trap 41 | to substitute a result value. If traps are not implemented, this routine 42 | should be simply `float_exception_flags |= flags;'. 43 *----------------------------------------------------------------------------*/ 44 45 void float_raise( int8 flags STATUS_PARAM ) 46 { 47 STATUS(float_exception_flags) |= flags; 48 } 49 50 /*---------------------------------------------------------------------------- 51 | Internal canonical NaN format. 52 *----------------------------------------------------------------------------*/ 53 typedef struct { 54 flag sign; 55 uint64_t high, low; 56 } commonNaNT; 57 58 /*---------------------------------------------------------------------------- 59 | Returns 1 if the half-precision floating-point value `a' is a quiet 60 | NaN; otherwise returns 0. 61 *----------------------------------------------------------------------------*/ 62 63 int float16_is_quiet_nan(float16 a_) 64 { 65 uint16_t a = float16_val(a_); 66 #if SNAN_BIT_IS_ONE 67 return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF); 68 #else 69 return ((a & ~0x8000) >= 0x7c80); 70 #endif 71 } 72 73 /*---------------------------------------------------------------------------- 74 | Returns 1 if the half-precision floating-point value `a' is a signaling 75 | NaN; otherwise returns 0. 76 *----------------------------------------------------------------------------*/ 77 78 int float16_is_signaling_nan(float16 a_) 79 { 80 uint16_t a = float16_val(a_); 81 #if SNAN_BIT_IS_ONE 82 return ((a & ~0x8000) >= 0x7c80); 83 #else 84 return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF); 85 #endif 86 } 87 88 /*---------------------------------------------------------------------------- 89 | Returns a quiet NaN if the half-precision floating point value `a' is a 90 | signaling NaN; otherwise returns `a'. 91 *----------------------------------------------------------------------------*/ 92 float16 float16_maybe_silence_nan(float16 a_) 93 { 94 if (float16_is_signaling_nan(a_)) { 95 #if SNAN_BIT_IS_ONE 96 # if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32) 97 return float16_default_nan; 98 # else 99 # error Rules for silencing a signaling NaN are target-specific 100 # endif 101 #else 102 uint16_t a = float16_val(a_); 103 a |= (1 << 9); 104 return make_float16(a); 105 #endif 106 } 107 return a_; 108 } 109 110 /*---------------------------------------------------------------------------- 111 | Returns the result of converting the half-precision floating-point NaN 112 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid 113 | exception is raised. 114 *----------------------------------------------------------------------------*/ 115 116 static commonNaNT float16ToCommonNaN( float16 a STATUS_PARAM ) 117 { 118 commonNaNT z; 119 120 if ( float16_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR ); 121 z.sign = float16_val(a) >> 15; 122 z.low = 0; 123 z.high = ((uint64_t) float16_val(a))<<54; 124 return z; 125 } 126 127 /*---------------------------------------------------------------------------- 128 | Returns the result of converting the canonical NaN `a' to the half- 129 | precision floating-point format. 130 *----------------------------------------------------------------------------*/ 131 132 static float16 commonNaNToFloat16(commonNaNT a STATUS_PARAM) 133 { 134 uint16_t mantissa = a.high>>54; 135 136 if (STATUS(default_nan_mode)) { 137 return float16_default_nan; 138 } 139 140 if (mantissa) { 141 return make_float16(((((uint16_t) a.sign) << 15) 142 | (0x1F << 10) | mantissa)); 143 } else { 144 return float16_default_nan; 145 } 146 } 147 148 /*---------------------------------------------------------------------------- 149 | Returns 1 if the single-precision floating-point value `a' is a quiet 150 | NaN; otherwise returns 0. 151 *----------------------------------------------------------------------------*/ 152 153 int float32_is_quiet_nan( float32 a_ ) 154 { 155 uint32_t a = float32_val(a_); 156 #if SNAN_BIT_IS_ONE 157 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); 158 #else 159 return ( 0xFF800000 <= (uint32_t) ( a<<1 ) ); 160 #endif 161 } 162 163 /*---------------------------------------------------------------------------- 164 | Returns 1 if the single-precision floating-point value `a' is a signaling 165 | NaN; otherwise returns 0. 166 *----------------------------------------------------------------------------*/ 167 168 int float32_is_signaling_nan( float32 a_ ) 169 { 170 uint32_t a = float32_val(a_); 171 #if SNAN_BIT_IS_ONE 172 return ( 0xFF800000 <= (uint32_t) ( a<<1 ) ); 173 #else 174 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); 175 #endif 176 } 177 178 /*---------------------------------------------------------------------------- 179 | Returns a quiet NaN if the single-precision floating point value `a' is a 180 | signaling NaN; otherwise returns `a'. 181 *----------------------------------------------------------------------------*/ 182 183 float32 float32_maybe_silence_nan( float32 a_ ) 184 { 185 if (float32_is_signaling_nan(a_)) { 186 #if SNAN_BIT_IS_ONE 187 # if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32) 188 return float32_default_nan; 189 # else 190 # error Rules for silencing a signaling NaN are target-specific 191 # endif 192 #else 193 uint32_t a = float32_val(a_); 194 a |= (1 << 22); 195 return make_float32(a); 196 #endif 197 } 198 return a_; 199 } 200 201 /*---------------------------------------------------------------------------- 202 | Returns the result of converting the single-precision floating-point NaN 203 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid 204 | exception is raised. 205 *----------------------------------------------------------------------------*/ 206 207 static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM ) 208 { 209 commonNaNT z; 210 211 if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR ); 212 z.sign = float32_val(a)>>31; 213 z.low = 0; 214 z.high = ( (uint64_t) float32_val(a) )<<41; 215 return z; 216 } 217 218 /*---------------------------------------------------------------------------- 219 | Returns the result of converting the canonical NaN `a' to the single- 220 | precision floating-point format. 221 *----------------------------------------------------------------------------*/ 222 223 static float32 commonNaNToFloat32( commonNaNT a STATUS_PARAM) 224 { 225 uint32_t mantissa = a.high>>41; 226 227 if ( STATUS(default_nan_mode) ) { 228 return float32_default_nan; 229 } 230 231 if ( mantissa ) 232 return make_float32( 233 ( ( (uint32_t) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) ); 234 else 235 return float32_default_nan; 236 } 237 238 /*---------------------------------------------------------------------------- 239 | Select which NaN to propagate for a two-input operation. 240 | IEEE754 doesn't specify all the details of this, so the 241 | algorithm is target-specific. 242 | The routine is passed various bits of information about the 243 | two NaNs and should return 0 to select NaN a and 1 for NaN b. 244 | Note that signalling NaNs are always squashed to quiet NaNs 245 | by the caller, by calling floatXX_maybe_silence_nan() before 246 | returning them. 247 | 248 | aIsLargerSignificand is only valid if both a and b are NaNs 249 | of some kind, and is true if a has the larger significand, 250 | or if both a and b have the same significand but a is 251 | positive but b is negative. It is only needed for the x87 252 | tie-break rule. 253 *----------------------------------------------------------------------------*/ 254 255 #if defined(TARGET_ARM) 256 static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN, 257 flag aIsLargerSignificand) 258 { 259 /* ARM mandated NaN propagation rules: take the first of: 260 * 1. A if it is signaling 261 * 2. B if it is signaling 262 * 3. A (quiet) 263 * 4. B (quiet) 264 * A signaling NaN is always quietened before returning it. 265 */ 266 if (aIsSNaN) { 267 return 0; 268 } else if (bIsSNaN) { 269 return 1; 270 } else if (aIsQNaN) { 271 return 0; 272 } else { 273 return 1; 274 } 275 } 276 #elif defined(TARGET_MIPS) 277 static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN, 278 flag aIsLargerSignificand) 279 { 280 /* According to MIPS specifications, if one of the two operands is 281 * a sNaN, a new qNaN has to be generated. This is done in 282 * floatXX_maybe_silence_nan(). For qNaN inputs the specifications 283 * says: "When possible, this QNaN result is one of the operand QNaN 284 * values." In practice it seems that most implementations choose 285 * the first operand if both operands are qNaN. In short this gives 286 * the following rules: 287 * 1. A if it is signaling 288 * 2. B if it is signaling 289 * 3. A (quiet) 290 * 4. B (quiet) 291 * A signaling NaN is always silenced before returning it. 292 */ 293 if (aIsSNaN) { 294 return 0; 295 } else if (bIsSNaN) { 296 return 1; 297 } else if (aIsQNaN) { 298 return 0; 299 } else { 300 return 1; 301 } 302 } 303 #elif defined(TARGET_PPC) 304 static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN, 305 flag aIsLargerSignificand) 306 { 307 /* PowerPC propagation rules: 308 * 1. A if it sNaN or qNaN 309 * 2. B if it sNaN or qNaN 310 * A signaling NaN is always silenced before returning it. 311 */ 312 if (aIsSNaN || aIsQNaN) { 313 return 0; 314 } else { 315 return 1; 316 } 317 } 318 #else 319 static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN, 320 flag aIsLargerSignificand) 321 { 322 /* This implements x87 NaN propagation rules: 323 * SNaN + QNaN => return the QNaN 324 * two SNaNs => return the one with the larger significand, silenced 325 * two QNaNs => return the one with the larger significand 326 * SNaN and a non-NaN => return the SNaN, silenced 327 * QNaN and a non-NaN => return the QNaN 328 * 329 * If we get down to comparing significands and they are the same, 330 * return the NaN with the positive sign bit (if any). 331 */ 332 if (aIsSNaN) { 333 if (bIsSNaN) { 334 return aIsLargerSignificand ? 0 : 1; 335 } 336 return bIsQNaN ? 1 : 0; 337 } 338 else if (aIsQNaN) { 339 if (bIsSNaN || !bIsQNaN) 340 return 0; 341 else { 342 return aIsLargerSignificand ? 0 : 1; 343 } 344 } else { 345 return 1; 346 } 347 } 348 #endif 349 350 /*---------------------------------------------------------------------------- 351 | Takes two single-precision floating-point values `a' and `b', one of which 352 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a 353 | signaling NaN, the invalid exception is raised. 354 *----------------------------------------------------------------------------*/ 355 356 static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM) 357 { 358 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN; 359 flag aIsLargerSignificand; 360 uint32_t av, bv; 361 362 aIsQuietNaN = float32_is_quiet_nan( a ); 363 aIsSignalingNaN = float32_is_signaling_nan( a ); 364 bIsQuietNaN = float32_is_quiet_nan( b ); 365 bIsSignalingNaN = float32_is_signaling_nan( b ); 366 av = float32_val(a); 367 bv = float32_val(b); 368 369 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR); 370 371 if ( STATUS(default_nan_mode) ) 372 return float32_default_nan; 373 374 if ((uint32_t)(av<<1) < (uint32_t)(bv<<1)) { 375 aIsLargerSignificand = 0; 376 } else if ((uint32_t)(bv<<1) < (uint32_t)(av<<1)) { 377 aIsLargerSignificand = 1; 378 } else { 379 aIsLargerSignificand = (av < bv) ? 1 : 0; 380 } 381 382 if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN, 383 aIsLargerSignificand)) { 384 return float32_maybe_silence_nan(b); 385 } else { 386 return float32_maybe_silence_nan(a); 387 } 388 } 389 390 /*---------------------------------------------------------------------------- 391 | Returns 1 if the double-precision floating-point value `a' is a quiet 392 | NaN; otherwise returns 0. 393 *----------------------------------------------------------------------------*/ 394 395 int float64_is_quiet_nan( float64 a_ ) 396 { 397 uint64_t a = float64_val(a_); 398 #if SNAN_BIT_IS_ONE 399 return 400 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE ) 401 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) ); 402 #else 403 return ( LIT64( 0xFFF0000000000000 ) <= (uint64_t) ( a<<1 ) ); 404 #endif 405 } 406 407 /*---------------------------------------------------------------------------- 408 | Returns 1 if the double-precision floating-point value `a' is a signaling 409 | NaN; otherwise returns 0. 410 *----------------------------------------------------------------------------*/ 411 412 int float64_is_signaling_nan( float64 a_ ) 413 { 414 uint64_t a = float64_val(a_); 415 #if SNAN_BIT_IS_ONE 416 return ( LIT64( 0xFFF0000000000000 ) <= (uint64_t) ( a<<1 ) ); 417 #else 418 return 419 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE ) 420 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) ); 421 #endif 422 } 423 424 /*---------------------------------------------------------------------------- 425 | Returns a quiet NaN if the double-precision floating point value `a' is a 426 | signaling NaN; otherwise returns `a'. 427 *----------------------------------------------------------------------------*/ 428 429 float64 float64_maybe_silence_nan( float64 a_ ) 430 { 431 if (float64_is_signaling_nan(a_)) { 432 #if SNAN_BIT_IS_ONE 433 # if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32) 434 return float64_default_nan; 435 # else 436 # error Rules for silencing a signaling NaN are target-specific 437 # endif 438 #else 439 uint64_t a = float64_val(a_); 440 a |= LIT64( 0x0008000000000000 ); 441 return make_float64(a); 442 #endif 443 } 444 return a_; 445 } 446 447 /*---------------------------------------------------------------------------- 448 | Returns the result of converting the double-precision floating-point NaN 449 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid 450 | exception is raised. 451 *----------------------------------------------------------------------------*/ 452 453 static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM) 454 { 455 commonNaNT z; 456 457 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR); 458 z.sign = float64_val(a)>>63; 459 z.low = 0; 460 z.high = float64_val(a)<<12; 461 return z; 462 } 463 464 /*---------------------------------------------------------------------------- 465 | Returns the result of converting the canonical NaN `a' to the double- 466 | precision floating-point format. 467 *----------------------------------------------------------------------------*/ 468 469 static float64 commonNaNToFloat64( commonNaNT a STATUS_PARAM) 470 { 471 uint64_t mantissa = a.high>>12; 472 473 if ( STATUS(default_nan_mode) ) { 474 return float64_default_nan; 475 } 476 477 if ( mantissa ) 478 return make_float64( 479 ( ( (uint64_t) a.sign )<<63 ) 480 | LIT64( 0x7FF0000000000000 ) 481 | ( a.high>>12 )); 482 else 483 return float64_default_nan; 484 } 485 486 /*---------------------------------------------------------------------------- 487 | Takes two double-precision floating-point values `a' and `b', one of which 488 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a 489 | signaling NaN, the invalid exception is raised. 490 *----------------------------------------------------------------------------*/ 491 492 static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM) 493 { 494 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN; 495 flag aIsLargerSignificand; 496 uint64_t av, bv; 497 498 aIsQuietNaN = float64_is_quiet_nan( a ); 499 aIsSignalingNaN = float64_is_signaling_nan( a ); 500 bIsQuietNaN = float64_is_quiet_nan( b ); 501 bIsSignalingNaN = float64_is_signaling_nan( b ); 502 av = float64_val(a); 503 bv = float64_val(b); 504 505 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR); 506 507 if ( STATUS(default_nan_mode) ) 508 return float64_default_nan; 509 510 if ((uint64_t)(av<<1) < (uint64_t)(bv<<1)) { 511 aIsLargerSignificand = 0; 512 } else if ((uint64_t)(bv<<1) < (uint64_t)(av<<1)) { 513 aIsLargerSignificand = 1; 514 } else { 515 aIsLargerSignificand = (av < bv) ? 1 : 0; 516 } 517 518 if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN, 519 aIsLargerSignificand)) { 520 return float64_maybe_silence_nan(b); 521 } else { 522 return float64_maybe_silence_nan(a); 523 } 524 } 525 526 #ifdef FLOATX80 527 528 /*---------------------------------------------------------------------------- 529 | Returns 1 if the extended double-precision floating-point value `a' is a 530 | quiet NaN; otherwise returns 0. This slightly differs from the same 531 | function for other types as floatx80 has an explicit bit. 532 *----------------------------------------------------------------------------*/ 533 534 int floatx80_is_quiet_nan( floatx80 a ) 535 { 536 #if SNAN_BIT_IS_ONE 537 uint64_t aLow; 538 539 aLow = a.low & ~ LIT64( 0x4000000000000000 ); 540 return 541 ( ( a.high & 0x7FFF ) == 0x7FFF ) 542 && (uint64_t) ( aLow<<1 ) 543 && ( a.low == aLow ); 544 #else 545 return ( ( a.high & 0x7FFF ) == 0x7FFF ) 546 && (LIT64( 0x8000000000000000 ) <= ((uint64_t) ( a.low<<1 ))); 547 #endif 548 } 549 550 /*---------------------------------------------------------------------------- 551 | Returns 1 if the extended double-precision floating-point value `a' is a 552 | signaling NaN; otherwise returns 0. This slightly differs from the same 553 | function for other types as floatx80 has an explicit bit. 554 *----------------------------------------------------------------------------*/ 555 556 int floatx80_is_signaling_nan( floatx80 a ) 557 { 558 #if SNAN_BIT_IS_ONE 559 return ( ( a.high & 0x7FFF ) == 0x7FFF ) 560 && (LIT64( 0x8000000000000000 ) <= ((uint64_t) ( a.low<<1 ))); 561 #else 562 uint64_t aLow; 563 564 aLow = a.low & ~ LIT64( 0x4000000000000000 ); 565 return 566 ( ( a.high & 0x7FFF ) == 0x7FFF ) 567 && (uint64_t) ( aLow<<1 ) 568 && ( a.low == aLow ); 569 #endif 570 } 571 572 /*---------------------------------------------------------------------------- 573 | Returns a quiet NaN if the extended double-precision floating point value 574 | `a' is a signaling NaN; otherwise returns `a'. 575 *----------------------------------------------------------------------------*/ 576 577 floatx80 floatx80_maybe_silence_nan( floatx80 a ) 578 { 579 if (floatx80_is_signaling_nan(a)) { 580 #if SNAN_BIT_IS_ONE 581 # if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32) 582 a.low = floatx80_default_nan_low; 583 a.high = floatx80_default_nan_high; 584 # else 585 # error Rules for silencing a signaling NaN are target-specific 586 # endif 587 #else 588 a.low |= LIT64( 0xC000000000000000 ); 589 return a; 590 #endif 591 } 592 return a; 593 } 594 595 /*---------------------------------------------------------------------------- 596 | Returns the result of converting the extended double-precision floating- 597 | point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the 598 | invalid exception is raised. 599 *----------------------------------------------------------------------------*/ 600 601 static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM) 602 { 603 commonNaNT z; 604 605 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR); 606 if ( a.low >> 63 ) { 607 z.sign = a.high >> 15; 608 z.low = 0; 609 z.high = a.low << 1; 610 } else { 611 z.sign = floatx80_default_nan_high >> 15; 612 z.low = 0; 613 z.high = floatx80_default_nan_low << 1; 614 } 615 return z; 616 } 617 618 /*---------------------------------------------------------------------------- 619 | Returns the result of converting the canonical NaN `a' to the extended 620 | double-precision floating-point format. 621 *----------------------------------------------------------------------------*/ 622 623 static floatx80 commonNaNToFloatx80( commonNaNT a STATUS_PARAM) 624 { 625 floatx80 z; 626 627 if ( STATUS(default_nan_mode) ) { 628 z.low = floatx80_default_nan_low; 629 z.high = floatx80_default_nan_high; 630 return z; 631 } 632 633 if (a.high >> 1) { 634 z.low = LIT64( 0x8000000000000000 ) | a.high >> 1; 635 z.high = ( ( (uint16_t) a.sign )<<15 ) | 0x7FFF; 636 } else { 637 z.low = floatx80_default_nan_low; 638 z.high = floatx80_default_nan_high; 639 } 640 641 return z; 642 } 643 644 /*---------------------------------------------------------------------------- 645 | Takes two extended double-precision floating-point values `a' and `b', one 646 | of which is a NaN, and returns the appropriate NaN result. If either `a' or 647 | `b' is a signaling NaN, the invalid exception is raised. 648 *----------------------------------------------------------------------------*/ 649 650 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM) 651 { 652 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN; 653 flag aIsLargerSignificand; 654 655 aIsQuietNaN = floatx80_is_quiet_nan( a ); 656 aIsSignalingNaN = floatx80_is_signaling_nan( a ); 657 bIsQuietNaN = floatx80_is_quiet_nan( b ); 658 bIsSignalingNaN = floatx80_is_signaling_nan( b ); 659 660 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR); 661 662 if ( STATUS(default_nan_mode) ) { 663 a.low = floatx80_default_nan_low; 664 a.high = floatx80_default_nan_high; 665 return a; 666 } 667 668 if (a.low < b.low) { 669 aIsLargerSignificand = 0; 670 } else if (b.low < a.low) { 671 aIsLargerSignificand = 1; 672 } else { 673 aIsLargerSignificand = (a.high < b.high) ? 1 : 0; 674 } 675 676 if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN, 677 aIsLargerSignificand)) { 678 return floatx80_maybe_silence_nan(b); 679 } else { 680 return floatx80_maybe_silence_nan(a); 681 } 682 } 683 684 #endif 685 686 #ifdef FLOAT128 687 688 /*---------------------------------------------------------------------------- 689 | Returns 1 if the quadruple-precision floating-point value `a' is a quiet 690 | NaN; otherwise returns 0. 691 *----------------------------------------------------------------------------*/ 692 693 int float128_is_quiet_nan( float128 a ) 694 { 695 #if SNAN_BIT_IS_ONE 696 return 697 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE ) 698 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) ); 699 #else 700 return 701 ( LIT64( 0xFFFE000000000000 ) <= (uint64_t) ( a.high<<1 ) ) 702 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) ); 703 #endif 704 } 705 706 /*---------------------------------------------------------------------------- 707 | Returns 1 if the quadruple-precision floating-point value `a' is a 708 | signaling NaN; otherwise returns 0. 709 *----------------------------------------------------------------------------*/ 710 711 int float128_is_signaling_nan( float128 a ) 712 { 713 #if SNAN_BIT_IS_ONE 714 return 715 ( LIT64( 0xFFFE000000000000 ) <= (uint64_t) ( a.high<<1 ) ) 716 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) ); 717 #else 718 return 719 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE ) 720 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) ); 721 #endif 722 } 723 724 /*---------------------------------------------------------------------------- 725 | Returns a quiet NaN if the quadruple-precision floating point value `a' is 726 | a signaling NaN; otherwise returns `a'. 727 *----------------------------------------------------------------------------*/ 728 729 float128 float128_maybe_silence_nan( float128 a ) 730 { 731 if (float128_is_signaling_nan(a)) { 732 #if SNAN_BIT_IS_ONE 733 # if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32) 734 a.low = float128_default_nan_low; 735 a.high = float128_default_nan_high; 736 # else 737 # error Rules for silencing a signaling NaN are target-specific 738 # endif 739 #else 740 a.high |= LIT64( 0x0000800000000000 ); 741 return a; 742 #endif 743 } 744 return a; 745 } 746 747 /*---------------------------------------------------------------------------- 748 | Returns the result of converting the quadruple-precision floating-point NaN 749 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid 750 | exception is raised. 751 *----------------------------------------------------------------------------*/ 752 753 static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM) 754 { 755 commonNaNT z; 756 757 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR); 758 z.sign = a.high>>63; 759 shortShift128Left( a.high, a.low, 16, &z.high, &z.low ); 760 return z; 761 } 762 763 /*---------------------------------------------------------------------------- 764 | Returns the result of converting the canonical NaN `a' to the quadruple- 765 | precision floating-point format. 766 *----------------------------------------------------------------------------*/ 767 768 static float128 commonNaNToFloat128( commonNaNT a STATUS_PARAM) 769 { 770 float128 z; 771 772 if ( STATUS(default_nan_mode) ) { 773 z.low = float128_default_nan_low; 774 z.high = float128_default_nan_high; 775 return z; 776 } 777 778 shift128Right( a.high, a.low, 16, &z.high, &z.low ); 779 z.high |= ( ( (uint64_t) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 ); 780 return z; 781 } 782 783 /*---------------------------------------------------------------------------- 784 | Takes two quadruple-precision floating-point values `a' and `b', one of 785 | which is a NaN, and returns the appropriate NaN result. If either `a' or 786 | `b' is a signaling NaN, the invalid exception is raised. 787 *----------------------------------------------------------------------------*/ 788 789 static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM) 790 { 791 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN; 792 flag aIsLargerSignificand; 793 794 aIsQuietNaN = float128_is_quiet_nan( a ); 795 aIsSignalingNaN = float128_is_signaling_nan( a ); 796 bIsQuietNaN = float128_is_quiet_nan( b ); 797 bIsSignalingNaN = float128_is_signaling_nan( b ); 798 799 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR); 800 801 if ( STATUS(default_nan_mode) ) { 802 a.low = float128_default_nan_low; 803 a.high = float128_default_nan_high; 804 return a; 805 } 806 807 if (lt128(a.high<<1, a.low, b.high<<1, b.low)) { 808 aIsLargerSignificand = 0; 809 } else if (lt128(b.high<<1, b.low, a.high<<1, a.low)) { 810 aIsLargerSignificand = 1; 811 } else { 812 aIsLargerSignificand = (a.high < b.high) ? 1 : 0; 813 } 814 815 if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN, 816 aIsLargerSignificand)) { 817 return float128_maybe_silence_nan(b); 818 } else { 819 return float128_maybe_silence_nan(a); 820 } 821 } 822 823 #endif 824