13 #include <xmmintrin.h> 22 #if !defined _GNU_SOURCE && defined __SSE__ && !defined __clang__ 24 static_assert(FE_INVALID == 0x01,
25 "incorrect assumption that FE_INVALID == 0x01");
26 static_assert(FE_DIVBYZERO == 0x04,
27 "incorrect assumption that FE_DIVBYZERO == 0x04");
28 static_assert(FE_OVERFLOW == 0x08,
29 "incorrect assumption that FE_OVERFLOW == 0x08");
30 static_assert(FE_UNDERFLOW == 0x10,
31 "incorrect assumption that FE_UNDERFLOW == 0x10");
32 static_assert(FE_INEXACT == 0x20,
33 "incorrect assumption that FE_INEXACT == 0x20");
36 femask &= FE_ALL_EXCEPT;
41 asm volatile(
"fstcw %0" :
"=m"(fpucw));
47 asm volatile(
"fldcw %0" ::
"m"(fpucw));
55 _mm_setcsr(_mm_getcsr() & ~femask);
64 const auto &log = logger<LogArea::Fpe>();
65 log.warn(
"Failed to setup traps on ", mask);
71 const auto &log = logger<LogArea::Fpe>();
75 log.warn(
"Failed to setup trap on pole error.");
80 log.warn(
"Failed to setup trap on domain error.");
86 log.warn(
"Failed to setup trap on overflow.");
98 #if (defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 199309L) || \ 99 (defined _XOPEN_SOURCE && _XOPEN_SOURCE) || \ 100 (defined _POSIX_SOURCE && _POSIX_SOURCE) 104 #pragma GCC diagnostic ignored "-Wmissing-field-initializers" 105 struct sigaction action = {};
106 action.sa_flags = SA_SIGINFO;
107 action.sa_sigaction = [](
int signal, siginfo_t *info,
void *) {
108 const auto &log = logger<LogArea::Fpe>();
109 if (signal == SIGFPE) {
110 const char *msg =
nullptr;
111 switch (info->si_code) {
113 msg =
"Division by Zero (NaN)";
116 msg =
"Underflow (result was subnormal with a loss of precision)";
119 msg =
"Overflow (result was too large to be representable)";
122 msg =
"Invalid (domain error occurred)";
126 "Inexact Result (rounding was necessary to store the result of " 127 "an earlier floating-point operation)";
133 log.fatal(
"Floating point trap was raised: ", msg);
135 log.fatal(
"Unexpected Signal ", signal,
136 " received in the FPE signal handler. Aborting.");
140 sigaction(SIGFPE, &action,
nullptr);
void setup_default_float_traps()
Setup the floating-point traps used throughout SMASH.
void reenable_traps(int mask)
Reenables the given traps.
bool enable_float_traps(int)
Fallback that fails to set the trap.