Teuchos_FloatingPointTrap.cpp

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!
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Wed Apr 13 09:57:43 2011 for Teuchos - Trilinos Tools Package by  doxygen 1.6.3