diff options
author | 2013-01-11 07:32:46 +0000 | |
---|---|---|
committer | 2013-01-11 07:32:46 +0000 | |
commit | 0e19f641d3186cdbf51f8ca857e2b07ab95779c2 (patch) | |
tree | 234109de1123b13f217494af4b3f8efad346d5cc /src/lib/softfloat/fyl2x.c | |
parent | 111157ca09a9ff60fe4a9ba49173c315e94314fa (diff) |
Cleanups and version bumpmame0148
Diffstat (limited to 'src/lib/softfloat/fyl2x.c')
-rw-r--r-- | src/lib/softfloat/fyl2x.c | 468 |
1 files changed, 234 insertions, 234 deletions
diff --git a/src/lib/softfloat/fyl2x.c b/src/lib/softfloat/fyl2x.c index fc41d125581..be5e134cc3b 100644 --- a/src/lib/softfloat/fyl2x.c +++ b/src/lib/softfloat/fyl2x.c @@ -53,7 +53,7 @@ static const floatx80 floatx80_default_nan = packFloatx80(0, 0xffff, U64(0xfffff INLINE bits64 extractFloatx80Frac( floatx80 a ) { - return a.low; + return a.low; } @@ -65,7 +65,7 @@ INLINE bits64 extractFloatx80Frac( floatx80 a ) INLINE int32 extractFloatx80Exp( floatx80 a ) { - return a.high & 0x7FFF; + return a.high & 0x7FFF; } @@ -77,7 +77,7 @@ INLINE int32 extractFloatx80Exp( floatx80 a ) INLINE flag extractFloatx80Sign( floatx80 a ) { - return a.high>>15; + return a.high>>15; } @@ -89,12 +89,12 @@ INLINE flag extractFloatx80Sign( floatx80 a ) INLINE floatx80 propagateFloatx80NaNOneArg(floatx80 a) { - if (floatx80_is_signaling_nan(a)) - float_raise(float_flag_invalid); + if (floatx80_is_signaling_nan(a)) + float_raise(float_flag_invalid); - a.low |= U64(0xC000000000000000); + a.low |= U64(0xC000000000000000); - return a; + return a; } /*---------------------------------------------------------------------------- @@ -106,9 +106,9 @@ INLINE floatx80 propagateFloatx80NaNOneArg(floatx80 a) INLINE void normalizeFloatx80Subnormal(UINT64 aSig, INT32 *zExpPtr, UINT64 *zSigPtr) { - int shiftCount = countLeadingZeros64(aSig); - *zSigPtr = aSig<<shiftCount; - *zExpPtr = 1 - shiftCount; + int shiftCount = countLeadingZeros64(aSig); + *zSigPtr = aSig<<shiftCount; + *zExpPtr = 1 - shiftCount; } @@ -119,7 +119,7 @@ INLINE void normalizeFloatx80Subnormal(UINT64 aSig, INT32 *zExpPtr, UINT64 *zSig INLINE int floatx80_is_nan(floatx80 a) { - return ((a.high & 0x7FFF) == 0x7FFF) && (INT64) (a.low<<1); + return ((a.high & 0x7FFF) == 0x7FFF) && (INT64) (a.low<<1); } /*---------------------------------------------------------------------------- @@ -130,38 +130,38 @@ INLINE int floatx80_is_nan(floatx80 a) static floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b) { - int aIsNaN = floatx80_is_nan(a); - int aIsSignalingNaN = floatx80_is_signaling_nan(a); - int bIsNaN = floatx80_is_nan(b); - int bIsSignalingNaN = floatx80_is_signaling_nan(b); - a.low |= U64(0xC000000000000000); - b.low |= U64(0xC000000000000000); - if (aIsSignalingNaN | bIsSignalingNaN) float_raise(float_flag_invalid); - if (aIsSignalingNaN) { - if (bIsSignalingNaN) goto returnLargerSignificand; - return bIsNaN ? b : a; - } - else if (aIsNaN) { - if (bIsSignalingNaN | ! bIsNaN) return a; - returnLargerSignificand: - if (a.low < b.low) return b; - if (b.low < a.low) return a; - return (a.high < b.high) ? a : b; - } - else { - return b; - } + int aIsNaN = floatx80_is_nan(a); + int aIsSignalingNaN = floatx80_is_signaling_nan(a); + int bIsNaN = floatx80_is_nan(b); + int bIsSignalingNaN = floatx80_is_signaling_nan(b); + a.low |= U64(0xC000000000000000); + b.low |= U64(0xC000000000000000); + if (aIsSignalingNaN | bIsSignalingNaN) float_raise(float_flag_invalid); + if (aIsSignalingNaN) { + if (bIsSignalingNaN) goto returnLargerSignificand; + return bIsNaN ? b : a; + } + else if (aIsNaN) { + if (bIsSignalingNaN | ! bIsNaN) return a; + returnLargerSignificand: + if (a.low < b.low) return b; + if (b.low < a.low) return a; + return (a.high < b.high) ? a : b; + } + else { + return b; + } } static const float128 float128_one = - packFloat_128(U64(0x3fff000000000000), U64(0x0000000000000000)); + packFloat_128(U64(0x3fff000000000000), U64(0x0000000000000000)); static const float128 float128_two = - packFloat_128(U64(0x4000000000000000), U64(0x0000000000000000)); + packFloat_128(U64(0x4000000000000000), U64(0x0000000000000000)); static const float128 float128_ln2inv2 = - packFloat_128(U64(0x400071547652b82f), U64(0xe1777d0ffda0d23a)); + packFloat_128(U64(0x400071547652b82f), U64(0xe1777d0ffda0d23a)); -#define SQRT2_HALF_SIG U64(0xb504f333f9de6484) +#define SQRT2_HALF_SIG U64(0xb504f333f9de6484) extern float128 OddPoly(float128 x, float128 *arr, unsigned n); @@ -169,15 +169,15 @@ extern float128 OddPoly(float128 x, float128 *arr, unsigned n); static float128 ln_arr[L2_ARR_SIZE] = { - PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 1 */ - PACK_FLOAT_128(0x3ffd555555555555, 0x5555555555555555), /* 3 */ - PACK_FLOAT_128(0x3ffc999999999999, 0x999999999999999a), /* 5 */ - PACK_FLOAT_128(0x3ffc249249249249, 0x2492492492492492), /* 7 */ - PACK_FLOAT_128(0x3ffbc71c71c71c71, 0xc71c71c71c71c71c), /* 9 */ - PACK_FLOAT_128(0x3ffb745d1745d174, 0x5d1745d1745d1746), /* 11 */ - PACK_FLOAT_128(0x3ffb3b13b13b13b1, 0x3b13b13b13b13b14), /* 13 */ - PACK_FLOAT_128(0x3ffb111111111111, 0x1111111111111111), /* 15 */ - PACK_FLOAT_128(0x3ffae1e1e1e1e1e1, 0xe1e1e1e1e1e1e1e2) /* 17 */ + PACK_FLOAT_128(0x3fff000000000000, 0x0000000000000000), /* 1 */ + PACK_FLOAT_128(0x3ffd555555555555, 0x5555555555555555), /* 3 */ + PACK_FLOAT_128(0x3ffc999999999999, 0x999999999999999a), /* 5 */ + PACK_FLOAT_128(0x3ffc249249249249, 0x2492492492492492), /* 7 */ + PACK_FLOAT_128(0x3ffbc71c71c71c71, 0xc71c71c71c71c71c), /* 9 */ + PACK_FLOAT_128(0x3ffb745d1745d174, 0x5d1745d1745d1746), /* 11 */ + PACK_FLOAT_128(0x3ffb3b13b13b13b1, 0x3b13b13b13b13b14), /* 13 */ + PACK_FLOAT_128(0x3ffb111111111111, 0x1111111111111111), /* 15 */ + PACK_FLOAT_128(0x3ffae1e1e1e1e1e1, 0xe1e1e1e1e1e1e1e2) /* 17 */ }; static float128 poly_ln(float128 x1) @@ -205,29 +205,29 @@ static float128 poly_ln(float128 x1) // 1-u // */ - return OddPoly(x1, ln_arr, L2_ARR_SIZE); + return OddPoly(x1, ln_arr, L2_ARR_SIZE); } /* required sqrt(2)/2 < x < sqrt(2) */ static float128 poly_l2(float128 x) { - /* using float128 for approximation */ - float128 x_p1 = float128_add(x, float128_one); - float128 x_m1 = float128_sub(x, float128_one); - x = float128_div(x_m1, x_p1); - x = poly_ln(x); - x = float128_mul(x, float128_ln2inv2); - return x; + /* using float128 for approximation */ + float128 x_p1 = float128_add(x, float128_one); + float128 x_m1 = float128_sub(x, float128_one); + x = float128_div(x_m1, x_p1); + x = poly_ln(x); + x = float128_mul(x, float128_ln2inv2); + return x; } static float128 poly_l2p1(float128 x) { - /* using float128 for approximation */ - float128 x_p2 = float128_add(x, float128_two); - x = float128_div(x, x_p2); - x = poly_ln(x); - x = float128_mul(x, float128_ln2inv2); - return x; + /* using float128 for approximation */ + float128 x_p2 = float128_add(x, float128_two); + x = float128_div(x, x_p2); + x = poly_ln(x); + x = float128_mul(x, float128_ln2inv2); + return x; } // ================================================= @@ -257,88 +257,88 @@ static float128 poly_l2p1(float128 x) static floatx80 fyl2x(floatx80 a, floatx80 b) { - UINT64 aSig = extractFloatx80Frac(a); - INT32 aExp = extractFloatx80Exp(a); - int aSign = extractFloatx80Sign(a); - UINT64 bSig = extractFloatx80Frac(b); - INT32 bExp = extractFloatx80Exp(b); - int bSign = extractFloatx80Sign(b); - - int zSign = bSign ^ 1; - - if (aExp == 0x7FFF) { - if ((UINT64) (aSig<<1) - || ((bExp == 0x7FFF) && (UINT64) (bSig<<1))) - { - return propagateFloatx80NaN(a, b); - } - if (aSign) - { + UINT64 aSig = extractFloatx80Frac(a); + INT32 aExp = extractFloatx80Exp(a); + int aSign = extractFloatx80Sign(a); + UINT64 bSig = extractFloatx80Frac(b); + INT32 bExp = extractFloatx80Exp(b); + int bSign = extractFloatx80Sign(b); + + int zSign = bSign ^ 1; + + if (aExp == 0x7FFF) { + if ((UINT64) (aSig<<1) + || ((bExp == 0x7FFF) && (UINT64) (bSig<<1))) + { + return propagateFloatx80NaN(a, b); + } + if (aSign) + { invalid: float_raise(float_flag_invalid); return floatx80_default_nan; - } - else { - if (bExp == 0) { - if (bSig == 0) goto invalid; - float_raise(float_flag_denormal); - } - return packFloatx80(bSign, 0x7FFF, U64(0x8000000000000000)); - } - } - if (bExp == 0x7FFF) - { - if ((UINT64) (bSig<<1)) return propagateFloatx80NaN(a, b); - if (aSign && (UINT64)(aExp | aSig)) goto invalid; - if (aSig && (aExp == 0)) - float_raise(float_flag_denormal); - if (aExp < 0x3FFF) { - return packFloatx80(zSign, 0x7FFF, U64(0x8000000000000000)); - } - if (aExp == 0x3FFF && ((UINT64) (aSig<<1) == 0)) goto invalid; - return packFloatx80(bSign, 0x7FFF, U64(0x8000000000000000)); - } - if (aExp == 0) { - if (aSig == 0) { - if ((bExp | bSig) == 0) goto invalid; - float_raise(float_flag_divbyzero); - return packFloatx80(zSign, 0x7FFF, U64(0x8000000000000000)); - } - if (aSign) goto invalid; - float_raise(float_flag_denormal); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - } - if (aSign) goto invalid; - if (bExp == 0) { - if (bSig == 0) { - if (aExp < 0x3FFF) return packFloatx80(zSign, 0, 0); - return packFloatx80(bSign, 0, 0); - } - float_raise(float_flag_denormal); - normalizeFloatx80Subnormal(bSig, &bExp, &bSig); - } - if (aExp == 0x3FFF && ((UINT64) (aSig<<1) == 0)) - return packFloatx80(bSign, 0, 0); - - float_raise(float_flag_inexact); - - int ExpDiff = aExp - 0x3FFF; - aExp = 0; - if (aSig >= SQRT2_HALF_SIG) { - ExpDiff++; - aExp--; - } - - /* ******************************** */ - /* using float128 for approximation */ - /* ******************************** */ - - UINT64 zSig0, zSig1; - shift128Right(aSig<<1, 0, 16, &zSig0, &zSig1); - float128 x = packFloat128(0, aExp+0x3FFF, zSig0, zSig1); - x = poly_l2(x); - x = float128_add(x, int64_to_float128((INT64) ExpDiff)); - return floatx80_mul(b, float128_to_floatx80(x)); + } + else { + if (bExp == 0) { + if (bSig == 0) goto invalid; + float_raise(float_flag_denormal); + } + return packFloatx80(bSign, 0x7FFF, U64(0x8000000000000000)); + } + } + if (bExp == 0x7FFF) + { + if ((UINT64) (bSig<<1)) return propagateFloatx80NaN(a, b); + if (aSign && (UINT64)(aExp | aSig)) goto invalid; + if (aSig && (aExp == 0)) + float_raise(float_flag_denormal); + if (aExp < 0x3FFF) { + return packFloatx80(zSign, 0x7FFF, U64(0x8000000000000000)); + } + if (aExp == 0x3FFF && ((UINT64) (aSig<<1) == 0)) goto invalid; + return packFloatx80(bSign, 0x7FFF, U64(0x8000000000000000)); + } + if (aExp == 0) { + if (aSig == 0) { + if ((bExp | bSig) == 0) goto invalid; + float_raise(float_flag_divbyzero); + return packFloatx80(zSign, 0x7FFF, U64(0x8000000000000000)); + } + if (aSign) goto invalid; + float_raise(float_flag_denormal); + normalizeFloatx80Subnormal(aSig, &aExp, &aSig); + } + if (aSign) goto invalid; + if (bExp == 0) { + if (bSig == 0) { + if (aExp < 0x3FFF) return packFloatx80(zSign, 0, 0); + return packFloatx80(bSign, 0, 0); + } + float_raise(float_flag_denormal); + normalizeFloatx80Subnormal(bSig, &bExp, &bSig); + } + if (aExp == 0x3FFF && ((UINT64) (aSig<<1) == 0)) + return packFloatx80(bSign, 0, 0); + + float_raise(float_flag_inexact); + + int ExpDiff = aExp - 0x3FFF; + aExp = 0; + if (aSig >= SQRT2_HALF_SIG) { + ExpDiff++; + aExp--; + } + + /* ******************************** */ + /* using float128 for approximation */ + /* ******************************** */ + + UINT64 zSig0, zSig1; + shift128Right(aSig<<1, 0, 16, &zSig0, &zSig1); + float128 x = packFloat128(0, aExp+0x3FFF, zSig0, zSig1); + x = poly_l2(x); + x = float128_add(x, int64_to_float128((INT64) ExpDiff)); + return floatx80_mul(b, float128_to_floatx80(x)); } // ================================================= @@ -368,123 +368,123 @@ invalid: floatx80 fyl2xp1(floatx80 a, floatx80 b) { - INT32 aExp, bExp; - UINT64 aSig, bSig, zSig0, zSig1, zSig2; - int aSign, bSign; - - aSig = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); - bSig = extractFloatx80Frac(b); - bExp = extractFloatx80Exp(b); - bSign = extractFloatx80Sign(b); - int zSign = aSign ^ bSign; - - if (aExp == 0x7FFF) { - if ((UINT64) (aSig<<1) - || ((bExp == 0x7FFF) && (UINT64) (bSig<<1))) - { - return propagateFloatx80NaN(a, b); - } - if (aSign) - { + INT32 aExp, bExp; + UINT64 aSig, bSig, zSig0, zSig1, zSig2; + int aSign, bSign; + + aSig = extractFloatx80Frac(a); + aExp = extractFloatx80Exp(a); + aSign = extractFloatx80Sign(a); + bSig = extractFloatx80Frac(b); + bExp = extractFloatx80Exp(b); + bSign = extractFloatx80Sign(b); + int zSign = aSign ^ bSign; + + if (aExp == 0x7FFF) { + if ((UINT64) (aSig<<1) + || ((bExp == 0x7FFF) && (UINT64) (bSig<<1))) + { + return propagateFloatx80NaN(a, b); + } + if (aSign) + { invalid: float_raise(float_flag_invalid); return floatx80_default_nan; - } - else { - if (bExp == 0) { - if (bSig == 0) goto invalid; - float_raise(float_flag_denormal); - } - return packFloatx80(bSign, 0x7FFF, U64(0x8000000000000000)); - } - } - if (bExp == 0x7FFF) - { - if ((UINT64) (bSig<<1)) - return propagateFloatx80NaN(a, b); - - if (aExp == 0) { - if (aSig == 0) goto invalid; - float_raise(float_flag_denormal); - } - - return packFloatx80(zSign, 0x7FFF, U64(0x8000000000000000)); - } - if (aExp == 0) { - if (aSig == 0) { - if (bSig && (bExp == 0)) float_raise(float_flag_denormal); - return packFloatx80(zSign, 0, 0); - } - float_raise(float_flag_denormal); - normalizeFloatx80Subnormal(aSig, &aExp, &aSig); - } - if (bExp == 0) { - if (bSig == 0) return packFloatx80(zSign, 0, 0); - float_raise(float_flag_denormal); - normalizeFloatx80Subnormal(bSig, &bExp, &bSig); - } - - float_raise(float_flag_inexact); - - if (aSign && aExp >= 0x3FFF) - return a; - - if (aExp >= 0x3FFC) // big argument - { - return fyl2x(floatx80_add(a, floatx80_one), b); - } - - // handle tiny argument - if (aExp < EXP_BIAS-70) - { - // first order approximation, return (a*b)/ln(2) - INT32 zExp = aExp + FLOAT_LN2INV_EXP - 0x3FFE; + } + else { + if (bExp == 0) { + if (bSig == 0) goto invalid; + float_raise(float_flag_denormal); + } + return packFloatx80(bSign, 0x7FFF, U64(0x8000000000000000)); + } + } + if (bExp == 0x7FFF) + { + if ((UINT64) (bSig<<1)) + return propagateFloatx80NaN(a, b); + + if (aExp == 0) { + if (aSig == 0) goto invalid; + float_raise(float_flag_denormal); + } + + return packFloatx80(zSign, 0x7FFF, U64(0x8000000000000000)); + } + if (aExp == 0) { + if (aSig == 0) { + if (bSig && (bExp == 0)) float_raise(float_flag_denormal); + return packFloatx80(zSign, 0, 0); + } + float_raise(float_flag_denormal); + normalizeFloatx80Subnormal(aSig, &aExp, &aSig); + } + if (bExp == 0) { + if (bSig == 0) return packFloatx80(zSign, 0, 0); + float_raise(float_flag_denormal); + normalizeFloatx80Subnormal(bSig, &bExp, &bSig); + } + + float_raise(float_flag_inexact); + + if (aSign && aExp >= 0x3FFF) + return a; + + if (aExp >= 0x3FFC) // big argument + { + return fyl2x(floatx80_add(a, floatx80_one), b); + } + + // handle tiny argument + if (aExp < EXP_BIAS-70) + { + // first order approximation, return (a*b)/ln(2) + INT32 zExp = aExp + FLOAT_LN2INV_EXP - 0x3FFE; mul128By64To192(FLOAT_LN2INV_HI, FLOAT_LN2INV_LO, aSig, &zSig0, &zSig1, &zSig2); - if (0 < (INT64) zSig0) { - shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1); - --zExp; - } + if (0 < (INT64) zSig0) { + shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1); + --zExp; + } - zExp = zExp + bExp - 0x3FFE; + zExp = zExp + bExp - 0x3FFE; mul128By64To192(zSig0, zSig1, bSig, &zSig0, &zSig1, &zSig2); - if (0 < (INT64) zSig0) { - shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1); - --zExp; - } - - return - roundAndPackFloatx80(80, aSign ^ bSign, zExp, zSig0, zSig1); - } - - /* ******************************** */ - /* using float128 for approximation */ - /* ******************************** */ - - shift128Right(aSig<<1, 0, 16, &zSig0, &zSig1); - float128 x = packFloat128(aSign, aExp, zSig0, zSig1); - x = poly_l2p1(x); - return floatx80_mul(b, float128_to_floatx80(x)); + if (0 < (INT64) zSig0) { + shortShift128Left(zSig0, zSig1, 1, &zSig0, &zSig1); + --zExp; + } + + return + roundAndPackFloatx80(80, aSign ^ bSign, zExp, zSig0, zSig1); + } + + /* ******************************** */ + /* using float128 for approximation */ + /* ******************************** */ + + shift128Right(aSig<<1, 0, 16, &zSig0, &zSig1); + float128 x = packFloat128(aSign, aExp, zSig0, zSig1); + x = poly_l2p1(x); + return floatx80_mul(b, float128_to_floatx80(x)); } floatx80 floatx80_flognp1(floatx80 a) { - return fyl2xp1(a, floatx80_ln_2); + return fyl2xp1(a, floatx80_ln_2); } floatx80 floatx80_flogn(floatx80 a) { - return fyl2x(a, floatx80_ln_2); + return fyl2x(a, floatx80_ln_2); } floatx80 floatx80_flog2(floatx80 a) { - return fyl2x(a, floatx80_one); + return fyl2x(a, floatx80_one); } floatx80 floatx80_flog10(floatx80 a) { - return fyl2x(a, floatx80_log10_2); + return fyl2x(a, floatx80_log10_2); } |