Skip to content
This repository was archived by the owner on Jun 20, 2019. It is now read-only.

Commit ae0cf9b

Browse files
authored
Merge pull request #582 from jpf91/backport
Various std.math backports for aarch64
2 parents e887689 + 47028c7 commit ae0cf9b

File tree

1 file changed

+51
-98
lines changed

1 file changed

+51
-98
lines changed

libphobos/src/std/math.d

Lines changed: 51 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ version (Win64)
139139

140140
static import core.math;
141141
static import core.stdc.math;
142+
static import core.stdc.fenv;
142143
import std.traits; // CommonType, isFloatingPoint, isIntegral, isSigned, isUnsigned, Largest, Unqual
143144

144145
version(LDC)
@@ -4508,7 +4509,7 @@ real round(real x) @trusted nothrow @nogc
45084509
{
45094510
auto old = FloatingPointControl.getControlState();
45104511
FloatingPointControl.setControlState(
4511-
(old & ~FloatingPointControl.ROUNDING_MASK) | FloatingPointControl.roundToZero
4512+
(old & ~FloatingPointControl.roundingMask) | FloatingPointControl.roundToZero
45124513
);
45134514
x = rint((x >= 0) ? x + 0.5 : x - 0.5);
45144515
FloatingPointControl.setControlState(old);
@@ -4646,9 +4647,13 @@ struct IeeeFlags
46464647
private:
46474648
// The x87 FPU status register is 16 bits.
46484649
// The Pentium SSE2 status register is 32 bits.
4650+
// The ARM and PowerPC FPSCR is a 32-bit register.
4651+
// The SPARC FSR is a 32bit register (64 bits for SPARC 7 & 8, but high bits are uninteresting).
46494652
uint flags;
4650-
version (X86_Any)
4653+
4654+
version (CRuntime_Microsoft)
46514655
{
4656+
// Microsoft uses hardware-incompatible custom constants in fenv.h (core.stdc.fenv).
46524657
// Applies to both x87 status word (16 bits) and SSE2 status word(32 bits).
46534658
enum : int
46544659
{
@@ -4663,45 +4668,19 @@ private:
46634668
// Don't bother about subnormals, they are not supported on most CPUs.
46644669
// SUBNORMAL_MASK = 0x02;
46654670
}
4666-
else version (PPC_Any)
4667-
{
4668-
// PowerPC FPSCR is a 32-bit register.
4669-
enum : int
4670-
{
4671-
INEXACT_MASK = 0x02000000,
4672-
DIVBYZERO_MASK = 0x04000000,
4673-
UNDERFLOW_MASK = 0x08000000,
4674-
OVERFLOW_MASK = 0x10000000,
4675-
INVALID_MASK = 0x20000000 // Summary as PowerPC has five types of invalid exceptions.
4676-
}
4677-
}
4678-
else version (ARM)
4679-
{
4680-
// ARM FPSCR is a 32bit register
4681-
enum : int
4682-
{
4683-
INEXACT_MASK = 0x10,
4684-
UNDERFLOW_MASK = 0x08,
4685-
OVERFLOW_MASK = 0x04,
4686-
DIVBYZERO_MASK = 0x02,
4687-
INVALID_MASK = 0x01
4688-
}
4689-
}
4690-
else version(SPARC)
4671+
else
46914672
{
4692-
// SPARC FSR is a 32bit register
4693-
//(64 bits for Sparc 7 & 8, but high 32 bits are uninteresting).
46944673
enum : int
46954674
{
4696-
INEXACT_MASK = 0x020,
4697-
UNDERFLOW_MASK = 0x080,
4698-
OVERFLOW_MASK = 0x100,
4699-
DIVBYZERO_MASK = 0x040,
4700-
INVALID_MASK = 0x200
4675+
INEXACT_MASK = core.stdc.fenv.FE_INEXACT,
4676+
UNDERFLOW_MASK = core.stdc.fenv.FE_UNDERFLOW,
4677+
OVERFLOW_MASK = core.stdc.fenv.FE_OVERFLOW,
4678+
DIVBYZERO_MASK = core.stdc.fenv.FE_DIVBYZERO,
4679+
INVALID_MASK = core.stdc.fenv.FE_INVALID,
4680+
EXCEPTIONS_MASK = core.stdc.fenv.FE_ALL_EXCEPT,
47014681
}
47024682
}
4703-
else
4704-
static assert(0, "Not implemented");
4683+
47054684
private:
47064685
static uint getIeeeFlags()
47074686
{
@@ -5058,55 +5037,53 @@ struct FloatingPointControl
50585037
{
50595038
/** IEEE rounding modes.
50605039
* The default mode is roundToNearest.
5040+
*
5041+
* roundingMask = A mask of all rounding modes.
50615042
*/
50625043
roundToNearest,
50635044
roundDown, /// ditto
50645045
roundUp, /// ditto
5065-
roundToZero /// ditto
5066-
}
5067-
}
5068-
else version(ARM)
5069-
{
5070-
enum : RoundingMode
5071-
{
5072-
roundToNearest = 0x000000,
5073-
roundDown = 0x800000,
5074-
roundUp = 0x400000,
5075-
roundToZero = 0xC00000
5046+
roundToZero, /// ditto
5047+
roundingMask, /// ditto
50765048
}
50775049
}
5078-
else version(PPC_Any)
5050+
else version (CRuntime_Microsoft)
50795051
{
5052+
// Microsoft uses hardware-incompatible custom constants in fenv.h (core.stdc.fenv).
50805053
enum : RoundingMode
50815054
{
5082-
roundToNearest = 0x00000000,
5083-
roundDown = 0x00000003,
5084-
roundUp = 0x00000002,
5085-
roundToZero = 0x00000001
5055+
roundToNearest = 0x0000,
5056+
roundDown = 0x0400,
5057+
roundUp = 0x0800,
5058+
roundToZero = 0x0C00,
5059+
roundingMask = roundToNearest | roundDown
5060+
| roundUp | roundToZero,
50865061
}
50875062
}
50885063
else
50895064
{
50905065
enum : RoundingMode
50915066
{
5092-
roundToNearest = 0x0000,
5093-
roundDown = 0x0400,
5094-
roundUp = 0x0800,
5095-
roundToZero = 0x0C00
5067+
roundToNearest = core.stdc.fenv.FE_TONEAREST,
5068+
roundDown = core.stdc.fenv.FE_DOWNWARD,
5069+
roundUp = core.stdc.fenv.FE_UPWARD,
5070+
roundToZero = core.stdc.fenv.FE_TOWARDZERO,
5071+
roundingMask = roundToNearest | roundDown
5072+
| roundUp | roundToZero,
50965073
}
50975074
}
50985075

50995076
//// Change the floating-point hardware rounding mode
51005077
@property void rounding(RoundingMode newMode) @nogc
51015078
{
51025079
initialize();
5103-
setControlState((getControlState() & (-1 - ROUNDING_MASK)) | (newMode & ROUNDING_MASK));
5080+
setControlState(cast(ushort)((getControlState() & (-1 - roundingMask)) | (newMode & roundingMask)));
51045081
}
51055082

51065083
/// Returns: the currently active rounding mode
51075084
@property static RoundingMode rounding() @nogc
51085085
{
5109-
return cast(RoundingMode)(getControlState() & ROUNDING_MASK);
5086+
return cast(RoundingMode)(getControlState() & roundingMask);
51105087
}
51115088

51125089
version(StdDdoc)
@@ -5177,30 +5154,6 @@ struct FloatingPointControl
51775154
}
51785155
}
51795156

