@@ -139,6 +139,7 @@ version (Win64)
139139
140140static import core.math ;
141141static import core.stdc.math ;
142+ static import core.stdc.fenv ;
142143import std.traits ; // CommonType, isFloatingPoint, isIntegral, isSigned, isUnsigned, Largest, Unqual
143144
144145version (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
46464647private :
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+
47054684private :
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-
52045157public :
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