Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

JobCFloatXImp.cxx

Go to the documentation of this file.
00001 
00002 // $Id: JobCFloatXImp.cxx,v 1.6 2009/09/28 22:28:26 nickd Exp $
00003 //
00004 // Activate floating point exceptions. Code from Jim Kowalkowski
00005 // <jbk@fnal.gov>.
00006 //
00007 // messier@indiana.edu
00009 #include "JobControl/JobCFloatXImp.h"
00010 #include <iostream>
00011 
00012 #if defined(__APPLE__)
00013 #include <fenv.h>
00014 #include <signal.h>
00015 #include <stdlib.h>
00016 #include <string.h>
00017 
00018 void macosx_fpe_handler( int a )
00019 {
00020   std::cerr <<  "Floating point exception! (" 
00021             << strsignal(a)
00022             << ") Aborting!" << std::endl;
00023   exit(1);
00024 }
00025 
00026 // Got this stuff from http://developer.apple.com/documentation/Performance/Conceptual/Mac_OSX_Numerics/
00027 // Mac_OSX_Numerics.pdf
00028 // Nathaniel Tagg, Feb 2006
00029 #define fegetenvd(x) asm volatile("mffs %0" : "=f" (x));
00030 #define fesetenvd(x) asm volatile("mtfsf 255,%0" : : "f" (x));
00031 enum {
00032  FE_ENABLE_INEXACT    = 0x00000008,
00033  FE_ENABLE_DIVBYZERO  = 0x00000010,
00034  FE_ENABLE_UNDERFLOW  = 0x00000020,
00035  FE_ENABLE_OVERFLOW   = 0x00000040,
00036  FE_ENABLE_INVALID    = 0x00000080,
00037  FE_ENABLE_ALL_EXCEPT = 0x000000F8
00038 };
00039 typedef union {
00040  struct {
00041   unsigned long hi;
00042   unsigned long lo;
00043  } i;
00044  double d;
00045 } hexdouble;
00046 
00047 
00048 #endif
00049 
00050 //......................................................................
00051 
00052 JobCFloatXImp::JobCFloatXImp(bool a):activate_(a) 
00053 {
00054   if(activate_==true)
00055   {
00056     // only activate invalid operand, division by zero, and
00057     // overflow exceptions
00058 
00059 #if defined(linux)    
00060 #if defined(__GLIBC__)&&(__GLIBC__>2 || __GLIBC__==2 && __GLIBC_MINOR__>=1)
00061     // use fenv
00062     fenv_t newval;
00063     fegetenv(&old_setting);
00064     fegetenv(&newval);
00065     newval.__control_word &= ~(FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW);
00066     fesetenv(&newval);
00067 #else
00068     // fpu control stuff
00069     old_setting = __fpu_control;
00070     fpu_control_t newval =
00071       old_setting & ~(
00072                       _FPU_MASK_IM
00073                       |_FPU_MASK_ZM
00074                       |_FPU_MASK_OM
00075                       );
00076     
00077     _FPU_SETCW(newval);
00078 #endif
00079 #endif
00080 
00081 #if defined(__APPLE__) 
00082 #if defined(__i386__) 
00083   // for intel chips:
00084 #elif defined(__x86_64__)
00085   // For 64bit apple installations84,85
00086 #else 
00087   // for ppc chips:
00088   hexdouble t;
00089   fegetenvd(t.d);                                
00090   t.i.lo |=  FE_ENABLE_DIVBYZERO | FE_ENABLE_OVERFLOW | FE_ENABLE_INVALID;;
00091   fesetenvd(t.d);
00092   signal(SIGFPE,macosx_fpe_handler);
00093 #endif
00094 #endif
00095 
00096   }
00097 }
00098 
00099 //......................................................................
00100 
00101 JobCFloatXImp::~JobCFloatXImp()
00102 {
00103 #if defined(linux)
00104 if(activate_==true)
00105 #if defined(__GLIBC__)&&(__GLIBC__>2 || __GLIBC__==2 && __GLIBC_MINOR__>=1)
00106   fesetenv(&old_setting);
00107 #else
00108 _FPU_SETCW(old_setting);
00109 #endif
00110 #endif
00111 }
00112 

Generated on Mon Feb 15 11:06:48 2010 for loon by  doxygen 1.3.9.1