1 2 /*============================================================================ 3 4 This C source fragment is part of the SoftFloat IEC/IEEE Floating-point 5 Arithmetic Package, Release 2b. 6 7 Written by John R. Hauser. This work was made possible in part by the 8 International Computer Science Institute, located at Suite 600, 1947 Center 9 Street, Berkeley, California 94704. Funding was partially provided by the 10 National Science Foundation under grant MIP-9311980. The original version 11 of this code was written as part of a project to build a fixed-point vector 12 processor in collaboration with the University of California at Berkeley, 13 overseen by Profs. Nelson Morgan and John Wawrzynek. More information 14 is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ 15 arithmetic/SoftFloat.html'. 16 17 THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has 18 been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES 19 RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS 20 AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, 21 COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE 22 EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE 23 INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR 24 OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. 25 26 Derivative works are acceptable, even for commercial purposes, so long as 27 (1) the source code for the derivative work includes prominent notice that 28 the work is derivative, and (2) the source code includes prominent notice with 29 these four paragraphs for those parts of this code that are retained. 30 31 =============================================================================*/ 32 33 #if defined(TARGET_MIPS) || defined(TARGET_HPPA) 34 #define SNAN_BIT_IS_ONE 1 35 #else 36 #define SNAN_BIT_IS_ONE 0 37 #endif 38 39 /*---------------------------------------------------------------------------- 40 | Raises the exceptions specified by `flags'. Floating-point traps can be 41 | defined here if desired. It is currently not possible for such a trap 42 | to substitute a result value. If traps are not implemented, this routine 43 | should be simply `float_exception_flags |= flags;'. 44 *----------------------------------------------------------------------------*/ 45 46 void float_raise( int8 flags STATUS_PARAM ) 47 { 48 STATUS(float_exception_flags) |= flags; 49 } 50 51 /*---------------------------------------------------------------------------- 52 | Internal canonical NaN format. 53 *----------------------------------------------------------------------------*/ 54 typedef struct { 55 flag sign; 56 bits64 high, low; 57 } commonNaNT; 58 59 /*---------------------------------------------------------------------------- 60 | The pattern for a default generated single-precision NaN. 61 *----------------------------------------------------------------------------*/ 62 #if defined(TARGET_SPARC) 63 #define float32_default_nan make_float32(0x7FFFFFFF) 64 #elif defined(TARGET_POWERPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) 65 #define float32_default_nan make_float32(0x7FC00000) 66 #elif defined(TARGET_HPPA) 67 #define float32_default_nan make_float32(0x7FA00000) 68 #elif SNAN_BIT_IS_ONE 69 #define float32_default_nan make_float32(0x7FBFFFFF) 70 #else 71 #define float32_default_nan make_float32(0xFFC00000) 72 #endif 73 74 /*---------------------------------------------------------------------------- 75 | Returns 1 if the single-precision floating-point value `a' is a quiet 76 | NaN; otherwise returns 0. 77 *----------------------------------------------------------------------------*/ 78 79 int float32_is_nan( float32 a_ ) 80 { 81 uint32_t a = float32_val(a_); 82 #if SNAN_BIT_IS_ONE 83 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); 84 #else 85 return ( 0xFF800000 <= (bits32) ( a<<1 ) ); 86 #endif 87 } 88 89 /*---------------------------------------------------------------------------- 90 | Returns 1 if the single-precision floating-point value `a' is a signaling 91 | NaN; otherwise returns 0. 92 *----------------------------------------------------------------------------*/ 93 94 int float32_is_signaling_nan( float32 a_ ) 95 { 96 uint32_t a = float32_val(a_); 97 #if SNAN_BIT_IS_ONE 98 return ( 0xFF800000 <= (bits32) ( a<<1 ) ); 99 #else 100 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); 101 #endif 102 } 103 104 /*---------------------------------------------------------------------------- 105 | Returns the result of converting the single-precision floating-point NaN 106 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid 107 | exception is raised. 108 *----------------------------------------------------------------------------*/ 109 110 static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM ) 111 { 112 commonNaNT z; 113 114 if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR ); 115 z.sign = float32_val(a)>>31; 116 z.low = 0; 117 z.high = ( (bits64) float32_val(a) )<<41; 118 return z; 119 } 120 121 /*---------------------------------------------------------------------------- 122 | Returns the result of converting the canonical NaN `a' to the single- 123 | precision floating-point format. 124 *----------------------------------------------------------------------------*/ 125 126 static float32 commonNaNToFloat32( commonNaNT a ) 127 { 128 bits32 mantissa = a.high>>41; 129 if ( mantissa ) 130 return make_float32( 131 ( ( (bits32) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) ); 132 else 133 return float32_default_nan; 134 } 135 136 /*---------------------------------------------------------------------------- 137 | Takes two single-precision floating-point values `a' and `b', one of which 138 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a 139 | signaling NaN, the invalid exception is raised. 140 *----------------------------------------------------------------------------*/ 141 142 static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM) 143 { 144 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 145 bits32 av, bv, res; 146 147 if ( STATUS(default_nan_mode) ) 148 return float32_default_nan; 149 150 aIsNaN = float32_is_nan( a ); 151 aIsSignalingNaN = float32_is_signaling_nan( a ); 152 bIsNaN = float32_is_nan( b ); 153 bIsSignalingNaN = float32_is_signaling_nan( b ); 154 av = float32_val(a); 155 bv = float32_val(b); 156 #if SNAN_BIT_IS_ONE 157 av &= ~0x00400000; 158 bv &= ~0x00400000; 159 #else 160 av |= 0x00400000; 161 bv |= 0x00400000; 162 #endif 163 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR); 164 if ( aIsSignalingNaN ) { 165 if ( bIsSignalingNaN ) goto returnLargerSignificand; 166 res = bIsNaN ? bv : av; 167 } 168 else if ( aIsNaN ) { 169 if ( bIsSignalingNaN || ! bIsNaN ) 170 res = av; 171 else { 172 returnLargerSignificand: 173 if ( (bits32) ( av<<1 ) < (bits32) ( bv<<1 ) ) 174 res = bv; 175 else if ( (bits32) ( bv<<1 ) < (bits32) ( av<<1 ) ) 176 res = av; 177 else 178 res = ( av < bv ) ? av : bv; 179 } 180 } 181 else { 182 res = bv; 183 } 184 return make_float32(res); 185 } 186 187 /*---------------------------------------------------------------------------- 188 | The pattern for a default generated double-precision NaN. 189 *----------------------------------------------------------------------------*/ 190 #if defined(TARGET_SPARC) 191 #define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF )) 192 #elif defined(TARGET_POWERPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) 193 #define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 )) 194 #elif defined(TARGET_HPPA) 195 #define float64_default_nan make_float64(LIT64( 0x7FF4000000000000 )) 196 #elif SNAN_BIT_IS_ONE 197 #define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF )) 198 #else 199 #define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 )) 200 #endif 201 202 /*---------------------------------------------------------------------------- 203 | Returns 1 if the double-precision floating-point value `a' is a quiet 204 | NaN; otherwise returns 0. 205 *----------------------------------------------------------------------------*/ 206 207 int float64_is_nan( float64 a_ ) 208 { 209 bits64 a = float64_val(a_); 210 #if SNAN_BIT_IS_ONE 211 return 212 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE ) 213 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) ); 214 #else 215 return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) ); 216 #endif 217 } 218 219 /*---------------------------------------------------------------------------- 220 | Returns 1 if the double-precision floating-point value `a' is a signaling 221 | NaN; otherwise returns 0. 222 *----------------------------------------------------------------------------*/ 223 224 int float64_is_signaling_nan( float64 a_ ) 225 { 226 bits64 a = float64_val(a_); 227 #if SNAN_BIT_IS_ONE 228 return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) ); 229 #else 230 return 231 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE ) 232 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) ); 233 #endif 234 } 235 236 /*---------------------------------------------------------------------------- 237 | Returns the result of converting the double-precision floating-point NaN 238 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid 239 | exception is raised. 240 *----------------------------------------------------------------------------*/ 241 242 static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM) 243 { 244 commonNaNT z; 245 246 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR); 247 z.sign = float64_val(a)>>63; 248 z.low = 0; 249 z.high = float64_val(a)<<12; 250 return z; 251 } 252 253 /*---------------------------------------------------------------------------- 254 | Returns the result of converting the canonical NaN `a' to the double- 255 | precision floating-point format. 256 *----------------------------------------------------------------------------*/ 257 258 static float64 commonNaNToFloat64( commonNaNT a ) 259 { 260 bits64 mantissa = a.high>>12; 261 262 if ( mantissa ) 263 return make_float64( 264 ( ( (bits64) a.sign )<<63 ) 265 | LIT64( 0x7FF0000000000000 ) 266 | ( a.high>>12 )); 267 else 268 return float64_default_nan; 269 } 270 271 /*---------------------------------------------------------------------------- 272 | Takes two double-precision floating-point values `a' and `b', one of which 273 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a 274 | signaling NaN, the invalid exception is raised. 275 *----------------------------------------------------------------------------*/ 276 277 static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM) 278 { 279 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 280 bits64 av, bv, res; 281 282 if ( STATUS(default_nan_mode) ) 283 return float64_default_nan; 284 285 aIsNaN = float64_is_nan( a ); 286 aIsSignalingNaN = float64_is_signaling_nan( a ); 287 bIsNaN = float64_is_nan( b ); 288 bIsSignalingNaN = float64_is_signaling_nan( b ); 289 av = float64_val(a); 290 bv = float64_val(b); 291 #if SNAN_BIT_IS_ONE 292 av &= ~LIT64( 0x0008000000000000 ); 293 bv &= ~LIT64( 0x0008000000000000 ); 294 #else 295 av |= LIT64( 0x0008000000000000 ); 296 bv |= LIT64( 0x0008000000000000 ); 297 #endif 298 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR); 299 if ( aIsSignalingNaN ) { 300 if ( bIsSignalingNaN ) goto returnLargerSignificand; 301 res = bIsNaN ? bv : av; 302 } 303 else if ( aIsNaN ) { 304 if ( bIsSignalingNaN || ! bIsNaN ) 305 res = av; 306 else { 307 returnLargerSignificand: 308 if ( (bits64) ( av<<1 ) < (bits64) ( bv<<1 ) ) 309 res = bv; 310 else if ( (bits64) ( bv<<1 ) < (bits64) ( av<<1 ) ) 311 res = av; 312 else 313 res = ( av < bv ) ? av : bv; 314 } 315 } 316 else { 317 res = bv; 318 } 319 return make_float64(res); 320 } 321 322 #ifdef FLOATX80 323 324 /*---------------------------------------------------------------------------- 325 | The pattern for a default generated extended double-precision NaN. The 326 | `high' and `low' values hold the most- and least-significant bits, 327 | respectively. 328 *----------------------------------------------------------------------------*/ 329 #if SNAN_BIT_IS_ONE 330 #define floatx80_default_nan_high 0x7FFF 331 #define floatx80_default_nan_low LIT64( 0xBFFFFFFFFFFFFFFF ) 332 #else 333 #define floatx80_default_nan_high 0xFFFF 334 #define floatx80_default_nan_low LIT64( 0xC000000000000000 ) 335 #endif 336 337 /*---------------------------------------------------------------------------- 338 | Returns 1 if the extended double-precision floating-point value `a' is a 339 | quiet NaN; otherwise returns 0. 340 *----------------------------------------------------------------------------*/ 341 342 int floatx80_is_nan( floatx80 a ) 343 { 344 #if SNAN_BIT_IS_ONE 345 bits64 aLow; 346 347 aLow = a.low & ~ LIT64( 0x4000000000000000 ); 348 return 349 ( ( a.high & 0x7FFF ) == 0x7FFF ) 350 && (bits64) ( aLow<<1 ) 351 && ( a.low == aLow ); 352 #else 353 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 ); 354 #endif 355 } 356 357 /*---------------------------------------------------------------------------- 358 | Returns 1 if the extended double-precision floating-point value `a' is a 359 | signaling NaN; otherwise returns 0. 360 *----------------------------------------------------------------------------*/ 361 362 int floatx80_is_signaling_nan( floatx80 a ) 363 { 364 #if SNAN_BIT_IS_ONE 365 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 ); 366 #else 367 bits64 aLow; 368 369 aLow = a.low & ~ LIT64( 0x4000000000000000 ); 370 return 371 ( ( a.high & 0x7FFF ) == 0x7FFF ) 372 && (bits64) ( aLow<<1 ) 373 && ( a.low == aLow ); 374 #endif 375 } 376 377 /*---------------------------------------------------------------------------- 378 | Returns the result of converting the extended double-precision floating- 379 | point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the 380 | invalid exception is raised. 381 *----------------------------------------------------------------------------*/ 382 383 static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM) 384 { 385 commonNaNT z; 386 387 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR); 388 z.sign = a.high>>15; 389 z.low = 0; 390 z.high = a.low; 391 return z; 392 } 393 394 /*---------------------------------------------------------------------------- 395 | Returns the result of converting the canonical NaN `a' to the extended 396 | double-precision floating-point format. 397 *----------------------------------------------------------------------------*/ 398 399 static floatx80 commonNaNToFloatx80( commonNaNT a ) 400 { 401 floatx80 z; 402 403 if (a.high) 404 z.low = a.high; 405 else 406 z.low = floatx80_default_nan_low; 407 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF; 408 return z; 409 } 410 411 /*---------------------------------------------------------------------------- 412 | Takes two extended double-precision floating-point values `a' and `b', one 413 | of which is a NaN, and returns the appropriate NaN result. If either `a' or 414 | `b' is a signaling NaN, the invalid exception is raised. 415 *----------------------------------------------------------------------------*/ 416 417 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM) 418 { 419 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 420 421 if ( STATUS(default_nan_mode) ) { 422 a.low = floatx80_default_nan_low; 423 a.high = floatx80_default_nan_high; 424 return a; 425 } 426 427 aIsNaN = floatx80_is_nan( a ); 428 aIsSignalingNaN = floatx80_is_signaling_nan( a ); 429 bIsNaN = floatx80_is_nan( b ); 430 bIsSignalingNaN = floatx80_is_signaling_nan( b ); 431 #if SNAN_BIT_IS_ONE 432 a.low &= ~LIT64( 0xC000000000000000 ); 433 b.low &= ~LIT64( 0xC000000000000000 ); 434 #else 435 a.low |= LIT64( 0xC000000000000000 ); 436 b.low |= LIT64( 0xC000000000000000 ); 437 #endif 438 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR); 439 if ( aIsSignalingNaN ) { 440 if ( bIsSignalingNaN ) goto returnLargerSignificand; 441 return bIsNaN ? b : a; 442 } 443 else if ( aIsNaN ) { 444 if ( bIsSignalingNaN || ! bIsNaN ) return a; 445 returnLargerSignificand: 446 if ( a.low < b.low ) return b; 447 if ( b.low < a.low ) return a; 448 return ( a.high < b.high ) ? a : b; 449 } 450 else { 451 return b; 452 } 453 } 454 455 #endif 456 457 #ifdef FLOAT128 458 459 /*---------------------------------------------------------------------------- 460 | The pattern for a default generated quadruple-precision NaN. The `high' and 461 | `low' values hold the most- and least-significant bits, respectively. 462 *----------------------------------------------------------------------------*/ 463 #if SNAN_BIT_IS_ONE 464 #define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF ) 465 #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF ) 466 #else 467 #define float128_default_nan_high LIT64( 0xFFFF800000000000 ) 468 #define float128_default_nan_low LIT64( 0x0000000000000000 ) 469 #endif 470 471 /*---------------------------------------------------------------------------- 472 | Returns 1 if the quadruple-precision floating-point value `a' is a quiet 473 | NaN; otherwise returns 0. 474 *----------------------------------------------------------------------------*/ 475 476 int float128_is_nan( float128 a ) 477 { 478 #if SNAN_BIT_IS_ONE 479 return 480 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE ) 481 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) ); 482 #else 483 return 484 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) ) 485 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) ); 486 #endif 487 } 488 489 /*---------------------------------------------------------------------------- 490 | Returns 1 if the quadruple-precision floating-point value `a' is a 491 | signaling NaN; otherwise returns 0. 492 *----------------------------------------------------------------------------*/ 493 494 int float128_is_signaling_nan( float128 a ) 495 { 496 #if SNAN_BIT_IS_ONE 497 return 498 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) ) 499 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) ); 500 #else 501 return 502 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE ) 503 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) ); 504 #endif 505 } 506 507 /*---------------------------------------------------------------------------- 508 | Returns the result of converting the quadruple-precision floating-point NaN 509 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid 510 | exception is raised. 511 *----------------------------------------------------------------------------*/ 512 513 static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM) 514 { 515 commonNaNT z; 516 517 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR); 518 z.sign = a.high>>63; 519 shortShift128Left( a.high, a.low, 16, &z.high, &z.low ); 520 return z; 521 } 522 523 /*---------------------------------------------------------------------------- 524 | Returns the result of converting the canonical NaN `a' to the quadruple- 525 | precision floating-point format. 526 *----------------------------------------------------------------------------*/ 527 528 static float128 commonNaNToFloat128( commonNaNT a ) 529 { 530 float128 z; 531 532 shift128Right( a.high, a.low, 16, &z.high, &z.low ); 533 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 ); 534 return z; 535 } 536 537 /*---------------------------------------------------------------------------- 538 | Takes two quadruple-precision floating-point values `a' and `b', one of 539 | which is a NaN, and returns the appropriate NaN result. If either `a' or 540 | `b' is a signaling NaN, the invalid exception is raised. 541 *----------------------------------------------------------------------------*/ 542 543 static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM) 544 { 545 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; 546 547 if ( STATUS(default_nan_mode) ) { 548 a.low = float128_default_nan_low; 549 a.high = float128_default_nan_high; 550 return a; 551 } 552 553 aIsNaN = float128_is_nan( a ); 554 aIsSignalingNaN = float128_is_signaling_nan( a ); 555 bIsNaN = float128_is_nan( b ); 556 bIsSignalingNaN = float128_is_signaling_nan( b ); 557 #if SNAN_BIT_IS_ONE 558 a.high &= ~LIT64( 0x0000800000000000 ); 559 b.high &= ~LIT64( 0x0000800000000000 ); 560 #else 561 a.high |= LIT64( 0x0000800000000000 ); 562 b.high |= LIT64( 0x0000800000000000 ); 563 #endif 564 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR); 565 if ( aIsSignalingNaN ) { 566 if ( bIsSignalingNaN ) goto returnLargerSignificand; 567 return bIsNaN ? b : a; 568 } 569 else if ( aIsNaN ) { 570 if ( bIsSignalingNaN || ! bIsNaN ) return a; 571 returnLargerSignificand: 572 if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b; 573 if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a; 574 return ( a.high < b.high ) ? a : b; 575 } 576 else { 577 return b; 578 } 579 } 580 581 #endif 582