From d2c370a95396ca47cb200348def9d5f7c6237c08 Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Fri, 9 Mar 2018 11:41:17 -0500 Subject: [PATCH] Enable FPE on Mac (#4213) Allow #3687 to work on Mac --- CMakeLists.txt | 2 +- include/fenv.h | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 include/fenv.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c3e8476b..bc67ebe0d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -461,7 +461,7 @@ IF(LMMS_BUILD_WIN32) ENDIF(LMMS_BUILD_WIN32) IF(WANT_DEBUG_FPE) - IF(LMMS_BUILD_LINUX) + IF(LMMS_BUILD_LINUX OR LMMS_BUILD_APPLE) SET(LMMS_DEBUG_FPE TRUE) SET (STATUS_DEBUG_FPE "Enabled") ELSE() diff --git a/include/fenv.h b/include/fenv.h new file mode 100644 index 000000000..c9cc508f5 --- /dev/null +++ b/include/fenv.h @@ -0,0 +1,48 @@ +#pragma once + +#include_next + +#if defined(__APPLE__) && defined(__MACH__) + +// Public domain polyfill for feenableexcept on OS X +// http://www-personal.umich.edu/~williams/archive/computation/fe-handling-example.c + +inline int feenableexcept(unsigned int excepts) +{ + static fenv_t fenv; + unsigned int new_excepts = excepts & FE_ALL_EXCEPT; + // previous masks + unsigned int old_excepts; + + if (fegetenv(&fenv)) { + return -1; + } + old_excepts = fenv.__control & FE_ALL_EXCEPT; + + // unmask + fenv.__control &= ~new_excepts; + fenv.__mxcsr &= ~(new_excepts << 7); + + return fesetenv(&fenv) ? -1 : old_excepts; +} + +inline int fedisableexcept(unsigned int excepts) +{ + static fenv_t fenv; + unsigned int new_excepts = excepts & FE_ALL_EXCEPT; + // all previous masks + unsigned int old_excepts; + + if (fegetenv(&fenv)) { + return -1; + } + old_excepts = fenv.__control & FE_ALL_EXCEPT; + + // mask + fenv.__control |= new_excepts; + fenv.__mxcsr |= new_excepts << 7; + + return fesetenv(&fenv) ? -1 : old_excepts; +} + +#endif