Teuchos Package Browser (Single Doxygen Collection) Version of the Day
Teuchos_FloatingPointTrap.cpp
Go to the documentation of this file.
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 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00039 //
00040 // ***********************************************************************
00041 // @HEADER
00042 
00043 
00044 #include "Teuchos_FloatingPointTrap.hpp"
00045 #include "Teuchos_TestForException.hpp"
00046 
00047 
00048 //
00049 // Implementation of floating point control
00050 //
00051 
00052 
00053 // ???
00054 
00055 
00056 //
00057 // We have floating point control!
00058 //
00059 
00060 
00061 static void ieee0(bool enableTrap);
00062 
00063 
00064 void Teuchos::doFloatingPointTrap(bool enableTrap)
00065 {
00066   ieee0(enableTrap);
00067 }
00068 
00069 
00070 
00071 //
00072 // Stuff from uninit.c from f2c and them from Sacado!
00073 //
00074 
00075 
00076 //
00077 // Up front stuff
00078 //
00079 
00080 
00081 #include <cstdio>
00082 #include <cstring>
00083 
00084 #define TYSHORT 2
00085 #define TYLONG 3
00086 #define TYREAL 4
00087 #define TYDREAL 5
00088 #define TYCOMPLEX 6
00089 #define TYDCOMPLEX 7
00090 #define TYINT1 11
00091 #define TYQUAD 14
00092 
00093 #ifndef Long
00094 #define Long long
00095 #endif // Long
00096 
00097 #ifdef __mips
00098 #define RNAN  0xffc00000
00099 #define DNAN0 0xfff80000
00100 #define DNAN1 0
00101 #endif // __mips
00102 
00103 #ifdef _PA_RISC1_1
00104 #define RNAN  0xffc00000
00105 #define DNAN0 0xfff80000
00106 #define DNAN1 0
00107 #endif // _PA_RISC1_1
00108 
00109 #ifndef RNAN
00110 #  define RNAN  0xff800001
00111 #  ifdef IEEE_MC68k
00112 #    define DNAN0 0xfff00000
00113 #    define DNAN1 1
00114 #  else
00115 #    define DNAN0 1
00116 #    define DNAN1 0xfff00000
00117 #  endif
00118 #endif /*RNAN*/
00119 
00120 
00121 static unsigned Long rnan = RNAN, dnan0 = DNAN0, dnan1 = DNAN1;
00122 
00123 double _0 = 0.;
00124 
00125 #ifndef MSpc
00126 #  ifdef MSDOS
00127 #    define MSpc
00128 #  else
00129 #    ifdef _WIN32
00130 #      define MSpc
00131 #    endif
00132 #  endif
00133 #endif
00134 
00135 
00136 //
00137 // MSpc
00138 //
00139 
00140 
00141 #ifdef MSpc
00142 
00143 #define IEEE0_done
00144 #include "cfloat"
00145 #include "csignal"
00146 
00147 static void ieee0(bool enableTrap)
00148 {
00149   TEST_FOR_EXCEPTION(
00150     enableTrap == false, std::logic_error,
00151     "Error, don't know how to turn off trap for MSpc!"
00152     );
00153 #ifndef __alpha
00154   _control87(EM_DENORMAL | EM_UNDERFLOW | EM_INEXACT, MCW_EM);
00155 #endif
00156   /* With MS VC++, compiling and linking with -Zi will permit */
00157   /* clicking to invoke the MS C++ debugger, which will show */
00158   /* the point of error -- provided SIGFPE is SIG_DFL. */
00159   signal(SIGFPE, SIG_DFL);
00160 }
00161 
00162 #endif // MSpc
00163 
00164 
00165 //
00166 // MIPS
00167 //
00168 
00169 
00170 #ifdef __mips /* must link with -lfpe */
00171 
00172 #define IEEE0_done
00173 #include <cstdlib>
00174 #include <cstdio>
00175 #include "/usr/include/sigfpe.h"  /* full pathname for lcc -N */
00176 #include "/usr/include/sys/fpu.h"
00177 
00178 static void ieeeuserhand(unsigned std::exception[5], int val[2])
00179 {
00180   fflush(stdout);
00181   fprintf(stderr,"ieee0() aborting because of ");
00182   if(std::exception[0]==_OVERFL) fprintf(stderr,"overflow\n");
00183   else if(std::exception[0]==_UNDERFL) fprintf(stderr,"underflow\n");
00184   else if(std::exception[0]==_DIVZERO) fprintf(stderr,"divide by 0\n");
00185   else if(std::exception[0]==_INVALID) fprintf(stderr,"invalid operation\n");
00186   else fprintf(stderr,"\tunknown reason\n");
00187   fflush(stderr);
00188   abort();
00189 }
00190 
00191 static void ieeeuserhand2(unsigned int **j)
00192 {
00193   fprintf(stderr,"ieee0() aborting because of confusion\n");
00194   abort();
00195 }
00196 
00197 static void ieee0(bool enableTrap)
00198 {
00199   TEST_FOR_EXCEPTION(
00200     enableTrap == false, std::logic_error,
00201     "Error, don't know how to turn off trap for MIPS!"
00202     );
00203   int i;
00204   for(i=1; i<=4; i++){
00205     sigfpe_[i].count = 1000;
00206     sigfpe_[i].trace = 1;
00207     sigfpe_[i].repls = _USER_DETERMINED;
00208     }
00209   sigfpe_[1].repls = _ZERO; /* underflow */
00210   handle_sigfpes( _ON,
00211     _EN_UNDERFL|_EN_OVERFL|_EN_DIVZERO|_EN_INVALID,
00212     ieeeuserhand,_ABORT_ON_ERROR,ieeeuserhand2);
00213   }
00214 #endif /* mips */
00215 
00216 
00217 //
00218 // Linux
00219 //
00220 
00221 
00222 #ifdef __linux__
00223 
00224 #define IEEE0_done
00225 #include "fpu_control.h"
00226 
00227 #ifdef __alpha__
00228 #  ifndef USE_setfpucw
00229 #    define __setfpucw(x) __fpu_control = (x)
00230 #  endif
00231 #endif
00232 
00233 #ifndef _FPU_SETCW
00234 #  undef  Can_use__setfpucw
00235 #  define Can_use__setfpucw
00236 #endif
00237 
00238 static void ieee0(bool enableTrap)
00239 {
00240 
00241   TEST_FOR_EXCEPTION(
00242     enableTrap == false, std::logic_error,
00243     "Error, don't know how to turn off trap for LINUX!"
00244     );
00245 
00246 #if (defined(__mc68000__) || defined(__mc68020__) || defined(mc68020) || defined (__mc68k__))
00247 
00248   /* Reported 20010705 by Alan Bain <alanb@chiark.greenend.org.uk> */
00249   /* Note that IEEE 754 IOP (illegal operation) */
00250   /* = Signaling NAN (SNAN) + operation error (OPERR). */
00251 
00252 #ifdef Can_use__setfpucw /* Has __setfpucw gone missing from S.u.S.E. 6.3? */
00253   __setfpucw(_FPU_IEEE + _FPU_DOUBLE + _FPU_MASK_OPERR + _FPU_MASK_DZ + _FPU_MASK_SNAN + _FPU_MASK_OVFL);
00254 #else
00255   __fpu_control = _FPU_IEEE + _FPU_DOUBLE + _FPU_MASK_OPERR + _FPU_MASK_DZ + _FPU_MASK_SNAN + _FPU_MASK_OVFL;
00256   _FPU_SETCW(__fpu_control);
00257 #endif
00258 
00259 #elif (defined(__powerpc__)||defined(_ARCH_PPC)||defined(_ARCH_PWR)) /* !__mc68k__ */
00260   /* Reported 20011109 by Alan Bain <alanb@chiark.greenend.org.uk> */
00261 
00262 #ifdef Can_use__setfpucw
00263 
00264   /* The following is NOT a mistake -- the author of the fpu_control.h
00265      for the PPC has erroneously defined IEEE mode to turn on exceptions
00266      other than Inexact! Start from default then and turn on only the ones
00267      which we want*/
00268 
00269   __setfpucw(_FPU_DEFAULT +  _FPU_MASK_IM+_FPU_MASK_OM+_FPU_MASK_UM);
00270 
00271 #else /* PPC && !Can_use__setfpucw */
00272 
00273   __fpu_control = _FPU_DEFAULT +_FPU_MASK_OM+_FPU_MASK_IM+_FPU_MASK_UM;
00274   _FPU_SETCW(__fpu_control);
00275 
00276 #endif /*Can_use__setfpucw*/
00277 
00278 #else /* !(mc68000||powerpc) */
00279 
00280 #ifdef _FPU_IEEE
00281 #  ifndef _FPU_EXTENDED /* e.g., ARM processor under Linux */
00282 #  define _FPU_EXTENDED 0
00283 #endif
00284 
00285 #ifndef _FPU_DOUBLE
00286 #  define _FPU_DOUBLE 0
00287 #endif
00288 
00289 #ifdef Can_use__setfpucw /* Has __setfpucw gone missing from S.u.S.E. 6.3? */
00290   __setfpucw(_FPU_IEEE - _FPU_EXTENDED + _FPU_DOUBLE - _FPU_MASK_IM - _FPU_MASK_ZM - _FPU_MASK_OM);
00291 #else
00292   __fpu_control = _FPU_IEEE - _FPU_EXTENDED + _FPU_DOUBLE - _FPU_MASK_IM - _FPU_MASK_ZM - _FPU_MASK_OM;
00293   _FPU_SETCW(__fpu_control);
00294 #endif
00295 
00296 #else /* !_FPU_IEEE */
00297 
00298   TEST_FOR_EXCEPTION(
00299     true, std::logic_error,
00300     "Error, don't know how to trap floating-point errors on this Linux system!"
00301     );
00302 
00303 #endif /* _FPU_IEEE */
00304 
00305 #endif /* __mc68k__ */
00306 
00307 } // ieee0()
00308 
00309 #endif /* __linux__ */
00310 
00311 
00312 //
00313 // Alpha
00314 //
00315 
00316 
00317 #ifdef __alpha
00318 
00319 #ifndef IEEE0_done
00320 
00321 #define IEEE0_done
00322 #include <machine/fpu.h>
00323 
00324 static void ieee0(bool enableTrap)
00325 {
00326   TEST_FOR_EXCEPTION(
00327     enableTrap == false, std::logic_error,
00328     "Error, don't know how to turn off trap for Alpha!"
00329     );
00330   ieee_set_fp_control(IEEE_TRAP_ENABLE_INV);
00331 }
00332 
00333 #endif /*IEEE0_done*/
00334 
00335 #endif /*__alpha*/
00336 
00337 
00338 //
00339 // hpux
00340 //
00341 
00342 
00343 
00344 #ifdef __hpux
00345 
00346 #define IEEE0_done
00347 #define _INCLUDE_HPUX_SOURCE
00348 
00349 #include <cmath>
00350 
00351 #ifndef FP_X_INV
00352 #  include <fenv.h>
00353 #  define fpsetmask fesettrapenable
00354 #  define FP_X_INV FE_INVALID
00355 #endif
00356 
00357 static void ieee0(bool enableTrap)
00358 {
00359   TEST_FOR_EXCEPTION(
00360     enableTrap == false, std::logic_error,
00361     "Error, don't know how to turn off trap for HPUX!"
00362     );
00363   fpsetmask(FP_X_INV);
00364 }
00365 
00366 #endif /*__hpux*/
00367 
00368 
00369 //
00370 // AIX
00371 //
00372 
00373 
00374 #ifdef _AIX
00375 
00376 #define IEEE0_done
00377 #include <fptrap.h>
00378 
00379 static void ieee0(bool enableTrap)
00380 {
00381   TEST_FOR_EXCEPTION(
00382     enableTrap == false, std::logic_error,
00383     "Error, don't know how to turn off trap for AIX!"
00384     );
00385   fp_enable(TRP_INVALID);
00386   fp_trap(FP_TRAP_SYNC);
00387 }
00388 
00389 #endif /*_AIX*/
00390 
00391 
00392 //
00393 // SUN
00394 //
00395 
00396 
00397 #ifdef __sun
00398 
00399 #define IEEE0_done
00400 #include <ieeefp.h>
00401 
00402 static void ieee0(bool enableTrap)
00403 {
00404   TEST_FOR_EXCEPTION(
00405     enableTrap == false, std::logic_error,
00406     "Error, don't know how to turn off trap for SUN!"
00407     );
00408   fpsetmask(FP_X_INV);
00409 }
00410 
00411 #endif // __sun
00412 
00413 
00414 //
00415 // Default (none)
00416 //
00417 
00418 
00419 #ifndef IEEE0_done
00420 
00421 static void ieee0(bool enableTrap)
00422 {
00423   TEST_FOR_EXCEPTION(
00424     true, std::logic_error,
00425     "Error, Don't know how to implement floating-point traps on this platform!"
00426     );
00427 }
00428 
00429 #endif // IEEE0_done
00430 
00431 #endif // 0 // Disabled!
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines