Hide IEEE flags and FloatingPointControl for soft-float targets

This commit is contained in:
Martin Kinkelin 2018-05-22 21:22:03 +02:00 committed by Denis Feklushkin
parent 45b2b0d1ad
commit 4d98ca2ba8

View file

@ -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.