5180-
private:
5181-
version(ARM)
5182-
{
5183-
enum uint EXCEPTION_MASK = 0x9F00;
5184-
enum uint ROUNDING_MASK = 0xC00000;
5185-
}
5186-
else version(PPC_Any)
5187-
{
5188-
enum uint EXCEPTION_MASK = 0x00F8;
5189-
enum uint ROUNDING_MASK = 0x0003;
5190-
}
5191-
else version(X86)
5192-
{
5193-
enum ushort EXCEPTION_MASK = 0x3F;
5194-
enum ushort ROUNDING_MASK = 0xC00;
5195-
}
5196-
else version(X86_64)
5197-
{
5198-
enum ushort EXCEPTION_MASK = 0x3F;
5199-
enum ushort ROUNDING_MASK = 0xC00;
5200-
}
5201-
else
5202-
static assert(false, "Architecture not supported");
5203-
52045157
public:
52055158
/// Returns: true if the current FPU supports exception trapping
52065159
@property static bool hasExceptionTraps() @safe nothrow @nogc
@@ -5214,8 +5167,8 @@ public:
52145167
auto oldState = getControlState();
52155168
// If exceptions are not supported, we set the bit but read it back as zero
52165169
// https://sourceware.org/ml/libc-ports/2012-06/msg00091.html
5217-
setControlState(oldState | (divByZeroException & EXCEPTION_MASK));
5218-
immutable result = (getControlState() & EXCEPTION_MASK) != 0;
5170+
setControlState(oldState | (divByZeroException & allExceptions));
5171+
immutable result = (getControlState() & allExceptions) != 0;
52195172
setControlState(oldState);
52205173
return result;
52215174
}
@@ -5229,9 +5182,9 @@ public:
52295182
assert(hasExceptionTraps);
52305183
initialize();
52315184
version(X86_Any)
5232-
setControlState(getControlState() & ~(exceptions & EXCEPTION_MASK));
5185+
setControlState(getControlState() & ~(exceptions & allExceptions));
52335186
else
5234-
setControlState(getControlState() | (exceptions & EXCEPTION_MASK));
5187+
setControlState(getControlState() | (exceptions & allExceptions));
52355188
}
52365189

