diff options
author | Iain Buclaw <ibuclaw@gcc.gnu.org> | 2019-01-26 13:41:26 +0000 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gcc.gnu.org> | 2019-01-26 13:41:26 +0000 |
commit | 685ae5b8717e08e0d7b5f147ed4c6bfeff10c4f6 (patch) | |
tree | b896cf6f236550f22bc5157e858c6714b7411e47 /libphobos/src/std/math.d | |
parent | 8f915edbe104731838ef8c6821829a93faf5d063 (diff) | |
download | gcc-685ae5b8717e08e0d7b5f147ed4c6bfeff10c4f6.zip gcc-685ae5b8717e08e0d7b5f147ed4c6bfeff10c4f6.tar.gz gcc-685ae5b8717e08e0d7b5f147ed4c6bfeff10c4f6.tar.bz2 |
libphobos: Merge phobos and druntime with upstream.
Commits merged from druntime.
Fix struct tls_index definition on x32
https://github.com/dlang/druntime/pull/2354
Update SectionGroup signatures to match on all targets
https://github.com/dlang/druntime/pull/2401
Fix issue 19128 - argument to alloca may be too large
https://github.com/dlang/druntime/pull/2409
Define some common filesystem limits in core.stdc.limits
https://github.com/dlang/druntime/pull/2460
Use version Darwin instead of OSX in core.sys.posix.aio
https://github.com/dlang/druntime/pull/2470
Commits merged from phobos.
Don't run HardFloat tests on SoftFloat systems
https://github.com/dlang/phobos/pull/5358
Remove reliance on stdin, stdout, stderr being aliasable
https://github.com/dlang/phobos/pull/5718
Solaris: add import clock_gettime to currStdTime
https://github.com/dlang/phobos/pull/5807
Don't print debug messages when building unittests
https://github.com/dlang/phobos/pull/6827
Add HPPA support to phobos
Fixes https://gcc.gnu.org/PR89054
https://github.com/dlang/phobos/pull/6836
From-SVN: r268293
Diffstat (limited to 'libphobos/src/std/math.d')
-rw-r--r-- | libphobos/src/std/math.d | 179 |
1 files changed, 102 insertions, 77 deletions
diff --git a/libphobos/src/std/math.d b/libphobos/src/std/math.d index 7bb4d7c..e98e746 100644 --- a/libphobos/src/std/math.d +++ b/libphobos/src/std/math.d @@ -160,6 +160,8 @@ version (MIPS32) version = MIPS_Any; version (MIPS64) version = MIPS_Any; version (AArch64) version = ARM_Any; version (ARM) version = ARM_Any; +version (SPARC) version = SPARC_Any; +version (SPARC64) version = SPARC_Any; version (D_InlineAsm_X86) { @@ -380,15 +382,22 @@ template floatTraits(T) enum ushort EXPMASK = 0x7FF0; enum ushort EXPSHIFT = 4; enum realFormat = RealFormat.ibmExtended; - // the exponent byte is not unique + + // For IBM doubledouble the larger magnitude double comes first. + // It's really a double[2] and arrays don't index differently + // between little and big-endian targets. + enum DOUBLEPAIR_MSB = 0; + enum DOUBLEPAIR_LSB = 1; + + // The exponent/sign byte is for most significant part. version (LittleEndian) { - enum EXPPOS_SHORT = 7; // [3] is also an exp short - enum SIGNPOS_BYTE = 15; + enum EXPPOS_SHORT = 3; + enum SIGNPOS_BYTE = 7; } else { - enum EXPPOS_SHORT = 0; // [4] is also an exp short + enum EXPPOS_SHORT = 0; enum SIGNPOS_BYTE = 0; } } @@ -420,19 +429,20 @@ T floorImpl(T)(const T x) @trusted pure nothrow @nogc { T rv; ushort[T.sizeof/2] vu; + + // Other kinds of extractors for real formats. + static if (F.realFormat == RealFormat.ieeeSingle) + int vi; } floatBits y = void; y.rv = x; // Find the exponent (power of 2) + // Do this by shifting the raw value so that the exponent lies in the low bits, + // then mask out the sign bit, and subtract the bias. static if (F.realFormat == RealFormat.ieeeSingle) { - int exp = ((y.vu[F.EXPPOS_SHORT] >> 7) & 0xff) - 0x7f; - - version (LittleEndian) - int pos = 0; - else - int pos = 3; + int exp = ((y.vi >> (T.mant_dig - 1)) & 0xff) - 0x7f; } else static if (F.realFormat == RealFormat.ieeeDouble) { @@ -472,24 +482,43 @@ T floorImpl(T)(const T x) @trusted pure nothrow @nogc return 0.0; } - exp = (T.mant_dig - 1) - exp; - - // Zero 16 bits at a time. - while (exp >= 16) + static if (F.realFormat == RealFormat.ieeeSingle) { - version (LittleEndian) - y.vu[pos++] = 0; - else - y.vu[pos--] = 0; - exp -= 16; + if (exp < (T.mant_dig - 1)) + { + // Clear all bits representing the fraction part. + const uint fraction_mask = F.MANTISSAMASK_INT >> exp; + + if ((y.vi & fraction_mask) != 0) + { + // If 'x' is negative, then first substract 1.0 from the value. + if (y.vi < 0) + y.vi += 0x00800000 >> exp; + y.vi &= ~fraction_mask; + } + } } + else + { + exp = (T.mant_dig - 1) - exp; + + // Zero 16 bits at a time. + while (exp >= 16) + { + version (LittleEndian) + y.vu[pos++] = 0; + else + y.vu[pos--] = 0; + exp -= 16; + } - // Clear the remaining bits. - if (exp > 0) - y.vu[pos] &= 0xffff ^ ((1 << exp) - 1); + // Clear the remaining bits. + if (exp > 0) + y.vu[pos] &= 0xffff ^ ((1 << exp) - 1); - if ((x < 0.0) && (x != y.rv)) - y.rv -= 1.0; + if ((x < 0.0) && (x != y.rv)) + y.rv -= 1.0; + } return y.rv; } @@ -4870,10 +4899,7 @@ public: /// version (GNU) { - unittest - { - pragma(msg, "ieeeFlags test disabled, see LDC Issue #888"); - } + // ieeeFlags test disabled, see LDC Issue #888. } else @system unittest @@ -4904,10 +4930,7 @@ else version (GNU) { - unittest - { - pragma(msg, "ieeeFlags test disabled, see LDC Issue #888"); - } + // ieeeFlags test disabled, see LDC Issue #888. } else @system unittest @@ -4960,10 +4983,6 @@ version (X86_Any) { version = IeeeFlagsSupport; } -version (X86_Any) -{ - version = IeeeFlagsSupport; -} else version (PPC_Any) { version = IeeeFlagsSupport; @@ -5132,37 +5151,52 @@ struct FloatingPointControl | inexactException | subnormalException, } } - else version (MIPS_Any) + else version (PPC_Any) { enum : ExceptionMask { - inexactException = 0x0080, - underflowException = 0x0100, - overflowException = 0x0200, - divByZeroException = 0x0400, - invalidException = 0x0800, + inexactException = 0x0008, + divByZeroException = 0x0010, + underflowException = 0x0020, + overflowException = 0x0040, + invalidException = 0x0080, severeExceptions = overflowException | divByZeroException | invalidException, allExceptions = severeExceptions | underflowException | inexactException, } } - else version (PPC_Any) + else version (HPPA) { enum : ExceptionMask { - inexactException = 0x08, - divByZeroException = 0x10, - underflowException = 0x20, - overflowException = 0x40, - invalidException = 0x80, + inexactException = 0x01, + underflowException = 0x02, + overflowException = 0x04, + divByZeroException = 0x08, + invalidException = 0x10, severeExceptions = overflowException | divByZeroException | invalidException, allExceptions = severeExceptions | underflowException | inexactException, } } - else version (SPARC64) + else version (MIPS_Any) + { + enum : ExceptionMask + { + inexactException = 0x0080, + divByZeroException = 0x0400, + overflowException = 0x0200, + underflowException = 0x0100, + invalidException = 0x0800, + severeExceptions = overflowException | divByZeroException + | invalidException, + allExceptions = severeExceptions | underflowException + | inexactException, + } + } + else version (SPARC_Any) { enum : ExceptionMask { @@ -5284,6 +5318,10 @@ private: { alias ControlState = uint; } + else version (HPPA) + { + alias ControlState = uint; + } else version (PPC_Any) { alias ControlState = uint; @@ -5292,7 +5330,7 @@ private: { alias ControlState = uint; } - else version (SPARC64) + else version (SPARC_Any) { alias ControlState = ulong; } @@ -5480,13 +5518,8 @@ private: } } -@system unittest +version (D_HardFloat) @system unittest { - // GCC floating point emulation doesn't allow changing - // rounding modes, getting error bits etc - version (GNU) version (D_SoftFloat) - return; - void ensureDefaults() { assert(FloatingPointControl.rounding @@ -5500,15 +5533,12 @@ private: } ensureDefaults(); - version (D_HardFloat) { - { - FloatingPointControl ctrl; - ctrl.rounding = FloatingPointControl.roundDown; - assert(FloatingPointControl.rounding == FloatingPointControl.roundDown); - } - ensureDefaults(); + FloatingPointControl ctrl; + ctrl.rounding = FloatingPointControl.roundDown; + assert(FloatingPointControl.rounding == FloatingPointControl.roundDown); } + ensureDefaults(); if (FloatingPointControl.hasExceptionTraps) { @@ -5525,7 +5555,7 @@ private: ensureDefaults(); } -@system unittest // rounding +version (D_HardFloat) @system unittest // rounding { import std.meta : AliasSeq; @@ -6662,19 +6692,14 @@ if (isFloatingPoint!(F) && isIntegral!(G)) assert(pow(x, neg1) == 1 / x); - version (X86_64) - { - pragma(msg, "test disabled on x86_64, see bug 5628"); - } - else version (ARM) - { - pragma(msg, "test disabled on ARM, see bug 5628"); - } - else version (GNU) - { - pragma(msg, "test disabled on GNU, see bug 5628"); - } - else + // Test disabled on most targets. + // See https://issues.dlang.org/show_bug.cgi?id=5628 + version (X86_64) enum BUG5628 = false; + else version (ARM) enum BUG5628 = false; + else version (GNU) enum BUG5628 = false; + else enum BUG5628 = true; + + static if (BUG5628) { assert(pow(xd, neg2) == 1 / (x * x)); assert(pow(xf, neg8) == 1 / ((x * x) * (x * x) * (x * x) * (x * x))); |