Go to the documentation of this file.00001 #ifndef ApproxMVBB_GeometryPredicates_xpfpa_h
00002 #define ApproxMVBB_GeometryPredicates_xpfpa_h
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #ifndef XPFPA_H
00037 #define XPFPA_H
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 #ifdef _MSC_VER
00060 # if _MSC_VER >= 1500
00061
00062 # define HAVE__CONTROLFP_S
00063 # else
00064
00065 # define HAVE__CONTROLFP
00066 # endif // MSC_VER >= 1500
00067
00068 # pragma fenv_access (on)
00069 #endif // _MSC_VER
00070
00071
00072
00073 #if defined(_MSC_VER) && defined(_WIN64 )
00074
00075 # define XPFPA_DECLARE()
00076 # define XPFPA_SWITCH_DOUBLE()
00077 # define XPFPA_SWITCH_SINGLE()
00078 # define XPFPA_SWITCH_DOUBLE_EXTENDED()
00079 # define XPFPA_RESTORE()
00080 # define XPFPA_RETURN_DOUBLE(val) return (val);
00081 # define XPFPA_RETURN_SINGLE(val) return (val);
00082 # define XPFPA_RETURN_DOUBLE_EXTENDED(val) return (val);
00083
00084 #elif HAVE__CONTROLFP_S
00085
00086
00087 # include <float.h>
00088
00089 # define XPFPA_DECLARE() \
00090 static unsigned int _xpfpa_fpu_oldcw, _xpfpa_fpu_cw;
00091
00092 # define XPFPA_SWITCH_DOUBLE() \
00093 _controlfp_s(&_xpfpa_fpu_cw, 0, 0); \
00094 _xpfpa_fpu_oldcw = _xpfpa_fpu_cw; \
00095 _controlfp_s(&_xpfpa_fpu_cw, _PC_53, _MCW_PC);
00096 # define XPFPA_SWITCH_SINGLE() \
00097 _controlfp_s(&_xpfpa_fpu_cw, 0, 0); \
00098 _xpfpa_fpu_oldcw = _xpfpa_fpu_cw; \
00099 _controlfp_s(&_xpfpa_fpu_cw, _PC_24, _MCW_PC);
00100
00101
00102 # define XPFPA_SWITCH_DOUBLE_EXTENDED() \
00103 _controlfp_s(&_xpfpa_fpu_cw, 0, 0); \
00104 _xpfpa_fpu_oldcw = _xpfpa_fpu_cw; \
00105 _controlfp_s(&_xpfpa_fpu_cw, _PC_64, _MCW_PC);
00106 # define XPFPA_RESTORE() \
00107 _controlfp_s(&_xpfpa_fpu_cw, _xpfpa_fpu_oldcw, _MCW_PC);
00108
00109
00110
00111
00112 # define XPFPA_RETURN_DOUBLE(val) \
00113 { \
00114 double _xpfpa_result = (val); \
00115 XPFPA_RESTORE() \
00116 return _xpfpa_result; \
00117 }
00118 # define XPFPA_RETURN_SINGLE(val) \
00119 { \
00120 float _xpfpa_result = (val); \
00121 XPFPA_RESTORE() \
00122 return _xpfpa_result; \
00123 }
00124
00125 # define XPFPA_RETURN_DOUBLE_EXTENDED(val) \
00126 { \
00127 long double _xpfpa_result = (val); \
00128 XPFPA_RESTORE() \
00129 return _xpfpa_result; \
00130 }
00131
00132 #elif defined(HAVE__CONTROLFP)
00133
00134
00135 # include <float.h>
00136
00137 # define XPFPA_DECLARE() \
00138 static unsigned int _xpfpa_fpu_oldcw;
00139
00140 # define XPFPA_SWITCH_DOUBLE() \
00141 _xpfpa_fpu_oldcw = _controlfp(0, 0); \
00142 _controlfp(_PC_53, _MCW_PC);
00143 # define XPFPA_SWITCH_SINGLE() \
00144 _xpfpa_fpu_oldcw = _controlfp(0, 0); \
00145 _controlfp(_PC_24, _MCW_PC);
00146
00147 # define XPFPA_SWITCH_DOUBLE_EXTENDED() \
00148 _xpfpa_fpu_oldcw = _controlfp(0, 0); \
00149 _controlfp(_PC_64, _MCW_PC);
00150 # define XPFPA_RESTORE() \
00151 _controlfp(_xpfpa_fpu_oldcw, _MCW_PC);
00152
00153
00154
00155
00156 # define XPFPA_RETURN_DOUBLE(val) \
00157 { \
00158 double _xpfpa_result = (val); \
00159 XPFPA_RESTORE() \
00160 return _xpfpa_result; \
00161 }
00162 # define XPFPA_RETURN_SINGLE(val) \
00163 { \
00164 float _xpfpa_result = (val); \
00165 XPFPA_RESTORE() \
00166 return _xpfpa_result; \
00167 }
00168
00169 # define XPFPA_RETURN_DOUBLE_EXTENDED(val) \
00170 { \
00171 long double _xpfpa_result = (val); \
00172 XPFPA_RESTORE() \
00173 return _xpfpa_result; \
00174 }
00175
00176 #elif defined(HAVE__FPU_SETCW) // glibc systems
00177
00178
00179 # include <fpu_control.h>
00180
00181 # define XPFPA_DECLARE() \
00182 static fpu_control_t _xpfpa_fpu_oldcw, _xpfpa_fpu_cw;
00183
00184 # define XPFPA_SWITCH_DOUBLE() \
00185 _FPU_GETCW(_xpfpa_fpu_oldcw); \
00186 _xpfpa_fpu_cw = (_xpfpa_fpu_oldcw & ~_FPU_EXTENDED & ~_FPU_SINGLE) | _FPU_DOUBLE; \
00187 _FPU_SETCW(_xpfpa_fpu_cw);
00188 # define XPFPA_SWITCH_SINGLE() \
00189 _FPU_GETCW(_xpfpa_fpu_oldcw); \
00190 _xpfpa_fpu_cw = (_xpfpa_fpu_oldcw & ~_FPU_EXTENDED & ~_FPU_DOUBLE) | _FPU_SINGLE; \
00191 _FPU_SETCW(_xpfpa_fpu_cw);
00192 # define XPFPA_SWITCH_DOUBLE_EXTENDED() \
00193 _FPU_GETCW(_xpfpa_fpu_oldcw); \
00194 _xpfpa_fpu_cw = (_xpfpa_fpu_oldcw & ~_FPU_SINGLE & ~_FPU_DOUBLE) | _FPU_EXTENDED; \
00195 _FPU_SETCW(_xpfpa_fpu_cw);
00196 # define XPFPA_RESTORE() \
00197 _FPU_SETCW(_xpfpa_fpu_oldcw);
00198
00199
00200
00201 # define XPFPA_RETURN_DOUBLE(val) \
00202 { \
00203 volatile double _xpfpa_result = (val); \
00204 XPFPA_RESTORE() \
00205 return _xpfpa_result; \
00206 }
00207 # define XPFPA_RETURN_SINGLE(val) \
00208 { \
00209 volatile float _xpfpa_result = (val); \
00210 XPFPA_RESTORE() \
00211 return _xpfpa_result; \
00212 }
00213 # define XPFPA_RETURN_DOUBLE_EXTENDED(val) \
00214 { \
00215 volatile long double _xpfpa_result = (val); \
00216 XPFPA_RESTORE() \
00217 return _xpfpa_result; \
00218 }
00219
00220 #elif defined(HAVE_FPSETPREC) // FreeBSD
00221
00222
00223 # include <machine/ieeefp.h>
00224
00225 # define XPFPA_DECLARE() \
00226 static fp_prec_t _xpfpa_fpu_oldprec;
00227
00228 # define XPFPA_SWITCH_DOUBLE() \
00229 _xpfpa_fpu_oldprec = fpgetprec(); \
00230 fpsetprec(FP_PD);
00231 # define XPFPA_SWITCH_SINGLE() \
00232 _xpfpa_fpu_oldprec = fpgetprec(); \
00233 fpsetprec(FP_PS);
00234 # define XPFPA_SWITCH_DOUBLE_EXTENDED() \
00235 _xpfpa_fpu_oldprec = fpgetprec(); \
00236 fpsetprec(FP_PE);
00237 # define XPFPA_RESTORE() \
00238 fpsetprec(_xpfpa_fpu_oldprec);
00239
00240
00241
00242 # define XPFPA_RETURN_DOUBLE(val) \
00243 { \
00244 volatile double _xpfpa_result = (val); \
00245 XPFPA_RESTORE() \
00246 return _xpfpa_result; \
00247 }
00248 # define XPFPA_RETURN_SINGLE(val) \
00249 { \
00250 volatile float _xpfpa_result = (val); \
00251 XPFPA_RESTORE() \
00252 return _xpfpa_result; \
00253 }
00254 # define XPFPA_RETURN_DOUBLE_EXTENDED(val) \
00255 { \
00256 volatile long double _xpfpa_result = (val); \
00257 XPFPA_RESTORE() \
00258 return _xpfpa_result; \
00259 }
00260
00261 #elif defined(HAVE_FPU_INLINE_ASM_X86)
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 # define XPFPA_DECLARE() \
00286 static unsigned int _xpfpa_fpu_oldcw, _xpfpa_fpu_cw;
00287
00288 # define XPFPA_SWITCH_DOUBLE() \
00289 __asm__ __volatile__ ("fnstcw %0" : "=m" (*&_xpfpa_fpu_oldcw)); \
00290 _xpfpa_fpu_cw = (_xpfpa_fpu_oldcw & ~0x100) | 0x200; \
00291 __asm__ __volatile__ ("fldcw %0" : : "m" (*&_xpfpa_fpu_cw));
00292 # define XPFPA_SWITCH_SINGLE() \
00293 __asm__ __volatile__ ("fnstcw %0" : "=m" (*&_xpfpa_fpu_oldcw)); \
00294 _xpfpa_fpu_cw = (_xpfpa_fpu_oldcw & ~0x300); \
00295 __asm__ __volatile__ ("fldcw %0" : : "m" (*&_xpfpa_fpu_cw));
00296 # define XPFPA_SWITCH_DOUBLE_EXTENDED() \
00297 __asm__ __volatile__ ("fnstcw %0" : "=m" (*&_xpfpa_fpu_oldcw)); \
00298 _xpfpa_fpu_cw = _xpfpa_fpu_oldcw | 0x300; \
00299 __asm__ __volatile__ ("fldcw %0" : : "m" (*&_xpfpa_fpu_cw));
00300 # define XPFPA_RESTORE() \
00301 __asm__ __volatile__ ("fldcw %0" : : "m" (*&_xpfpa_fpu_oldcw));
00302
00303
00304
00305 # define XPFPA_RETURN_DOUBLE(val) \
00306 { \
00307 volatile double _xpfpa_result = (val); \
00308 XPFPA_RESTORE() \
00309 return _xpfpa_result; \
00310 }
00311 # define XPFPA_RETURN_SINGLE(val) \
00312 { \
00313 volatile float _xpfpa_result = (val); \
00314 XPFPA_RESTORE() \
00315 return _xpfpa_result; \
00316 }
00317 # define XPFPA_RETURN_DOUBLE_EXTENDED(val) \
00318 { \
00319 volatile long double _xpfpa_result = (val); \
00320 XPFPA_RESTORE() \
00321 return _xpfpa_result; \
00322 }
00323
00324 #else // FPU CONTROL
00325
00326
00327
00328
00329
00330
00331 # define XPFPA_DECLARE()
00332 # define XPFPA_SWITCH_DOUBLE()
00333 # define XPFPA_SWITCH_SINGLE()
00334 # define XPFPA_SWITCH_DOUBLE_EXTENDED()
00335 # define XPFPA_RESTORE()
00336 # define XPFPA_RETURN_DOUBLE(val) return (val);
00337 # define XPFPA_RETURN_SINGLE(val) return (val);
00338 # define XPFPA_RETURN_DOUBLE_EXTENDED(val) return (val);
00339
00340 #endif // FPU CONTROL
00341
00342 #endif // XPFPA_H
00343
00344 #endif // header guard