From e7b00f99e37d944cc9bd7b9fa858c007d3d2b5a0 Mon Sep 17 00:00:00 2001 From: Martin Date: Sat, 27 Sep 2014 21:23:37 +0200 Subject: [PATCH 1/3] core.stdc.fenv: standardize version() statements --- src/core/stdc/fenv.d | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/src/core/stdc/fenv.d b/src/core/stdc/fenv.d index 39db0c92a1..fdfeafbd1e 100644 --- a/src/core/stdc/fenv.d +++ b/src/core/stdc/fenv.d @@ -24,10 +24,6 @@ version( MinGW ) version( linux ) version = GNUFP; -version( DigitalMars ) - version( Win32 ) - version = DMC_RUNTIME; - version( GNUFP ) { // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86/fpu/bits/fenv.h @@ -114,7 +110,7 @@ version( GNUFP ) static assert(0, "Unimplemented architecture"); } } -else version( DMC_RUNTIME ) +else version( CRuntime_DigitalMars ) { struct fenv_t { @@ -125,9 +121,8 @@ else version( DMC_RUNTIME ) } alias fexcept_t = int; } -else version( Windows ) +else version( CRuntime_Microsoft ) { - // MSVCRT struct fenv_t { uint ctl; @@ -231,28 +226,22 @@ enum FE_TOWARDZERO = 0xC00, /// } -version( DMC_RUNTIME ) +version( GNUFP ) { - private extern __gshared fenv_t _FE_DFL_ENV; /// - enum fenv_t* FE_DFL_ENV = &_FE_DFL_ENV; + enum FE_DFL_ENV = cast(fenv_t*)(-1); } -else version( Windows ) +else version( CRuntime_DigitalMars ) { - version( MinGW ) - /// - enum FE_DFL_ENV = cast(fenv_t*)(-1); - else - { - private immutable fenv_t _Fenv0 = {0, 0}; - /// - enum FE_DFL_ENV = &_Fenv0; - } + private extern __gshared fenv_t _FE_DFL_ENV; + /// + enum fenv_t* FE_DFL_ENV = &_FE_DFL_ENV; } -else version( linux ) +else version( CRuntime_Microsoft ) { + private immutable fenv_t _Fenv0 = {0, 0}; /// - enum FE_DFL_ENV = cast(fenv_t*)(-1); + enum FE_DFL_ENV = &_Fenv0; } else version( OSX ) { From 395fb2569de8bf1a3ee73c9f303a59f3d00ebafc Mon Sep 17 00:00:00 2001 From: Martin Date: Sat, 27 Sep 2014 21:27:23 +0200 Subject: [PATCH 2/3] core.stdc.fenv: all functions return an int --- src/core/stdc/fenv.d | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/core/stdc/fenv.d b/src/core/stdc/fenv.d index fdfeafbd1e..c25e5e89b8 100644 --- a/src/core/stdc/fenv.d +++ b/src/core/stdc/fenv.d @@ -273,9 +273,9 @@ else } /// -void feraiseexcept(int excepts); +int feraiseexcept(int excepts); /// -void feclearexcept(int excepts); +int feclearexcept(int excepts); /// int fetestexcept(int excepts); @@ -283,9 +283,9 @@ int fetestexcept(int excepts); int feholdexcept(fenv_t* envp); /// -void fegetexceptflag(fexcept_t* flagp, int excepts); +int fegetexceptflag(fexcept_t* flagp, int excepts); /// -void fesetexceptflag(in fexcept_t* flagp, int excepts); +int fesetexceptflag(in fexcept_t* flagp, int excepts); /// int fegetround(); @@ -293,8 +293,8 @@ int fegetround(); int fesetround(int round); /// -void fegetenv(fenv_t* envp); +int fegetenv(fenv_t* envp); /// -void fesetenv(in fenv_t* envp); +int fesetenv(in fenv_t* envp); /// -void feupdateenv(in fenv_t* envp); +int feupdateenv(in fenv_t* envp); From c3da47d25095495d01a58ba3412311cb5f728950 Mon Sep 17 00:00:00 2001 From: Martin Date: Sat, 27 Sep 2014 22:01:11 +0200 Subject: [PATCH 3/3] core.stdc.fenv: add proper support for MSVCRT 12+ (VS 2013) --- src/core/stdc/fenv.d | 99 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 82 insertions(+), 17 deletions(-) diff --git a/src/core/stdc/fenv.d b/src/core/stdc/fenv.d index c25e5e89b8..0d563398d7 100644 --- a/src/core/stdc/fenv.d +++ b/src/core/stdc/fenv.d @@ -211,19 +211,38 @@ else static assert( false, "Unsupported platform" ); } -enum +version( CRuntime_Microsoft ) { - FE_INVALID = 1, /// - FE_DENORMAL = 2, /// non-standard - FE_DIVBYZERO = 4, /// - FE_OVERFLOW = 8, /// - FE_UNDERFLOW = 0x10, /// - FE_INEXACT = 0x20, /// - FE_ALL_EXCEPT = 0x3F, /// - FE_TONEAREST = 0, /// - FE_UPWARD = 0x800, /// - FE_DOWNWARD = 0x400, /// - FE_TOWARDZERO = 0xC00, /// + enum + { + FE_INEXACT = 1, /// + FE_UNDERFLOW = 2, /// + FE_OVERFLOW = 4, /// + FE_DIVBYZERO = 8, /// + FE_INVALID = 0x10, /// + FE_ALL_EXCEPT = 0x1F, /// + FE_TONEAREST = 0, /// + FE_UPWARD = 0x100, /// + FE_DOWNWARD = 0x200, /// + FE_TOWARDZERO = 0x300, /// + } +} +else +{ + enum + { + FE_INVALID = 1, /// + FE_DENORMAL = 2, /// non-standard + FE_DIVBYZERO = 4, /// + FE_OVERFLOW = 8, /// + FE_UNDERFLOW = 0x10, /// + FE_INEXACT = 0x20, /// + FE_ALL_EXCEPT = 0x3F, /// + FE_TONEAREST = 0, /// + FE_UPWARD = 0x800, /// + FE_DOWNWARD = 0x400, /// + FE_TOWARDZERO = 0xC00, /// + } } version( GNUFP ) @@ -239,7 +258,7 @@ else version( CRuntime_DigitalMars ) } else version( CRuntime_Microsoft ) { - private immutable fenv_t _Fenv0 = {0, 0}; + private extern __gshared fenv_t _Fenv0; /// enum FE_DFL_ENV = &_Fenv0; } @@ -272,8 +291,6 @@ else static assert( false, "Unsupported platform" ); } -/// -int feraiseexcept(int excepts); /// int feclearexcept(int excepts); @@ -296,5 +313,53 @@ int fesetround(int round); int fegetenv(fenv_t* envp); /// int fesetenv(in fenv_t* envp); -/// -int feupdateenv(in fenv_t* envp); + +// MS define feraiseexcept() and feupdateenv() inline. +version( CRuntime_Microsoft ) // supported since MSVCRT 12 (VS 2013) only +{ + /// + int feraiseexcept()(int excepts) + { + struct Entry + { + int exceptVal; + double num; + double denom; + } + static __gshared immutable(Entry[5]) table = + [ // Raise exception by evaluating num / denom: + { FE_INVALID, 0.0, 0.0 }, + { FE_DIVBYZERO, 1.0, 0.0 }, + { FE_OVERFLOW, 1e+300, 1e-300 }, + { FE_UNDERFLOW, 1e-300, 1e+300 }, + { FE_INEXACT, 2.0, 3.0 } + ]; + + if ((excepts &= FE_ALL_EXCEPT) == 0) + return 0; + + // Raise the exceptions not masked: + double ans = void; + foreach (i; 0 .. table.length) + { + if ((excepts & table[i].exceptVal) != 0) + ans = table[i].num / table[i].denom; + } + + return 0; + } + + /// + int feupdateenv()(in fenv_t* envp) + { + int excepts = fetestexcept(FE_ALL_EXCEPT); + return (fesetenv(envp) != 0 || feraiseexcept(excepts) != 0 ? 1 : 0); + } +} +else +{ + /// + int feraiseexcept(int excepts); + /// + int feupdateenv(in fenv_t* envp); +}