trunk/src/lib/softfloat/softfloat.h
r25446 | r25447 | |
89 | 89 | *----------------------------------------------------------------------------*/ |
90 | 90 | extern int8 float_exception_flags; |
91 | 91 | enum { |
92 | | float_flag_inexact = 1, |
93 | | float_flag_underflow = 2, |
94 | | float_flag_overflow = 4, |
95 | | float_flag_divbyzero = 8, |
96 | | float_flag_invalid = 16 |
| 92 | float_flag_invalid = 0x01, float_flag_denormal = 0x02, float_flag_divbyzero = 0x04, float_flag_overflow = 0x08, |
| 93 | float_flag_underflow = 0x10, float_flag_inexact = 0x20 |
97 | 94 | }; |
98 | 95 | |
99 | 96 | /*---------------------------------------------------------------------------- |
r25446 | r25447 | |
202 | 199 | #ifdef FLOAT128 |
203 | 200 | float128 floatx80_to_float128( floatx80 ); |
204 | 201 | #endif |
| 202 | floatx80 floatx80_scale(floatx80 a, floatx80 b); |
205 | 203 | |
206 | 204 | /*---------------------------------------------------------------------------- |
207 | 205 | | Packs the sign `zSign', exponent `zExp', and significand `zSig' into an |
r25446 | r25447 | |
459 | 457 | return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 ); |
460 | 458 | |
461 | 459 | } |
462 | | |
463 | 460 | #endif |
trunk/src/lib/softfloat/fsincos.c
r25446 | r25447 | |
563 | 563 | { |
564 | 564 | return float128_mul(x, EvenPoly(x, arr, n)); |
565 | 565 | } |
| 566 | |
| 567 | /*---------------------------------------------------------------------------- |
| 568 | | Scales extended double-precision floating-point value in operand `a' by |
| 569 | | value `b'. The function truncates the value in the second operand 'b' to |
| 570 | | an integral value and adds that value to the exponent of the operand 'a'. |
| 571 | | The operation performed according to the IEC/IEEE Standard for Binary |
| 572 | | Floating-Point Arithmetic. |
| 573 | *----------------------------------------------------------------------------*/ |
| 574 | |
| 575 | extern floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b ); |
| 576 | |
| 577 | floatx80 floatx80_scale(floatx80 a, floatx80 b) |
| 578 | { |
| 579 | sbits32 aExp, bExp; |
| 580 | bits64 aSig, bSig; |
| 581 | |
| 582 | // handle unsupported extended double-precision floating encodings |
| 583 | /* if (floatx80_is_unsupported(a) || floatx80_is_unsupported(b)) |
| 584 | { |
| 585 | float_raise(float_flag_invalid); |
| 586 | return floatx80_default_nan; |
| 587 | }*/ |
| 588 | |
| 589 | aSig = extractFloatx80Frac(a); |
| 590 | aExp = extractFloatx80Exp(a); |
| 591 | int aSign = extractFloatx80Sign(a); |
| 592 | bSig = extractFloatx80Frac(b); |
| 593 | bExp = extractFloatx80Exp(b); |
| 594 | int bSign = extractFloatx80Sign(b); |
| 595 | |
| 596 | if (aExp == 0x7FFF) { |
| 597 | if ((bits64) (aSig<<1) || ((bExp == 0x7FFF) && (bits64) (bSig<<1))) |
| 598 | { |
| 599 | return propagateFloatx80NaN(a, b); |
| 600 | } |
| 601 | if ((bExp == 0x7FFF) && bSign) { |
| 602 | float_raise(float_flag_invalid); |
| 603 | return floatx80_default_nan; |
| 604 | } |
| 605 | if (bSig && (bExp == 0)) float_raise(float_flag_denormal); |
| 606 | return a; |
| 607 | } |
| 608 | if (bExp == 0x7FFF) { |
| 609 | if ((bits64) (bSig<<1)) return propagateFloatx80NaN(a, b); |
| 610 | if ((aExp | aSig) == 0) { |
| 611 | if (! bSign) { |
| 612 | float_raise(float_flag_invalid); |
| 613 | return floatx80_default_nan; |
| 614 | } |
| 615 | return a; |
| 616 | } |
| 617 | if (aSig && (aExp == 0)) float_raise(float_flag_denormal); |
| 618 | if (bSign) return packFloatx80(aSign, 0, 0); |
| 619 | return packFloatx80(aSign, 0x7FFF, U64(0x8000000000000000)); |
| 620 | } |
| 621 | if (aExp == 0) { |
| 622 | if (aSig == 0) return a; |
| 623 | float_raise(float_flag_denormal); |
| 624 | normalizeFloatx80Subnormal(aSig, &aExp, &aSig); |
| 625 | } |
| 626 | if (bExp == 0) { |
| 627 | if (bSig == 0) return a; |
| 628 | float_raise(float_flag_denormal); |
| 629 | normalizeFloatx80Subnormal(bSig, &bExp, &bSig); |
| 630 | } |
| 631 | |
| 632 | if (bExp > 0x400E) { |
| 633 | /* generate appropriate overflow/underflow */ |
| 634 | return roundAndPackFloatx80(80, aSign, |
| 635 | bSign ? -0x3FFF : 0x7FFF, aSig, 0); |
| 636 | } |
| 637 | if (bExp < 0x3FFF) return a; |
| 638 | |
| 639 | int shiftCount = 0x403E - bExp; |
| 640 | bSig >>= shiftCount; |
| 641 | sbits32 scale = bSig; |
| 642 | if (bSign) scale = -scale; /* -32768..32767 */ |
| 643 | return |
| 644 | roundAndPackFloatx80(80, aSign, aExp+scale, aSig, 0); |
| 645 | } |