Teuchos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Teuchos_FloatingPointTrap.cpp
Go to the documentation of this file.
1 #if 0 // Disabled!
2 // @HEADER
3 // ***********************************************************************
4 //
5 // Teuchos: Common Tools Package
6 // Copyright (2004) Sandia Corporation
7 //
8 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
9 // license for use of this work by or on behalf of the U.S. Government.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
39 //
40 // ***********************************************************************
41 // @HEADER
42 
43 
45 #include "Teuchos_Assert.hpp"
46 
47 
48 //
49 // Implementation of floating point control
50 //
51 
52 
53 // ???
54 
55 
56 //
57 // We have floating point control!
58 //
59 
60 
61 static void ieee0(bool enableTrap);
62 
63 
64 void Teuchos::doFloatingPointTrap(bool enableTrap)
65 {
66  ieee0(enableTrap);
67 }
68 
69 
70 
71 //
72 // Stuff from uninit.c from f2c and them from Sacado!
73 //
74 
75 
76 //
77 // Up front stuff
78 //
79 
80 
81 #include <cstdio>
82 #include <cstring>
83 
84 #define TYSHORT 2
85 #define TYLONG 3
86 #define TYREAL 4
87 #define TYDREAL 5
88 #define TYCOMPLEX 6
89 #define TYDCOMPLEX 7
90 #define TYINT1 11
91 #define TYQUAD 14
92 
93 #ifndef Long
94 #define Long long
95 #endif // Long
96 
97 #ifdef __mips
98 #define RNAN 0xffc00000
99 #define DNAN0 0xfff80000
100 #define DNAN1 0
101 #endif // __mips
102 
103 #ifdef _PA_RISC1_1
104 #define RNAN 0xffc00000
105 #define DNAN0 0xfff80000
106 #define DNAN1 0
107 #endif // _PA_RISC1_1
108 
109 #ifndef RNAN
110 # define RNAN 0xff800001
111 # ifdef IEEE_MC68k
112 # define DNAN0 0xfff00000
113 # define DNAN1 1
114 # else
115 # define DNAN0 1
116 # define DNAN1 0xfff00000
117 # endif
118 #endif /*RNAN*/
119 
120 
121 static unsigned Long rnan = RNAN, dnan0 = DNAN0, dnan1 = DNAN1;
122 
123 double _0 = 0.;
124 
125 #ifndef MSpc
126 # ifdef MSDOS
127 # define MSpc
128 # else
129 # ifdef _WIN32
130 # define MSpc
131 # endif
132 # endif
133 #endif
134 
135 
136 //
137 // MSpc
138 //
139 
140 
141 #ifdef MSpc
142 
143 #define IEEE0_done
144 #include "cfloat"
145 #include "csignal"
146 
147 static void ieee0(bool enableTrap)
148 {
150  enableTrap == false, std::logic_error,
151  "Error, don't know how to turn off trap for MSpc!"
152  );
153 #ifndef __alpha
154  _control87(EM_DENORMAL | EM_UNDERFLOW | EM_INEXACT, MCW_EM);
155 #endif
156  /* With MS VC++, compiling and linking with -Zi will permit */
157  /* clicking to invoke the MS C++ debugger, which will show */
158  /* the point of error -- provided SIGFPE is SIG_DFL. */
159  signal(SIGFPE, SIG_DFL);
160 }
161 
162 #endif // MSpc
163 
164 
165 //
166 // MIPS
167 //
168 
169 
170 #ifdef __mips /* must link with -lfpe */
171 
172 #define IEEE0_done
173 #include <cstdlib>
174 #include <cstdio>
175 #include "/usr/include/sigfpe.h" /* full pathname for lcc -N */
176 #include "/usr/include/sys/fpu.h"
177 
178 static void ieeeuserhand(unsigned std::exception[5], int val[2])
179 {
180  fflush(stdout);
181  fprintf(stderr,"ieee0() aborting because of ");
182  if(std::exception[0]==_OVERFL) fprintf(stderr,"overflow\n");
183  else if(std::exception[0]==_UNDERFL) fprintf(stderr,"underflow\n");
184  else if(std::exception[0]==_DIVZERO) fprintf(stderr,"divide by 0\n");
185  else if(std::exception[0]==_INVALID) fprintf(stderr,"invalid operation\n");
186  else fprintf(stderr,"\tunknown reason\n");
187  fflush(stderr);
188  abort();
189 }
190 
191 static void ieeeuserhand2(unsigned int **j)
192 {
193  fprintf(stderr,"ieee0() aborting because of confusion\n");
194  abort();
195 }
196 
197 static void ieee0(bool enableTrap)
198 {
200  enableTrap == false, std::logic_error,
201  "Error, don't know how to turn off trap for MIPS!"
202  );
203  int i;
204  for(i=1; i<=4; i++){
205  sigfpe_[i].count = 1000;
206  sigfpe_[i].trace = 1;
207  sigfpe_[i].repls = _USER_DETERMINED;
208  }
209  sigfpe_[1].repls = _ZERO; /* underflow */
210  handle_sigfpes( _ON,
211  _EN_UNDERFL|_EN_OVERFL|_EN_DIVZERO|_EN_INVALID,
212  ieeeuserhand,_ABORT_ON_ERROR,ieeeuserhand2);
213  }
214 #endif /* mips */
215 
216 
217 //
218 // Linux
219 //
220 
221 
222 #ifdef __linux__
223 
224 #define IEEE0_done
225 #include "fpu_control.h"
226 
227 #ifdef __alpha__
228 # ifndef USE_setfpucw
229 # define __setfpucw(x) __fpu_control = (x)
230 # endif
231 #endif
232 
233 #ifndef _FPU_SETCW
234 # undef Can_use__setfpucw
235 # define Can_use__setfpucw
236 #endif
237 
238 static void ieee0(bool enableTrap)
239 {
240 
242  enableTrap == false, std::logic_error,
243  "Error, don't know how to turn off trap for LINUX!"
244  );
245 
246 #if (defined(__mc68000__) || defined(__mc68020__) || defined(mc68020) || defined (__mc68k__))
247 
248  /* Reported 20010705 by Alan Bain <alanb@chiark.greenend.org.uk> */
249  /* Note that IEEE 754 IOP (illegal operation) */
250  /* = Signaling NAN (SNAN) + operation error (OPERR). */
251 
252 #ifdef Can_use__setfpucw /* Has __setfpucw gone missing from S.u.S.E. 6.3? */
253  __setfpucw(_FPU_IEEE + _FPU_DOUBLE + _FPU_MASK_OPERR + _FPU_MASK_DZ + _FPU_MASK_SNAN + _FPU_MASK_OVFL);
254 #else
255  __fpu_control = _FPU_IEEE + _FPU_DOUBLE + _FPU_MASK_OPERR + _FPU_MASK_DZ + _FPU_MASK_SNAN + _FPU_MASK_OVFL;
256  _FPU_SETCW(__fpu_control);
257 #endif
258 
259 #elif (defined(__powerpc__)||defined(_ARCH_PPC)||defined(_ARCH_PWR)) /* !__mc68k__ */
260  /* Reported 20011109 by Alan Bain <alanb@chiark.greenend.org.uk> */
261 
262 #ifdef Can_use__setfpucw
263 
264  /* The following is NOT a mistake -- the author of the fpu_control.h
265  for the PPC has erroneously defined IEEE mode to turn on exceptions
266  other than Inexact! Start from default then and turn on only the ones
267  which we want*/
268 
269  __setfpucw(_FPU_DEFAULT + _FPU_MASK_IM+_FPU_MASK_OM+_FPU_MASK_UM);
270 
271 #else /* PPC && !Can_use__setfpucw */
272 
273  __fpu_control = _FPU_DEFAULT +_FPU_MASK_OM+_FPU_MASK_IM+_FPU_MASK_UM;
274  _FPU_SETCW(__fpu_control);
275 
276 #endif /*Can_use__setfpucw*/
277 
278 #else /* !(mc68000||powerpc) */
279 
280 #ifdef _FPU_IEEE
281 # ifndef _FPU_EXTENDED /* e.g., ARM processor under Linux */
282 # define _FPU_EXTENDED 0
283 #endif
284 
285 #ifndef _FPU_DOUBLE
286 # define _FPU_DOUBLE 0
287 #endif
288 
289 #ifdef Can_use__setfpucw /* Has __setfpucw gone missing from S.u.S.E. 6.3? */
290  __setfpucw(_FPU_IEEE - _FPU_EXTENDED + _FPU_DOUBLE - _FPU_MASK_IM - _FPU_MASK_ZM - _FPU_MASK_OM);
291 #else
292  __fpu_control = _FPU_IEEE - _FPU_EXTENDED + _FPU_DOUBLE - _FPU_MASK_IM - _FPU_MASK_ZM - _FPU_MASK_OM;
293  _FPU_SETCW(__fpu_control);
294 #endif
295 
296 #else /* !_FPU_IEEE */
297 
299  true, std::logic_error,
300  "Error, don't know how to trap floating-point errors on this Linux system!"
301  );
302 
303 #endif /* _FPU_IEEE */
304 
305 #endif /* __mc68k__ */
306 
307 } // ieee0()
308 
309 #endif /* __linux__ */
310 
311 
312 //
313 // Alpha
314 //
315 
316 
317 #ifdef __alpha
318 
319 #ifndef IEEE0_done
320 
321 #define IEEE0_done
322 #include <machine/fpu.h>
323 
324 static void ieee0(bool enableTrap)
325 {
327  enableTrap == false, std::logic_error,
328  "Error, don't know how to turn off trap for Alpha!"
329  );
330  ieee_set_fp_control(IEEE_TRAP_ENABLE_INV);
331 }
332 
333 #endif /*IEEE0_done*/
334 
335 #endif /*__alpha*/
336 
337 
338 //
339 // hpux
340 //
341 
342 
343 
344 #ifdef __hpux
345 
346 #define IEEE0_done
347 #define _INCLUDE_HPUX_SOURCE
348 
349 #include <cmath>
350 
351 #ifndef FP_X_INV
352 # include <fenv.h>
353 # define fpsetmask fesettrapenable
354 # define FP_X_INV FE_INVALID
355 #endif
356 
357 static void ieee0(bool enableTrap)
358 {
360  enableTrap == false, std::logic_error,
361  "Error, don't know how to turn off trap for HPUX!"
362  );
363  fpsetmask(FP_X_INV);
364 }
365 
366 #endif /*__hpux*/
367 
368 
369 //
370 // AIX
371 //
372 
373 
374 #ifdef _AIX
375 
376 #define IEEE0_done
377 #include <fptrap.h>
378 
379 static void ieee0(bool enableTrap)
380 {
382  enableTrap == false, std::logic_error,
383  "Error, don't know how to turn off trap for AIX!"
384  );
385  fp_enable(TRP_INVALID);
386  fp_trap(FP_TRAP_SYNC);
387 }
388 
389 #endif /*_AIX*/
390 
391 
392 //
393 // SUN
394 //
395 
396 
397 #ifdef __sun
398 
399 #define IEEE0_done
400 #include <ieeefp.h>
401 
402 static void ieee0(bool enableTrap)
403 {
405  enableTrap == false, std::logic_error,
406  "Error, don't know how to turn off trap for SUN!"
407  );
408  fpsetmask(FP_X_INV);
409 }
410 
411 #endif // __sun
412 
413 
414 //
415 // Default (none)
416 //
417 
418 
419 #ifndef IEEE0_done
420 
421 static void ieee0(bool enableTrap)
422 {
424  true, std::logic_error,
425  "Error, Don't know how to implement floating-point traps on this platform!"
426  );
427 }
428 
429 #endif // IEEE0_done
430 
431 #endif // 0 // Disabled!
void doFloatingPointTrap(bool enableTrap)
Turn on or off a floating point trap.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.