52375190
/// Disable (mask) specific hardware exceptions. Multiple exceptions may be ORed together.
@@ -5240,19 +5193,19 @@ public:
52405193
assert(hasExceptionTraps);
52415194
initialize();
52425195
version(X86_Any)
5243-
setControlState(getControlState() | (exceptions & EXCEPTION_MASK));
5196+
setControlState(getControlState() | (exceptions & allExceptions));
52445197
else
5245-
setControlState(getControlState() & ~(exceptions & EXCEPTION_MASK));
5198+
setControlState(getControlState() & ~(exceptions & allExceptions));
52465199
}
52475200

52485201
/// Returns: the exceptions which are currently enabled (unmasked)
52495202
@property static uint enabledExceptions() @nogc
52505203
{
52515204
assert(hasExceptionTraps);
52525205
version(X86_Any)
5253-
return (getControlState() & EXCEPTION_MASK) ^ EXCEPTION_MASK;
5206+
return (getControlState() & allExceptions) ^ allExceptions;
52545207
else
5255-
return (getControlState() & EXCEPTION_MASK);
5208+
return (getControlState() & allExceptions);
52565209
}
52575210

52585211
/// Clear all pending exceptions, then restore the original exception state and rounding mode.
@@ -5377,15 +5330,15 @@ private:
53775330

53785331
/* In the FPU control register, rounding mode is in bits 10 and
53795332
11. In MXCSR it's in bits 13 and 14. */
5380-
enum ROUNDING_MASK_SSE = ROUNDING_MASK << 3;
5381-
immutable newRoundingModeSSE = (newState & ROUNDING_MASK) << 3;
5333+
enum ROUNDING_MASK_SSE = roundingMask << 3;
5334+
immutable newRoundingModeSSE = (newState & roundingMask) << 3;
53825335
mxcsr &= ~ROUNDING_MASK_SSE; // delete old rounding mode
53835336
mxcsr |= newRoundingModeSSE; // write new rounding mode
53845337

53855338
/* In the FPU control register, masks are bits 0 through 5.
53865339
In MXCSR they're 7 through 12. */
5387-
enum EXCEPTION_MASK_SSE = EXCEPTION_MASK << 7;
5388-
immutable newExceptionMasks = (newState & EXCEPTION_MASK) << 7;
5340+
enum EXCEPTION_MASK_SSE = allExceptions << 7;
5341+
immutable newExceptionMasks = (newState & allExceptions) << 7;
53895342
mxcsr &= ~EXCEPTION_MASK_SSE; // delete old masks
53905343
mxcsr |= newExceptionMasks; // write new exception masks
53915344

@@ -5412,13 +5365,13 @@ private:
54125365

54135366
/* In the FPU control register, rounding mode is in bits 10 and
54145367
11. In MXCSR it's in bits 13 and 14. */
5415-
mxcsr &= ~(ROUNDING_MASK << 3); // delete old rounding mode
5416-
mxcsr |= (newState & ROUNDING_MASK) << 3; // write new rounding mode
5368+
mxcsr &= ~(roundingMask << 3); // delete old rounding mode
5369+
mxcsr |= (newState & roundingMask) << 3; // write new rounding mode
54175370

54185371
/* In the FPU control register, masks are bits 0 through 5.
54195372
In MXCSR they're 7 through 12. */
5420-
mxcsr &= ~(EXCEPTION_MASK << 7); // delete old masks
5421-
mxcsr |= (newState & EXCEPTION_MASK) << 7; // write new exception masks
5373+
mxcsr &= ~(allExceptions << 7); // delete old masks
5374+
mxcsr |= (newState & allExceptions) << 7; // write new exception masks
54225375

54235376
asm pure nothrow @nogc
54245377
{

0 commit comments

Comments
 (0)