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)
{
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;
}
}
{
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)
{
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;
}
///
version (GNU)
{
- unittest
- {
- pragma(msg, "ieeeFlags test disabled, see LDC Issue #888");
- }
+ // ieeeFlags test disabled, see LDC Issue #888.
}
else
@system unittest
version (GNU)
{
- unittest
- {
- pragma(msg, "ieeeFlags test disabled, see LDC Issue #888");
- }
+ // ieeeFlags test disabled, see LDC Issue #888.
}
else
@system unittest
}
}
-version (X86_Any)
-{
- version = IeeeFlagsSupport;
-}
version (X86_Any)
{
version = IeeeFlagsSupport;
| 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
{
{
alias ControlState = uint;
}
+ else version (HPPA)
+ {
+ alias ControlState = uint;
+ }
else version (PPC_Any)
{
alias ControlState = uint;
{
alias ControlState = uint;
}
- else version (SPARC64)
+ else version (SPARC_Any)
{
alias ControlState = ulong;
}
}
}
-@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
}
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)
{
ensureDefaults();
}
-@system unittest // rounding
+version (D_HardFloat) @system unittest // rounding
{
import std.meta : AliasSeq;
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)));