40#ifndef G4FPEDetection_h
41#define G4FPEDetection_h 1
52 struct sigaction termaction, oldaction;
54 static void TerminationSignalHandler(
int sig, siginfo_t* sinfo,
void* )
56 std::cerr <<
"ERROR: " << sig;
57 std::string message =
"Floating-point exception (FPE).";
60 switch (sinfo->si_code) {
65 message =
"Integer divide by zero.";
68 message =
"Integer overflow.";
71 message =
"Floating point divide by zero.";
74 message =
"Floating point overflow.";
77 message =
"Floating point underflow.";
80 message =
"Floating point inexact result.";
83 message =
"Floating point invalid operation.";
86 message =
"Subscript out of range.";
89 message =
"Unknown error.";
94 std::cerr <<
" - " << message << std::endl;
99 static void InvalidOperationDetection()
101 std::cout << std::endl
103 <<
"############################################" << std::endl
105 <<
"!!! WARNING - FPE detection is activated !!!" << std::endl
107 <<
"############################################" << std::endl;
109 (void) feenableexcept( FE_DIVBYZERO );
110 (void) feenableexcept( FE_INVALID );
114 sigdelset(&termaction.sa_mask,SIGFPE);
115 termaction.sa_sigaction=TerminationSignalHandler;
116 termaction.sa_flags=SA_SIGINFO;
117 sigaction(SIGFPE, &termaction, &oldaction);
125 #define DEFINED_PPC (defined(__ppc__) || defined(__ppc64__))
126 #define DEFINED_INTEL (defined(__i386__) || defined(__x86_64__))
130 #define FE_EXCEPT_SHIFT 22
131 #define FM_ALL_EXCEPT FE_ALL_EXCEPT >> FE_EXCEPT_SHIFT
133 static inline int feenableexcept (
unsigned int excepts)
136 unsigned int new_excepts = (excepts & FE_ALL_EXCEPT) >> FE_EXCEPT_SHIFT,
139 if ( fegetenv (&fenv) ) {
return -1; }
140 old_excepts = (fenv & FM_ALL_EXCEPT) << FE_EXCEPT_SHIFT;
141 fenv = (fenv & ~new_excepts) | new_excepts;
143 return ( fesetenv (&fenv) ? -1 : old_excepts );
146 static inline int fedisableexcept (
unsigned int excepts)
149 unsigned int still_on = ~((excepts & FE_ALL_EXCEPT) >> FE_EXCEPT_SHIFT),
152 if ( fegetenv (&fenv) ) {
return -1; }
153 old_excepts = (fenv & FM_ALL_EXCEPT) << FE_EXCEPT_SHIFT;
156 return ( fesetenv (&fenv) ? -1 : old_excepts );
161 static inline int feenableexcept (
unsigned int excepts)
164 unsigned int new_excepts = excepts & FE_ALL_EXCEPT,
167 if ( fegetenv (&fenv) ) {
return -1; }
168 old_excepts = fenv.__control & FE_ALL_EXCEPT;
172 fenv.__control &= ~new_excepts;
173 fenv.__mxcsr &= ~(new_excepts << 7);
175 return ( fesetenv (&fenv) ? -1 : old_excepts );
178 static inline int fedisableexcept (
unsigned int excepts)
181 unsigned int new_excepts = excepts & FE_ALL_EXCEPT,
184 if ( fegetenv (&fenv) ) {
return -1; }
185 old_excepts = fenv.__control & FE_ALL_EXCEPT;
189 fenv.__control |= new_excepts;
190 fenv.__mxcsr |= new_excepts << 7;
192 return ( fesetenv (&fenv) ? -1 : old_excepts );
197 static void TerminationSignalHandler(
int sig, siginfo_t* sinfo,
void* )
199 std::cerr <<
"ERROR: " << sig;
200 std::string message =
"Floating-point exception (FPE).";
203 switch (sinfo->si_code) {
208 message =
"Integer divide by zero.";
211 message =
"Integer overflow.";
214 message =
"Floating point divide by zero.";
217 message =
"Floating point overflow.";
220 message =
"Floating point underflow.";
223 message =
"Floating point inexact result.";
226 message =
"Floating point invalid operation.";
229 message =
"Subscript out of range.";
232 message =
"Unknown error.";
237 std::cerr <<
" - " << message << std::endl;
242 static void InvalidOperationDetection()
244 struct sigaction termaction, oldaction;
246 std::cout << std::endl
248 <<
"############################################" << std::endl
250 <<
"!!! WARNING - FPE detection is activated !!!" << std::endl
252 <<
"############################################" << std::endl;
254 feenableexcept ( FE_DIVBYZERO );
255 feenableexcept ( FE_INVALID );
259 sigdelset(&termaction.sa_mask,SIGFPE);
260 termaction.sa_sigaction=TerminationSignalHandler;
261 termaction.sa_flags=SA_SIGINFO;
262 sigaction(SIGFPE, &termaction, &oldaction);
266 static void InvalidOperationDetection() {;}