diff --git a/src/system.cpp b/src/system.cpp index a6532ac5..e1a76d9a 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -530,7 +530,48 @@ void resetSignalHandling() /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// int getDefaultFloatingPointExceptions() { - return ( FE_DIVBYZERO | FE_OVERFLOW | FE_INVALID ); + return ( FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID ); +} + +unsigned long long int translateFloatingPointException( unsigned long long int const exception ) +{ + unsigned long long int result = 0; +#if defined(__APPLE__) && defined(__MACH__) // if apple + if( exception & FE_INEXACT ) + { + result |= __fpcr_trap_inexact; + } + if( exception & FE_UNDERFLOW ) + { + result |= __fpcr_trap_underflow; + } + if( exception & FE_OVERFLOW ) + { + result |= __fpcr_trap_overflow; + } + if( exception & FE_DIVBYZERO ) + { + result |= __fpcr_trap_divbyzero; + } + if( exception & FE_INVALID ) + { + result |= __fpcr_trap_invalid; + } + +#if defined(__arm__) || defined(__arm64__) // if apple arm +#elif defined(__x86_64__) // if apple x86_64 +#else // if apple but not arm or x86_64 + std::cerr<< "LvArray::system::translateFloatingPointException() not implemented for this architecture" << std::endl; +#endif + + +#else // if not apple +#if defined(__x86_64__) + result = exception; +#endif +#endif + +return result; } #if defined(__APPLE__) && defined(__MACH__)&& !defined(__x86_64__) @@ -542,10 +583,8 @@ fpe_signal_handler( int sig, siginfo_t *sip, void *scp ) int fe_code = sip->si_code; - printf( "In signal handler : " ); - if( fe_code == ILL_ILLTRP ) - printf( "Illegal trap detected\n" ); + printf( "Illegal trap detected. If you see this you have a FPE, but Apple Silicon doesn't provide data on which FPE has occured.\n" ); else printf( "Code detected : %d\n", fe_code ); @@ -559,19 +598,22 @@ int enableFloatingPointExceptions( int const exceptions ) #if defined(__APPLE__) && defined(__MACH__) #if !defined(__x86_64__) - LVARRAY_UNUSED_VARIABLE( exceptions ); + unsigned long long int const exceptionMasks = translateFloatingPointException( exceptions ); fenv_t env; fegetenv( &env ); - env.__fpcr = env.__fpcr | __fpcr_trap_invalid; +// std::cout< #include - -#if defined(__x86_64__) - using namespace testFloatingPointExceptionsHelpers; const char IGNORE_OUTPUT[] = ".*"; @@ -74,7 +71,6 @@ TEST( TestFloatingPointEnvironment, FloatingPointExceptionGuard ) } // namespace testing } // namespace LvArray -#endif // This is the default gtest main method. It is included for ease of debugging. int main( int argc, char * * argv )