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