static void ieee0(Void) { #ifdef RQD_FPU_STATE #ifndef UNINIT_F2C_PRECISION_53 /* 20051004 */ __fpu_control = RQD_FPU_STATE; _FPU_SETCW(__fpu_control); #else /* unmask invalid, etc., and keep current rounding precision */ fpu_control_t cw; _FPU_GETCW(cw); #ifdef RQD_FPU_CLEAR_MASK cw &= ~ RQD_FPU_CLEAR_MASK; #else cw |= RQD_FPU_MASK; #endif _FPU_SETCW(cw); #endif #else /* !_FPU_IEEE */ fprintf(stderr, "\n%s\n%s\n%s\n%s\n", "WARNING: _uninit_f2c in libf2c does not know how", "to enable trapping on this system, so f2c's -trapuv", "option will not detect uninitialized variables unless", "you can enable trapping manually."); fflush(stderr); #endif /* _FPU_IEEE */ }
void Sys_ConfigureFPU() { // bk001213 - divide by zero #ifdef __linux__ #ifdef __i386 #ifndef NDEBUG // bk0101022 - enable FPE's in debug mode static int fpu_word = _FPU_DEFAULT & ~(_FPU_MASK_ZM | _FPU_MASK_IM); int current = 0; _FPU_GETCW(current); if ( current!=fpu_word) { #if 0 Com_Printf("FPU Control 0x%x (was 0x%x)\n", fpu_word, current ); _FPU_SETCW( fpu_word ); _FPU_GETCW( current ); assert(fpu_word==current); #endif } #else // NDEBUG static int fpu_word = _FPU_DEFAULT; _FPU_SETCW( fpu_word ); #endif // NDEBUG #endif // __i386 #endif // __linux }
/* This might be useful at some point */ void enable_exceptions(bool enable) { #if INCLUDE_FPU_CONTROL const fpu_control_t bits = _FPU_MASK_IM | _FPU_MASK_DM | _FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM; if (enable) { /* generate FP exceptions */ fpu_control_t mask; _FPU_GETCW(mask); mask &= ~bits; _FPU_SETCW(mask); } else { fpu_control_t mask; _FPU_GETCW(mask); mask |= bits; _FPU_SETCW(mask); } #else (void) enable; #endif }
void f(mpfr_t y, mpfr_t xMpfr) { unsigned short oldcw, cw; #if defined(D_TO_D) double x; double resh; #elif defined(D_TO_DD) double x; double resh, resm; #elif defined(D_TO_TD) double x; double resh, resm, resl; #elif defined(DD_TO_DD) double xh, xm; double resh, resm; #elif defined(DD_TO_TD) double xh, xm; double resh, resm, resl; #elif defined (TD_TO_TD) double xh, xm, xl; double resh, resm, resl; #endif _FPU_GETCW(oldcw); cw = (_FPU_DEFAULT & ~_FPU_EXTENDED)|_FPU_DOUBLE; _FPU_SETCW(cw); #if defined(D_TO_D) mpfr_to_double(&x, xMpfr); POLYNOMIALNAME(&resh, x); double_to_mpfr(y, resh); #elif defined(D_TO_DD) mpfr_to_double(&x, xMpfr); POLYNOMIALNAME(&resh, &resm, x); doubledouble_to_mpfr(y, resh, resm); #elif defined(D_TO_TD) mpfr_to_double(&x, xMpfr); POLYNOMIALNAME(&resh, &resm, &resl, x); tripledouble_to_mpfr(y, resh, resm, resl); #elif defined(DD_TO_DD) mpfr_to_doubledouble(&xh, &xm, xMpfr); POLYNOMIALNAME(&resh, &resm, xh, xm); doubledouble_to_mpfr(y, resh, resm); #elif defined(DD_TO_TD) mpfr_to_doubledouble(&xh, &xm, xMpfr); POLYNOMIALNAME(&resh, &resm, &resl, xh, xm); tripledouble_to_mpfr(y, resh, resm, resl); #elif defined(TD_TO_TD) mpfr_to_tripledouble(&xh, &xm, &xl, xMpfr); POLYNOMIALNAME(&resh, &resm, &resl, xh, xm, xl); tripledouble_to_mpfr(y, resh, resm, resl); #else #warning You must define one of the macros for the argument and result formats mpfr_set(y,xMpfr,GMP_RNDN); #endif _FPU_SETCW(oldcw); }
int fesetenv (const fenv_t *envp) { if (envp == FE_DFL_ENV) _FPU_SETCW (_FPU_DEFAULT); else { unsigned long int temp = envp->__fpscr; _FPU_SETCW (temp); } return 0; }
void fpu_fix_end(unsigned int *old_cw) { #ifdef X86 #ifdef _WIN32 #ifdef __BORLANDC__ /* Win 32 Borland C */ if (old_cw) { unsigned short cw = (unsigned short) *old_cw; _control87(cw, 0xFFFF); } #else /* Win 32 MSVC */ if (old_cw) { _control87(*old_cw, 0xFFFFFFFF); } #endif #else /* Linux */ if (old_cw) { int cw; cw = *old_cw; _FPU_SETCW(cw); } #endif #endif }
int __feclearexcept (int excepts) { if (ARM_HAVE_VFP) { unsigned long int temp; /* Mask out unsupported bits/exceptions. */ excepts &= FE_ALL_EXCEPT; /* Get the current floating point status. */ _FPU_GETCW (temp); /* Clear the relevant bits. */ temp = (temp & ~FE_ALL_EXCEPT) | (temp & FE_ALL_EXCEPT & ~excepts); /* Put the new data in effect. */ _FPU_SETCW (temp); /* Success. */ return 0; } /* Unsupported, so fail unless nothing needs to be done. */ return (excepts != 0); }
trapfpe () { /* This enables FPE exception trapping for "common" exceptions: */ fpu_control_t cw= _FPU_DEFAULT & ~(_FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM), ow, nw; /* Whereas this puts the FPU in double precision (as opposed to extended precision) mode: */ cw= (_FPU_DEFAULT & ~(_FPU_EXTENDED | (1<<12))) | _FPU_DOUBLE; if( !getenv( "DEFAULT_FPU") ) { char *c; _FPU_GETCW(ow); _FPU_SETCW( cw ); _FPU_GETCW(nw); if( (c=getenv( "SHOW_FPU")) ) { fprintf( stderr, "FPU state mask: originally 0x%lx, requested 0x%lx, now 0x%lx\n", ow, cw, nw ); if( strncasecmp(c, "verbose", 7)== 0 ) { fprintf( stderr, "\tOriginal mask: %s\n", fpu_mask_string(ow) ); fprintf( stderr, "\tRequested mask: %s\n", fpu_mask_string(cw) ); fprintf( stderr, "\tActual mask: %s\n", fpu_mask_string(nw) ); fprintf( stderr, "\t\t(see fpu_control.h for explanation)\n"); } } } else if( getenv( "SHOW_FPU") ) { _FPU_GETCW(ow); fprintf( stderr, "FPU state mask: 0x%lx\n", ow ); } }
void FPCATCH() { fpu_control_t cw; struct sigaction *p; Step1: /* Set FPHAND as the handler for floating point exceptions. */ p = (struct sigaction *)malloc(sizeof(struct sigaction)); p->sa_handler = (__sighandler_t) FPHAND; sigemptyset(&(p->sa_mask)); p->sa_flags = SA_ONESHOT | SA_SIGINFO; sigaction(SIGFPE,p,NULL); Step2: /* Set exceptions that actually cause traps. This must include overflow and underflow. */ _FPU_GETCW(cw); cw &= ~(_FPU_MASK_IM | _FPU_MASK_DM | _FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM); _FPU_SETCW(cw); Step3: /* Set error flag to zero. */ FPFLAG = 0; Return: /* Prepare to return. */ return; }
int fesetround (int round) { if (ARM_HAVE_VFP) { fpu_control_t temp; switch (round) { case FE_TONEAREST: case FE_UPWARD: case FE_DOWNWARD: case FE_TOWARDZERO: _FPU_GETCW (temp); temp = (temp & ~FE_TOWARDZERO) | round; _FPU_SETCW (temp); return 0; default: return 1; } } else if (round == FE_TONEAREST) /* This is the only supported rounding mode for soft-fp. */ return 0; /* Unsupported, so fail. */ return 1; }
int feholdexcept (fenv_t *envp) { if (GLRO (dl_hwcap) & HWCAP_VFP) { unsigned long int temp; /* Store the environment. */ _FPU_GETCW(temp); envp->__cw = temp; /* Now set all exceptions to non-stop. */ temp &= ~(FE_ALL_EXCEPT << FE_EXCEPT_SHIFT); /* And clear all exception flags. */ temp &= ~FE_ALL_EXCEPT; _FPU_SETCW(temp); return 0; } /* Unsupported, so fail. */ return 1; }
void enable_xp_(void) { /* Set FPU flags to use not double but extended, with rounding to nearest */ short unsigned int cw = (_FPU_DEFAULT & ~_FPU_DOUBLE)|_FPU_EXTENDED; _FPU_SETCW(cw); }
int feenableexcept (int excepts) { fpu_control_t fpscr, new_fpscr, updated_fpscr; /* Fail if a VFP unit isn't present. */ if (!ARM_HAVE_VFP) return -1; _FPU_GETCW (fpscr); excepts &= FE_ALL_EXCEPT; new_fpscr = fpscr | (excepts << FE_EXCEPT_SHIFT); if (new_fpscr != fpscr) { _FPU_SETCW (new_fpscr); /* Not all VFP architectures support trapping exceptions, so test whether the relevant bits were set and fail if not. */ _FPU_GETCW (updated_fpscr); if (new_fpscr & ~updated_fpscr) return -1; } return (fpscr >> FE_EXCEPT_SHIFT) & FE_ALL_EXCEPT; }
int __fesetenv (const fenv_t *envp) { if (GLRO (dl_hwcap) & HWCAP_VFP) { unsigned int temp; _FPU_GETCW (temp); temp &= _FPU_RESERVED; if (envp == FE_DFL_ENV) temp |= _FPU_DEFAULT; else if (envp == FE_NOMASK_ENV) temp |= _FPU_IEEE; else temp |= envp->__cw & ~_FPU_RESERVED; _FPU_SETCW (temp); /* Success. */ return 0; } /* Unsupported, so fail. */ return 1; }
void trapfpe() { unsigned int cw; cw = _FPU_DEFAULT & ~(_FPU_MASK_IM|_FPU_MASK_ZM|_FPU_MASK_UM|_FPU_MASK_OM); _FPU_SETCW(cw); if (0) test_fpe_trapping(); }
int main (int argc, char *argv[]) { #ifdef WITH_FPU_CONTROL fpu_control_t cw; /* cw=895 (0x037f): round to double extended precision cw=639 (0x027f): round to double precision cw=127 (0x007f): round to single precision */ if (argc > 1) { cw = strtol(argv[1], NULL, 0); printf ("FPU control word: 0x%x\n", (unsigned int) cw); _FPU_SETCW (cw); } #endif tests_start_mpfr (); check_special (); check_large (); check_small (); tests_end_mpfr (); return 0; }
void fpu_fix_start(unsigned int *old_cw) { #ifdef X86 #ifdef _WIN32 #ifdef __BORLANDC__ /* Win 32 Borland C */ unsigned short cw = _control87(0, 0); _control87(0x0200, 0x0300); if (old_cw) { *old_cw = cw; } #else /* Win 32 MSVC */ unsigned int cw = _control87(0, 0); _control87(0x00010000, 0x00030000); if (old_cw) { *old_cw = cw; } #endif #else /* Linux */ int cw, new_cw; _FPU_GETCW(cw); new_cw = (cw & ~_FPU_EXTENDED) | _FPU_DOUBLE; _FPU_SETCW(new_cw); if (old_cw) { *old_cw = cw; } #endif #endif }
int fesetenv (const fenv_t *envp) { fpu_control_t fpcr; fpu_fpsr_t fpsr; _FPU_GETCW (fpcr); _FPU_GETFPSR (fpsr); fpcr &= _FPU_RESERVED; fpsr &= _FPU_FPSR_RESERVED; if (envp == FE_DFL_ENV) { fpcr |= _FPU_DEFAULT; fpsr |= _FPU_FPSR_DEFAULT; } else if (envp == FE_NOMASK_ENV) { fpcr |= _FPU_FPCR_IEEE; fpsr |= _FPU_FPSR_IEEE; } else { fpcr |= envp->__fpcr & ~_FPU_RESERVED; fpsr |= envp->__fpsr & ~_FPU_FPSR_RESERVED; } _FPU_SETFPSR (fpsr); _FPU_SETCW (fpcr); return 0; }
_Float32x __f32xsubf64 (_Float64 x, _Float64 y) { /* To avoid double rounding, set double precision for the subtraction. math_narrow_eval is still needed to eliminate excess range in the case of overflow. If the result of the subtraction is in the subnormal range for double, it is exact, so no issues of double rounding for subnormals arise. */ fpu_control_t cw, cw_double; _FPU_GETCW (cw); cw_double = (cw & ~_FPU_EXTENDED) | _FPU_DOUBLE; _FPU_SETCW (cw_double); _Float32x ret = math_narrow_eval (x - y); _FPU_SETCW (cw); CHECK_NARROW_SUB (ret, x, y); return ret; }
int fesetenv (const fenv_t *envp) { fpu_control_t cw; /* Read first current state to flush fpu pipeline. */ _FPU_GETCW (cw); if (envp == FE_DFL_ENV) _FPU_SETCW (_FPU_DEFAULT); else if (envp == FE_NOMASK_ENV) _FPU_SETCW (_FPU_IEEE); else _FPU_SETCW (envp->__fp_control_register); /* Success. */ return 0; }
static void detect_denormals() { #include <fpu_control.h> int cw = 0; _FPU_GETCW(cw); cw &= ~_FPU_MASK_DM; _FPU_SETCW(cw); }
set_fast_math (void) { unsigned int fcr; /* Flush to zero, round to nearest, IEEE exceptions disabled. */ fcr = _FPU_FLUSH_TZ | _FPU_RC_NEAREST; _FPU_SETCW(fcr); }
void Sys_ConfigureFPU() { // bk001213 - divide by zero #ifdef __linux__ #ifdef __i386 #ifdef NDEBUG static int fpu_word = _FPU_DEFAULT; _FPU_SETCW( fpu_word ); #endif // NDEBUG #endif // __i386 #endif // __linux }
static void set_fpu_prec (void) { fpu_control_t cw; _FPU_GETCW(cw); cw &= ~(_FPU_EXTENDED|_FPU_DOUBLE|_FPU_SINGLE); cw |= (MPFR_FPU_PREC); _FPU_SETCW(cw); }
int feholdexcept (fenv_t *envp) { /* Store the environment. */ fegetenv (envp); /* Clear the current sticky bits as more than one exception may be generated. */ envp->fpc &= ~(FPC_FLAGS_MASK | FPC_DXC_MASK); /* Hold from generating fpu exceptions temporarily. */ _FPU_SETCW ((envp->fpc & ~(FE_ALL_EXCEPT << FPC_EXCEPTION_MASK_SHIFT))); return 0; }
int fesetmode (const femode_t *modep) { femode_t mode; if (modep == FE_DFL_MODE) mode = _FPU_DEFAULT; else mode = *modep; _FPU_SETCW (mode); return 0; }
/** * Set the debugging flags. * * \param debug debug string * * If compiled with debugging support then search for keywords in \p debug and * enables the verbose debug output of the respective feature. */ static void add_debug_flags( const char *debug ) { #ifdef DEBUG if (_mesa_strstr(debug, "varray")) MESA_VERBOSE |= VERBOSE_VARRAY; if (_mesa_strstr(debug, "tex")) MESA_VERBOSE |= VERBOSE_TEXTURE; if (_mesa_strstr(debug, "imm")) MESA_VERBOSE |= VERBOSE_IMMEDIATE; if (_mesa_strstr(debug, "pipe")) MESA_VERBOSE |= VERBOSE_PIPELINE; if (_mesa_strstr(debug, "driver")) MESA_VERBOSE |= VERBOSE_DRIVER; if (_mesa_strstr(debug, "state")) MESA_VERBOSE |= VERBOSE_STATE; if (_mesa_strstr(debug, "api")) MESA_VERBOSE |= VERBOSE_API; if (_mesa_strstr(debug, "list")) MESA_VERBOSE |= VERBOSE_DISPLAY_LIST; if (_mesa_strstr(debug, "lighting")) MESA_VERBOSE |= VERBOSE_LIGHTING; if (_mesa_strstr(debug, "disassem")) MESA_VERBOSE |= VERBOSE_DISASSEM; /* Debug flag: */ if (_mesa_strstr(debug, "flush")) MESA_DEBUG_FLAGS |= DEBUG_ALWAYS_FLUSH; #if defined(_FPU_GETCW) && defined(_FPU_SETCW) if (_mesa_strstr(debug, "fpexceptions")) { /* raise FP exceptions */ fpu_control_t mask; _FPU_GETCW(mask); mask &= ~(_FPU_MASK_IM | _FPU_MASK_DM | _FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM); _FPU_SETCW(mask); } #endif #else (void) debug; #endif }
int fedisableexcept (int excepts) { fexcept_t temp, old_exc, new_flags; _FPU_GETCW (temp); old_exc = (temp & FPC_EXCEPTION_MASK) >> FPC_EXCEPTION_MASK_SHIFT; new_flags = (temp & (~((excepts & FE_ALL_EXCEPT) << FPC_EXCEPTION_MASK_SHIFT))); _FPU_SETCW (new_flags); return old_exc; }
static unsigned int _controlfp(unsigned int val, unsigned int mask) { unsigned int ret; _FPU_GETCW(ret); if (mask) { ret&=~mask; ret|=val; _FPU_SETCW(ret); } return ret; }
int fesetmode (const femode_t *modep) { fpu_control_t fpcr, fpcr_new; _FPU_GETCW (fpcr); if (modep == FE_DFL_MODE) fpcr_new = (fpcr & _FPU_RESERVED) | _FPU_DEFAULT; else fpcr_new = *modep; if (fpcr != fpcr_new) _FPU_SETCW (fpcr_new); return 0; }