diff --git a/std/math.d b/std/math.d index c19c0ac14..0a25cc631 100644 --- a/std/math.d +++ b/std/math.d @@ -133,11 +133,6 @@ static import core.stdc.fenv; import std.traits : CommonType, isFloatingPoint, isIntegral, isNumeric, isSigned, isUnsigned, Largest, Unqual; -version (LDC) -{ - import ldc.intrinsics; -} - version (DigitalMars) { version = INLINE_YL2X; // x87 has opcodes for these @@ -186,6 +181,16 @@ else version (X86) private alias haveSSE = core.cpuid.sse; } +version (D_SoftFloat) +{ + // Some soft float architectures may support IEEE floating flags. + // Feel free to add exclusion for them. +} +else version (X86_Any) version = IeeeFlagsSupport; +else version (PPC_Any) version = IeeeFlagsSupport; +else version (MIPS_Any) version = IeeeFlagsSupport; +else version (ARM_Any) version = IeeeFlagsSupport; + version (StdUnittest) private { static if (real.sizeof > double.sizeof) @@ -2340,7 +2345,7 @@ private T expImpl(T)(T x) @safe pure nothrow @nogc return x; } -version (InlineAsm_X86_Any) @safe @nogc nothrow unittest +version (IeeeFlagsSupport) @safe @nogc nothrow unittest { FloatingPointControl ctrl; if (FloatingPointControl.hasExceptionTraps) @@ -5204,7 +5209,7 @@ float rint(float x) @safe pure nothrow @nogc { return rint(cast(real) x); } /// @safe unittest { - version (InlineAsm_X86_Any) + version (IeeeFlagsSupport) { resetIeeeFlags(); assert(rint(0.4) == 0); @@ -5627,6 +5632,10 @@ real remquo(real x, real y, out int n) @trusted nothrow @nogc /// ditto } } + +version (IeeeFlagsSupport) +{ + /** IEEE exception status flags ('sticky bits') These flags indicate that an exceptional floating-point condition has occurred. @@ -5740,47 +5749,46 @@ private: assert(0, "Not yet supported"); } } + public: version (IeeeFlagsSupport) { + /** + * The result cannot be represented exactly, so rounding occurred. + * Example: `x = sin(0.1);` + */ + @property bool inexact() @safe const { return (flags & INEXACT_MASK) != 0; } - /** - * The result cannot be represented exactly, so rounding occurred. - * Example: `x = sin(0.1);` - */ - @property bool inexact() @safe const { return (flags & INEXACT_MASK) != 0; } + /** + * A zero was generated by underflow + * Example: `x = real.min*real.epsilon/2;` + */ + @property bool underflow() @safe const { return (flags & UNDERFLOW_MASK) != 0; } - /** - * A zero was generated by underflow - * Example: `x = real.min*real.epsilon/2;` - */ - @property bool underflow() @safe const { return (flags & UNDERFLOW_MASK) != 0; } + /** + * An infinity was generated by overflow + * Example: `x = real.max*2;` + */ + @property bool overflow() @safe const { return (flags & OVERFLOW_MASK) != 0; } - /** - * An infinity was generated by overflow - * Example: `x = real.max*2;` - */ - @property bool overflow() @safe const { return (flags & OVERFLOW_MASK) != 0; } + /** + * An infinity was generated by division by zero + * Example: `x = 3/0.0;` + */ + @property bool divByZero() @safe const { return (flags & DIVBYZERO_MASK) != 0; } - /** - * An infinity was generated by division by zero - * Example: `x = 3/0.0;` - */ - @property bool divByZero() @safe const { return (flags & DIVBYZERO_MASK) != 0; } - - /** - * A machine NaN was generated. - * Example: `x = real.infinity * 0.0;` - */ - @property bool invalid() @safe const { return (flags & INVALID_MASK) != 0; } - - } + /** + * A machine NaN was generated. + * Example: `x = real.infinity * 0.0;` + */ + @property bool invalid() @safe const { return (flags & INVALID_MASK) != 0; } + } } /// @safe unittest { - version (InlineAsm_X86_Any) + version (IeeeFlagsSupport) { static void func() { int a = 10 * 10; @@ -5809,7 +5817,7 @@ public: } } -version (InlineAsm_X86_Any) @safe unittest +version (IeeeFlagsSupport) @safe unittest { import std.meta : AliasSeq; @@ -5855,27 +5863,6 @@ version (InlineAsm_X86_Any) @safe unittest }} } -version (X86_Any) -{ - version = IeeeFlagsSupport; -} -else version (PPC_Any) -{ - version = IeeeFlagsSupport; -} -else version (RISCV_Any) -{ - version = IeeeFlagsSupport; -} -else version (MIPS_Any) -{ - version = IeeeFlagsSupport; -} -else version (ARM_Any) -{ - version = IeeeFlagsSupport; -} - /// Set all of the floating-point status flags to false. void resetIeeeFlags() @trusted nothrow @nogc { @@ -5885,7 +5872,7 @@ void resetIeeeFlags() @trusted nothrow @nogc /// @safe unittest { - version (InlineAsm_X86_Any) + version (IeeeFlagsSupport) { pragma(inline, false) static void blockopt(ref real x) {} resetIeeeFlags(); @@ -5910,7 +5897,7 @@ void resetIeeeFlags() @trusted nothrow @nogc /// @safe nothrow unittest { - version (InlineAsm_X86_Any) + version (IeeeFlagsSupport) { pragma(inline, false) static void blockopt(ref real x) {} resetIeeeFlags(); @@ -5928,6 +5915,12 @@ void resetIeeeFlags() @trusted nothrow @nogc } } +} // IeeeFlagsSupport + + +version (D_HardFloat) +{ + /** Control the Floating point hardware Change the IEEE754 floating-point rounding mode and the floating-point @@ -6319,7 +6312,10 @@ private: // Clear all pending exceptions static void clearExceptions() @safe { - resetIeeeFlags(); + version (IeeeFlagsSupport) + resetIeeeFlags(); + else + static assert(false, "Not implemented for this architecture"); } // Read from the control register @@ -6388,7 +6384,7 @@ private: /// @safe unittest { - version (InlineAsm_X86_Any) + version (IeeeFlagsSupport) { FloatingPointControl fpctrl; @@ -6403,7 +6399,7 @@ private: } } -version (InlineAsm_X86_Any) @safe unittest +version (IeeeFlagsSupport) @safe unittest { void ensureDefaults() { @@ -6440,7 +6436,7 @@ version (InlineAsm_X86_Any) @safe unittest ensureDefaults(); } -version (InlineAsm_X86_Any) @safe unittest // rounding +version (IeeeFlagsSupport) @safe unittest // rounding { import std.meta : AliasSeq; @@ -6495,6 +6491,8 @@ version (InlineAsm_X86_Any) @safe unittest // rounding }} } +} // D_HardFloat + /********************************* * Determines if $(D_PARAM x) is NaN.