Skip to content

Commit

Permalink
add getter
Browse files Browse the repository at this point in the history
  • Loading branch information
simonbyrne committed Dec 19, 2022
1 parent beedde6 commit aef54b4
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 16 deletions.
75 changes: 62 additions & 13 deletions base/rounding.jl
Original file line number Diff line number Diff line change
Expand Up @@ -254,21 +254,70 @@ for IEEE arithmetic, and `true` if they might be converted to zeros.
get_zero_subnormals() = ccall(:jl_get_zero_subnormals,Int32,())!=0


function _get_exceptions()
excepts = ccall(:jl_set_fenv_except,Cint,())
if excepts < 0
error("Floating point exceptions not supported on this platform")
end
return excepts
end
function get_exceptions()
excepts = _get_exceptions()
return (;
invalid = excepts & JL_FE_INVALID != 0,
inexact = excepts & JL_FE_INEXACT != 0,
underflow = excepts & JL_FE_UNDERFLOW != 0,
overflow = excepts & JL_FE_OVERFLOW != 0,
dividebyzero = excepts & JL_FE_DIVBYZERO != 0,
)
end

function set_exceptions(;
invalid=false,
inexact=false,
overflow=false,
underflow=false,
dividebyzero=false
invalid=nothing,
inexact=nothing,
overflow=nothing,
underflow=nothing,
dividebyzero=nothing
)

excepts = (invalid * JL_FE_INVALID) |
(inexact * JL_FE_INEXACT) |
(underflow * JL_FE_UNDERFLOW) |
(overflow * JL_FE_OVERFLOW) |
(dividebyzero * JL_FE_DIVBYZERO)

ccall(:jl_set_fenv_except,Cint,(Cint,), excepts) == 0
excepts = _get_exceptions()
if !isnothing(invalid)
if invalid
excepts |= JL_FE_INVALID
else
excepts &= ~JL_FE_INVALID
end
end
if !isnothing(inexact)
if inexact
excepts |= JL_FE_INEXACT
else
excepts &= ~JL_FE_INEXACT
end
end
if !isnothing(underflow)
if underflow
excepts |= JL_FE_UNDERFLOW
else
excepts &= ~JL_FE_UNDERFLOW
end
end
if !isnothing(overflow)
if overflow
excepts |= JL_FE_OVERFLOW
else
excepts &= ~JL_FE_OVERFLOW
end
end
if !isnothing(dividebyzero)
if dividebyzero
excepts |= JL_FE_DIVBYZERO
else
excepts &= ~JL_FE_DIVBYZERO
end
end
if ccall(:jl_set_fenv_except,Cint,(Cint,), excepts) < 0
error("Floating point exceptions not supported on this platform")
end
end

end #module
38 changes: 35 additions & 3 deletions src/jlapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,39 @@ JL_DLLEXPORT int jl_set_fenv_rounding(int i)
return fesetround(i);
}


JL_DLLEXPORT int jl_get_fenv_except(void)
{
#if defined(__GLIBC__)
return fegetexcept();
#elif defined(_OS_WINDOWS_)
unsigned int flags = _controlfp(0, 0);
int excepts = 0;
if (flags & _EM_INEXACT)
excepts |= FE_INEXACT;
if (flags & _EM_UNDERFLOW)
excepts |= FE_UNDERFLOW;
if (flags & _EM_OVERFLOW)
excepts |= FE_OVERFLOW;
if (flags & _EM_ZERODIVIDE)
excepts |= FE_DIVBYZERO;
if (flags & _EM_INVALID)
excepts |= FE_INVALID;
return excepts;
#elif defined(_OS_DARWIN_)
fenv_t env;
fegetenv(&env);
#if defined(_CPU_AARCH64_)
return (env.__fpcr & FE_ALL_EXCEPT << 8)
#elif defined(_CPU_X86_64_)
return (~env.__mxcsr & FE_ALL_EXCEPT << 7)
#else
return -1;
#endif
return -1;
#endif
}

JL_DLLEXPORT int jl_set_fenv_except(int excepts)
{
#if defined(__GLIBC__)
Expand Down Expand Up @@ -559,17 +592,16 @@ JL_DLLEXPORT int jl_set_fenv_except(int excepts)
env.__control = (env.__control | FE_ALL_EXCEPT) & ~excepts;
env.__mxcsr = (env.__mxcsr | FE_ALL_EXCEPT << 7) & ~(excepts << 7);
#else
return 1;
return -1;
#endif
fesetenv(&env);
return 0;
#else
return 1;
return -1;
#endif
}



static int exec_program(char *program)
{
JL_TRY {
Expand Down

0 comments on commit aef54b4

Please sign in to comment.