00001
00002
00003
00004
00005
00006
00007
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
00027
00028
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
00057
00058
00059 #if defined(linux)
00060 #if defined(__GLIBC__)&&(__GLIBC__>2 || __GLIBC__==2 && __GLIBC_MINOR__>=1)
00061
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
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
00084 #elif defined(__x86_64__)
00085
00086 #else
00087
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