|
Teuchos Package Browser (Single Doxygen Collection) Version of the Day
|
00001 #if 0 // Disabled! 00002 // @HEADER 00003 // *********************************************************************** 00004 // 00005 // Teuchos: Common Tools Package 00006 // Copyright (2004) Sandia Corporation 00007 // 00008 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00009 // license for use of this work by or on behalf of the U.S. Government. 00010 // 00011 // This library is free software; you can redistribute it and/or modify 00012 // it under the terms of the GNU Lesser General Public License as 00013 // published by the Free Software Foundation; either version 2.1 of the 00014 // License, or (at your option) any later version. 00015 // 00016 // This library is distributed in the hope that it will be useful, but 00017 // WITHOUT ANY WARRANTY; without even the implied warranty of 00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00019 // Lesser General Public License for more details. 00020 // 00021 // You should have received a copy of the GNU Lesser General Public 00022 // License along with this library; if not, write to the Free Software 00023 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00024 // USA 00025 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00026 // 00027 // *********************************************************************** 00028 // @HEADER 00029 00030 00031 #include "Teuchos_FloatingPointTrap.hpp" 00032 #include "Teuchos_TestForException.hpp" 00033 00034 00035 // 00036 // Implementation of floating point control 00037 // 00038 00039 00040 // ??? 00041 00042 00043 // 00044 // We have floating point control! 00045 // 00046 00047 00048 static void ieee0(bool enableTrap); 00049 00050 00051 void Teuchos::doFloatingPointTrap(bool enableTrap) 00052 { 00053 ieee0(enableTrap); 00054 } 00055 00056 00057 00058 // 00059 // Stuff from uninit.c from f2c and them from Sacado! 00060 // 00061 00062 00063 // 00064 // Up front stuff 00065 // 00066 00067 00068 #include <cstdio> 00069 #include <cstring> 00070 00071 #define TYSHORT 2 00072 #define TYLONG 3 00073 #define TYREAL 4 00074 #define TYDREAL 5 00075 #define TYCOMPLEX 6 00076 #define TYDCOMPLEX 7 00077 #define TYINT1 11 00078 #define TYQUAD 14 00079 00080 #ifndef Long 00081 #define Long long 00082 #endif // Long 00083 00084 #ifdef __mips 00085 #define RNAN 0xffc00000 00086 #define DNAN0 0xfff80000 00087 #define DNAN1 0 00088 #endif // __mips 00089 00090 #ifdef _PA_RISC1_1 00091 #define RNAN 0xffc00000 00092 #define DNAN0 0xfff80000 00093 #define DNAN1 0 00094 #endif // _PA_RISC1_1 00095 00096 #ifndef RNAN 00097 # define RNAN 0xff800001 00098 # ifdef IEEE_MC68k 00099 # define DNAN0 0xfff00000 00100 # define DNAN1 1 00101 # else 00102 # define DNAN0 1 00103 # define DNAN1 0xfff00000 00104 # endif 00105 #endif /*RNAN*/ 00106 00107 00108 static unsigned Long rnan = RNAN, dnan0 = DNAN0, dnan1 = DNAN1; 00109 00110 double _0 = 0.; 00111 00112 #ifndef MSpc 00113 # ifdef MSDOS 00114 # define MSpc 00115 # else 00116 # ifdef _WIN32 00117 # define MSpc 00118 # endif 00119 # endif 00120 #endif 00121 00122 00123 // 00124 // MSpc 00125 // 00126 00127 00128 #ifdef MSpc 00129 00130 #define IEEE0_done 00131 #include "cfloat" 00132 #include "csignal" 00133 00134 static void ieee0(bool enableTrap) 00135 { 00136 TEST_FOR_EXCEPTION( 00137 enableTrap == false, std::logic_error, 00138 "Error, don't know how to turn off trap for MSpc!" 00139 ); 00140 #ifndef __alpha 00141 _control87(EM_DENORMAL | EM_UNDERFLOW | EM_INEXACT, MCW_EM); 00142 #endif 00143 /* With MS VC++, compiling and linking with -Zi will permit */ 00144 /* clicking to invoke the MS C++ debugger, which will show */ 00145 /* the point of error -- provided SIGFPE is SIG_DFL. */ 00146 signal(SIGFPE, SIG_DFL); 00147 } 00148 00149 #endif // MSpc 00150 00151 00152 // 00153 // MIPS 00154 // 00155 00156 00157 #ifdef __mips /* must link with -lfpe */ 00158 00159 #define IEEE0_done 00160 #include <cstdlib> 00161 #include <cstdio> 00162 #include "/usr/include/sigfpe.h" /* full pathname for lcc -N */ 00163 #include "/usr/include/sys/fpu.h" 00164 00165 static void ieeeuserhand(unsigned std::exception[5], int val[2]) 00166 { 00167 fflush(stdout); 00168 fprintf(stderr,"ieee0() aborting because of "); 00169 if(std::exception[0]==_OVERFL) fprintf(stderr,"overflow\n"); 00170 else if(std::exception[0]==_UNDERFL) fprintf(stderr,"underflow\n"); 00171 else if(std::exception[0]==_DIVZERO) fprintf(stderr,"divide by 0\n"); 00172 else if(std::exception[0]==_INVALID) fprintf(stderr,"invalid operation\n"); 00173 else fprintf(stderr,"\tunknown reason\n"); 00174 fflush(stderr); 00175 abort(); 00176 } 00177 00178 static void ieeeuserhand2(unsigned int **j) 00179 { 00180 fprintf(stderr,"ieee0() aborting because of confusion\n"); 00181 abort(); 00182 } 00183 00184 static void ieee0(bool enableTrap) 00185 { 00186 TEST_FOR_EXCEPTION( 00187 enableTrap == false, std::logic_error, 00188 "Error, don't know how to turn off trap for MIPS!" 00189 ); 00190 int i; 00191 for(i=1; i<=4; i++){ 00192 sigfpe_[i].count = 1000; 00193 sigfpe_[i].trace = 1; 00194 sigfpe_[i].repls = _USER_DETERMINED; 00195 } 00196 sigfpe_[1].repls = _ZERO; /* underflow */ 00197 handle_sigfpes( _ON, 00198 _EN_UNDERFL|_EN_OVERFL|_EN_DIVZERO|_EN_INVALID, 00199 ieeeuserhand,_ABORT_ON_ERROR,ieeeuserhand2); 00200 } 00201 #endif /* mips */ 00202 00203 00204 // 00205 // Linux 00206 // 00207 00208 00209 #ifdef __linux__ 00210 00211 #define IEEE0_done 00212 #include "fpu_control.h" 00213 00214 #ifdef __alpha__ 00215 # ifndef USE_setfpucw 00216 # define __setfpucw(x) __fpu_control = (x) 00217 # endif 00218 #endif 00219 00220 #ifndef _FPU_SETCW 00221 # undef Can_use__setfpucw 00222 # define Can_use__setfpucw 00223 #endif 00224 00225 static void ieee0(bool enableTrap) 00226 { 00227 00228 TEST_FOR_EXCEPTION( 00229 enableTrap == false, std::logic_error, 00230 "Error, don't know how to turn off trap for LINUX!" 00231 ); 00232 00233 #if (defined(__mc68000__) || defined(__mc68020__) || defined(mc68020) || defined (__mc68k__)) 00234 00235 /* Reported 20010705 by Alan Bain <alanb@chiark.greenend.org.uk> */ 00236 /* Note that IEEE 754 IOP (illegal operation) */ 00237 /* = Signaling NAN (SNAN) + operation error (OPERR). */ 00238 00239 #ifdef Can_use__setfpucw /* Has __setfpucw gone missing from S.u.S.E. 6.3? */ 00240 __setfpucw(_FPU_IEEE + _FPU_DOUBLE + _FPU_MASK_OPERR + _FPU_MASK_DZ + _FPU_MASK_SNAN + _FPU_MASK_OVFL); 00241 #else 00242 __fpu_control = _FPU_IEEE + _FPU_DOUBLE + _FPU_MASK_OPERR + _FPU_MASK_DZ + _FPU_MASK_SNAN + _FPU_MASK_OVFL; 00243 _FPU_SETCW(__fpu_control); 00244 #endif 00245 00246 #elif (defined(__powerpc__)||defined(_ARCH_PPC)||defined(_ARCH_PWR)) /* !__mc68k__ */ 00247 /* Reported 20011109 by Alan Bain <alanb@chiark.greenend.org.uk> */ 00248 00249 #ifdef Can_use__setfpucw 00250 00251 /* The following is NOT a mistake -- the author of the fpu_control.h 00252 for the PPC has erroneously defined IEEE mode to turn on exceptions 00253 other than Inexact! Start from default then and turn on only the ones 00254 which we want*/ 00255 00256 __setfpucw(_FPU_DEFAULT + _FPU_MASK_IM+_FPU_MASK_OM+_FPU_MASK_UM); 00257 00258 #else /* PPC && !Can_use__setfpucw */ 00259 00260 __fpu_control = _FPU_DEFAULT +_FPU_MASK_OM+_FPU_MASK_IM+_FPU_MASK_UM; 00261 _FPU_SETCW(__fpu_control); 00262 00263 #endif /*Can_use__setfpucw*/ 00264 00265 #else /* !(mc68000||powerpc) */ 00266 00267 #ifdef _FPU_IEEE 00268 # ifndef _FPU_EXTENDED /* e.g., ARM processor under Linux */ 00269 # define _FPU_EXTENDED 0 00270 #endif 00271 00272 #ifndef _FPU_DOUBLE 00273 # define _FPU_DOUBLE 0 00274 #endif 00275 00276 #ifdef Can_use__setfpucw /* Has __setfpucw gone missing from S.u.S.E. 6.3? */ 00277 __setfpucw(_FPU_IEEE - _FPU_EXTENDED + _FPU_DOUBLE - _FPU_MASK_IM - _FPU_MASK_ZM - _FPU_MASK_OM); 00278 #else 00279 __fpu_control = _FPU_IEEE - _FPU_EXTENDED + _FPU_DOUBLE - _FPU_MASK_IM - _FPU_MASK_ZM - _FPU_MASK_OM; 00280 _FPU_SETCW(__fpu_control); 00281 #endif 00282 00283 #else /* !_FPU_IEEE */ 00284 00285 TEST_FOR_EXCEPTION( 00286 true, std::logic_error, 00287 "Error, don't know how to trap floating-point errors on this Linux system!" 00288 ); 00289 00290 #endif /* _FPU_IEEE */ 00291 00292 #endif /* __mc68k__ */ 00293 00294 } // ieee0() 00295 00296 #endif /* __linux__ */ 00297 00298 00299 // 00300 // Alpha 00301 // 00302 00303 00304 #ifdef __alpha 00305 00306 #ifndef IEEE0_done 00307 00308 #define IEEE0_done 00309 #include <machine/fpu.h> 00310 00311 static void ieee0(bool enableTrap) 00312 { 00313 TEST_FOR_EXCEPTION( 00314 enableTrap == false, std::logic_error, 00315 "Error, don't know how to turn off trap for Alpha!" 00316 ); 00317 ieee_set_fp_control(IEEE_TRAP_ENABLE_INV); 00318 } 00319 00320 #endif /*IEEE0_done*/ 00321 00322 #endif /*__alpha*/ 00323 00324 00325 // 00326 // hpux 00327 // 00328 00329 00330 00331 #ifdef __hpux 00332 00333 #define IEEE0_done 00334 #define _INCLUDE_HPUX_SOURCE 00335 00336 #include <cmath> 00337 00338 #ifndef FP_X_INV 00339 # include <fenv.h> 00340 # define fpsetmask fesettrapenable 00341 # define FP_X_INV FE_INVALID 00342 #endif 00343 00344 static void ieee0(bool enableTrap) 00345 { 00346 TEST_FOR_EXCEPTION( 00347 enableTrap == false, std::logic_error, 00348 "Error, don't know how to turn off trap for HPUX!" 00349 ); 00350 fpsetmask(FP_X_INV); 00351 } 00352 00353 #endif /*__hpux*/ 00354 00355 00356 // 00357 // AIX 00358 // 00359 00360 00361 #ifdef _AIX 00362 00363 #define IEEE0_done 00364 #include <fptrap.h> 00365 00366 static void ieee0(bool enableTrap) 00367 { 00368 TEST_FOR_EXCEPTION( 00369 enableTrap == false, std::logic_error, 00370 "Error, don't know how to turn off trap for AIX!" 00371 ); 00372 fp_enable(TRP_INVALID); 00373 fp_trap(FP_TRAP_SYNC); 00374 } 00375 00376 #endif /*_AIX*/ 00377 00378 00379 // 00380 // SUN 00381 // 00382 00383 00384 #ifdef __sun 00385 00386 #define IEEE0_done 00387 #include <ieeefp.h> 00388 00389 static void ieee0(bool enableTrap) 00390 { 00391 TEST_FOR_EXCEPTION( 00392 enableTrap == false, std::logic_error, 00393 "Error, don't know how to turn off trap for SUN!" 00394 ); 00395 fpsetmask(FP_X_INV); 00396 } 00397 00398 #endif // __sun 00399 00400 00401 // 00402 // Default (none) 00403 // 00404 00405 00406 #ifndef IEEE0_done 00407 00408 static void ieee0(bool enableTrap) 00409 { 00410 TEST_FOR_EXCEPTION( 00411 true, std::logic_error, 00412 "Error, Don't know how to implement floating-point traps on this platform!" 00413 ); 00414 } 00415 00416 #endif // IEEE0_done 00417 00418 #endif // 0 // Disabled!
1.7.4