int test_settings(void) { int failures = 0; fp_except mask_orig; printf("Testing settings on the chip... "); fflush(stdout); fpsetround(FP_RM); if(fpgetround() != FP_RM) FAIL_TEST; fpsetround(FP_RP); if(fpgetround() != FP_RP) FAIL_TEST; fpsetround(FP_RZ); if(fpgetround() != FP_RZ) FAIL_TEST; fpsetround(FP_RN); if(fpgetround() != FP_RN) FAIL_TEST; fpsetsticky(FP_X_INV | FP_X_DZ | FP_X_IMP); if(fpgetsticky() != (FP_X_INV | FP_X_DZ | FP_X_IMP)) FAIL_TEST; fpsetsticky(FP_X_OFL | FP_X_IMP); if(fpgetsticky() != (FP_X_OFL | FP_X_IMP)) FAIL_TEST; fpsetsticky(FP_X_UFL | FP_X_DZ); if(fpgetsticky() != (FP_X_UFL | FP_X_DZ)) FAIL_TEST; fpsetsticky(0); if(fpgetsticky() != 0) FAIL_TEST; mask_orig = fpsetmask(FP_X_INV | FP_X_DZ); if(fpgetmask() != (FP_X_INV | FP_X_DZ)) FAIL_TEST; fpsetmask(FP_X_OFL | FP_X_IMP); if(fpgetmask() != (FP_X_OFL | FP_X_IMP)) FAIL_TEST; fpsetmask(FP_X_UFL | FP_X_DZ | FP_X_INV); if(fpgetmask() != (FP_X_UFL | FP_X_DZ | FP_X_INV)) FAIL_TEST; fpsetmask(mask_orig); if(fpgetmask() != mask_orig) FAIL_TEST; #ifdef __CYGWIN__ fpsetprecision(FP_PC_SGL); if(fpgetprecision() != FP_PC_SGL) FAIL_TEST; fpsetprecision(FP_PC_DBL); if(fpgetprecision() != FP_PC_DBL) FAIL_TEST; fpsetprecision(FP_PC_EXT); if(fpgetprecision() != FP_PC_EXT) FAIL_TEST; #endif if(failures == 0) { printf(" PASSED\n"); return 0; } else { printf(" %d failures\n", failures); return 1; } }
/* * The feraiseexcept() function shall attempt to raise the supported * floating-point exceptions represented by the argument excepts. The order * in which these floating-point exceptions are raised is unspecified. */ int feraiseexcept(int excepts) { #ifndef lint _DIAGASSERT((except & ~FE_ALL_EXCEPT) == 0); #endif #ifdef __SOFTFP__ excepts &= fpgetsticky(); if (excepts) { siginfo_t info; memset(&info, 0, sizeof info); info.si_signo = SIGFPE; info.si_pid = getpid(); info.si_uid = geteuid(); if (excepts & FE_UNDERFLOW) info.si_code = FPE_FLTUND; else if (excepts & FE_OVERFLOW) info.si_code = FPE_FLTOVF; else if (excepts & FE_DIVBYZERO) info.si_code = FPE_FLTDIV; else if (excepts & FE_INVALID) info.si_code = FPE_FLTINV; else if (excepts & FE_INEXACT) info.si_code = FPE_FLTRES; sigqueueinfo(getpid(), &info); } #else int fpscr = armreg_fpscr_read(); fpscr = (fpscr & ~VFP_FPSCR_ESUM) | __SHIFTIN(excepts, VFP_FPSCR_ESUM); armreg_fpscr_write(fpscr); #endif return 0; }
/* * The fetestexcept() function shall determine which of a specified subset of * the floating-point exception flags are currently set. The excepts argument * specifies the floating-point status flags to be queried. */ int fetestexcept(int excepts) { _DIAGASSERT((except & ~FE_ALL_EXCEPT) == 0); #ifdef __SOFTFP__ return fpgetsticky() & excepts; #else return __SHIFTOUT(armreg_fpscr_read(), VFP_FPSCR_CSUM) & excepts; #endif }
static PyObject *turnoff_sigfpe(PyObject *self,PyObject *args) { #ifdef __FreeBSD__ fpresetsticky(fpgetsticky()); fpsetmask(0); #else fputs("Operation not implemented\n", stderr); #endif Py_RETURN_NONE; }
/* update the current exceptions: */ static void _tme_float_exceptions_update(int at_least_one) { int exceptions_new; #ifdef HAVE_FPGETSTICKY int sticky; #endif /* HAVE_FPGETSTICKY */ /* start with no new exceptions: */ exceptions_new = 0; /* get the exception status: */ #ifdef HAVE_FPGETSTICKY sticky = fpgetsticky(); #define TME_FP_X_MAP(fp_x, float_x) if (sticky & (fp_x)) exceptions_new |= (float_x) #ifdef FP_X_INV TME_FP_X_MAP(FP_X_INV, TME_FLOAT_EXCEPTION_INVALID); #endif #ifdef FP_X_DNML TME_FP_X_MAP(FP_X_DNML, TME_FLOAT_EXCEPTION_DENORMAL); #endif #ifdef FP_X_DZ TME_FP_X_MAP(FP_X_DZ, TME_FLOAT_EXCEPTION_DIVBYZERO); #endif #ifdef FP_X_OFL TME_FP_X_MAP(FP_X_OFL, TME_FLOAT_EXCEPTION_OVERFLOW); #endif #ifdef FP_X_UFL TME_FP_X_MAP(FP_X_UFL, TME_FLOAT_EXCEPTION_UNDERFLOW); #endif #ifdef FP_X_IMP TME_FP_X_MAP(FP_X_IMP, TME_FLOAT_EXCEPTION_INEXACT); #endif #ifdef FP_X_IOV TME_FP_X_MAP(FP_X_IOV, TME_FLOAT_EXCEPTION_OVERFLOW_INT); #endif #undef TME_FP_X_MAP #endif /* HAVE_FPGETSTICKY */ /* if we have no new exceptions, but we should have at least one, add in the generic exception: */ if (exceptions_new == 0 && at_least_one) { exceptions_new |= TME_FLOAT_EXCEPTION_GENERIC; } /* accumulate the new exceptions into the current exceptions: */ _tme_float_exceptions |= exceptions_new; /* clear the exception status: */ #ifdef HAVE_FPSETSTICKY fpsetsticky(0); #endif /* HAVE_FPSETSTICKY */ }
/* * The fegetexceptflag() function shall attempt to store an * implementation-defined representation of the states of the floating-point * status flags indicated by the argument excepts in the object pointed to by * the argument flagp. */ int fegetexceptflag(fexcept_t *flagp, int excepts) { _DIAGASSERT((except & ~FE_ALL_EXCEPT) == 0); #ifdef __SOFTFP__ *flagp = fpgetsticky() & excepts; #else *flagp = __SHIFTOUT(armreg_fpscr_read(), VFP_FPSCR_CSUM) & excepts; #endif return 0; }
/* * The fegetenv() function shall attempt to store the current floating-point * environment in the object pointed to by envp. */ int fegetenv(fenv_t *envp) { #ifdef __SOFTFP__ *envp = __SHIFTIN(fpgetround(), VFP_FPSCR_RMODE) | __SHIFTIN(fpgetmask(), VFP_FPSCR_ESUM) | __SHIFTIN(fpgetsticky(), VFP_FPSCR_CSUM); #else *envp = armreg_fpscr_read(); #endif return 0; }
/* * The feclearexcept() function shall attempt to clear the supported * floating-point exceptions represented by excepts. */ int feclearexcept(int excepts) { #ifndef lint _DIAGASSERT((except & ~FE_ALL_EXCEPT) == 0); #endif #ifdef __SOFTFP__ fpsetsticky(fpgetsticky() & ~excepts); return 0; #else int tmp = armreg_fpscr_read() & ~__SHIFTIN(excepts, VFP_FPSCR_CSUM); armreg_fpscr_write(tmp); return 0; #endif }
/* * The feholdexcept() function shall save the current floating-point * environment in the object pointed to by envp, clear the floating-point * status flags, and then install a non-stop (continue on floating-point * exceptions) mode, if available, for all floating-point exceptions. */ int feholdexcept(fenv_t *envp) { #ifdef __SOFTFP__ *envp = __SHIFTIN(fpgetround(), VFP_FPSCR_RMODE) | __SHIFTIN(fpgetmask(), VFP_FPSCR_ESUM) | __SHIFTIN(fpgetsticky(), VFP_FPSCR_CSUM); fpsetmask(0); fpsetsticky(0); #else *envp = armreg_fpscr_read(); armreg_fpscr_write((*envp) & ~(VFP_FPSCR_ESUM|VFP_FPSCR_CSUM)); #endif return 0; }
/* * The fesetexceptflag() function shall attempt to set the floating-point * status flags indicated by the argument excepts to the states stored in the * object pointed to by flagp. The value pointed to by flagp shall have been * set by a previous call to fegetexceptflag() whose second argument * represented at least those floating-point exceptions represented by the * argument excepts. This function does not raise floating-point exceptions, * but only sets the state of the flags. */ int fesetexceptflag(const fexcept_t *flagp, int excepts) { #ifndef lint _DIAGASSERT((except & ~FE_ALL_EXCEPT) == 0); #endif #ifdef __SOFTFP__ fpsetsticky((fpgetsticky() & ~excepts) | (excepts & *flagp)); #else int fpscr = armreg_fpscr_read(); fpscr &= ~__SHIFTIN(excepts, VFP_FPSCR_CSUM); fpscr |= __SHIFTIN((*flagp & excepts), VFP_FPSCR_CSUM); armreg_fpscr_write(fpscr); #endif return 0; }
static PyObject *turnoff_sigfpe(PyObject *self,PyObject *args) { #ifdef __FreeBSD__ fpresetsticky(fpgetsticky()); fpsetmask(0); #elif defined(__VMS) IEEE clrmsk; clrmsk.ieee$q_flags = IEEE$M_TRAP_ENABLE_UNF | IEEE$M_TRAP_ENABLE_INE | IEEE$M_MAP_UMZ | IEEE$M_TRAP_ENABLE_INV | IEEE$M_TRAP_ENABLE_DZE | IEEE$M_TRAP_ENABLE_OVF | IEEE$M_INHERIT; sys$ieee_set_fp_control(&clrmsk, 0, 0); #else fputs("Operation not implemented\n", stderr); #endif Py_INCREF(Py_None); return Py_None; }
/* * The feupdateenv() function shall attempt to save the currently raised * floating-point exceptions in its automatic storage, attempt to install the * floating-point environment represented by the object pointed to by envp, * and then attempt to raise the saved floating-point exceptions. */ int feupdateenv(const fenv_t *envp) { #ifndef lint _DIAGASSERT(envp != NULL); #endif #ifdef __SOFTFP__ (void)fpsetround(__SHIFTIN(*envp, VFP_FPSCR_RMODE)); (void)fpsetmask(fpgetmask() | __SHIFTOUT(*envp, VFP_FPSCR_ESUM)); (void)fpsetsticky(fpgetsticky() | __SHIFTOUT(*envp, VFP_FPSCR_CSUM)); #else int fpscr = armreg_fpscr_read() & ~(VFP_FPSCR_ESUM|VFP_FPSCR_CSUM); fpscr |= *envp; armreg_fpscr_write(fpscr); #endif /* Success */ return 0; }
int test_sticky(void) { double ans; int failures = 0; printf("Testing sticky bits... "); fflush(stdout); fpsetsticky(0); ans = two / three; if((fpgetsticky() & FP_X_IMP) != FP_X_IMP) FAIL_TEST; fpsetsticky(0); ans = DBL_MIN / three; if((fpgetsticky() & FP_X_UFL) != FP_X_UFL) FAIL_TEST; #ifdef __CYGWIN__ ans = ans / three; if((fpgetsticky() & FP_X_DNML) != FP_X_DNML) FAIL_TEST; #endif fpsetsticky(0); ans = DBL_MAX * three; if((fpgetsticky() & FP_X_OFL) != FP_X_OFL) FAIL_TEST; fpsetsticky(0); ans = one / zero; if((fpgetsticky() & FP_X_DZ) != FP_X_DZ) FAIL_TEST; fpsetsticky(0); ans = sqrt(negone); if((fpgetsticky() & FP_X_INV) != FP_X_INV) FAIL_TEST; fpsetsticky(0); if(failures == 0) { printf(" PASSED\n"); return 0; } else { printf(" %d failures\n", failures); return 1; } }
static void fpe_reset(Sigfunc *handler) { /* Reset the exception handling machinery, and reset the signal * handler for SIGFPE to the given handler. */ /*-- SunOS and Solaris ----------------------------------------------------*/ #if defined(sun) /* References: ieee_handler, ieee_sun, ieee_functions, and ieee_flags man pages (SunOS or Solaris) cc -c -I/usr/local/python/include fpectlmodule.c ld -G -o fpectlmodule.so -L/opt/SUNWspro/lib fpectlmodule.o -lsunmath -lm */ #include <math.h> #ifndef _SUNMATH_H extern void nonstandard_arithmetic(void); extern int ieee_flags(const char*, const char*, const char*, char **); extern long ieee_handler(const char*, const char*, sigfpe_handler_type); #endif char *mode="exception", *in="all", *out; (void) nonstandard_arithmetic(); (void) ieee_flags("clearall",mode,in,&out); (void) ieee_handler("set","common",(sigfpe_handler_type)handler); PyOS_setsig(SIGFPE, handler); /*-- HPUX -----------------------------------------------------------------*/ #elif defined(__hppa) || defined(hppa) /* References: fpsetmask man page */ /* cc -Aa +z -c -I/usr/local/python/include fpectlmodule.c */ /* ld -b -o fpectlmodule.sl fpectlmodule.o -lm */ #include <math.h> fpsetdefaults(); PyOS_setsig(SIGFPE, handler); /*-- IBM AIX --------------------------------------------------------------*/ #elif defined(__AIX) || defined(_AIX) /* References: fp_trap, fp_enable man pages */ #include <fptrap.h> fp_trap(FP_TRAP_SYNC); fp_enable(TRP_INVALID | TRP_DIV_BY_ZERO | TRP_OVERFLOW); PyOS_setsig(SIGFPE, handler); /*-- DEC ALPHA LINUX ------------------------------------------------------*/ #elif defined(__alpha) && defined(linux) #include <asm/fpu.h> unsigned long fp_control = IEEE_TRAP_ENABLE_INV | IEEE_TRAP_ENABLE_DZE | IEEE_TRAP_ENABLE_OVF; ieee_set_fp_control(fp_control); PyOS_setsig(SIGFPE, handler); /*-- Cray Unicos ----------------------------------------------------------*/ #elif defined(cray) /* UNICOS delivers SIGFPE by default, but no matherr */ #ifdef HAS_LIBMSET libmset(-1); #endif PyOS_setsig(SIGFPE, handler); /*-- FreeBSD ----------------------------------------------------------------*/ #elif defined(__FreeBSD__) fpresetsticky(fpgetsticky()); fpsetmask(FP_X_INV | FP_X_DZ | FP_X_OFL); PyOS_setsig(SIGFPE, handler); /*-- Linux ----------------------------------------------------------------*/ #elif defined(linux) #ifdef __GLIBC__ #include <fpu_control.h> #else #include <i386/fpu_control.h> #endif #ifdef _FPU_SETCW { fpu_control_t cw = 0x1372; _FPU_SETCW(cw); } #else __setfpucw(0x1372); #endif PyOS_setsig(SIGFPE, handler); /*-- Microsoft Windows, NT ------------------------------------------------*/ #elif defined(_MSC_VER) /* Reference: Visual C++ Books Online 4.2, Run-Time Library Reference, _control87, _controlfp */ #include <float.h> unsigned int cw = _EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW; (void)_controlfp(0, cw); PyOS_setsig(SIGFPE, handler); /*-- Give Up --------------------------------------------------------------*/ #else fputs("Operation not implemented\n", stderr); #endif }
static void fpe_reset(Sigfunc *handler) { /* Reset the exception handling machinery, and reset the signal * handler for SIGFPE to the given handler. */ /*-- IRIX -----------------------------------------------------------------*/ #if defined(sgi) /* See man page on handle_sigfpes -- must link with -lfpe * My usage doesn't follow the man page exactly. Maybe somebody * else can explain handle_sigfpes to me.... * cc -c -I/usr/local/python/include fpectlmodule.c * ld -shared -o fpectlmodule.so fpectlmodule.o -lfpe */ #include <sigfpe.h> typedef void user_routine (unsigned[5], int[2]); typedef void abort_routine (unsigned long); handle_sigfpes(_OFF, 0, (user_routine *)0, _TURN_OFF_HANDLER_ON_ERROR, NULL); handle_sigfpes(_ON, _EN_OVERFL | _EN_DIVZERO | _EN_INVALID, (user_routine *)0, _ABORT_ON_ERROR, NULL); PyOS_setsig(SIGFPE, handler); /*-- SunOS and Solaris ----------------------------------------------------*/ #elif defined(sun) /* References: ieee_handler, ieee_sun, ieee_functions, and ieee_flags man pages (SunOS or Solaris) cc -c -I/usr/local/python/include fpectlmodule.c ld -G -o fpectlmodule.so -L/opt/SUNWspro/lib fpectlmodule.o -lsunmath -lm */ #include <math.h> #ifndef _SUNMATH_H extern void nonstandard_arithmetic(void); extern int ieee_flags(const char*, const char*, const char*, char **); extern long ieee_handler(const char*, const char*, sigfpe_handler_type); #endif char *mode="exception", *in="all", *out; (void) nonstandard_arithmetic(); (void) ieee_flags("clearall",mode,in,&out); (void) ieee_handler("set","common",(sigfpe_handler_type)handler); PyOS_setsig(SIGFPE, handler); /*-- HPUX -----------------------------------------------------------------*/ #elif defined(__hppa) || defined(hppa) /* References: fpsetmask man page */ /* cc -Aa +z -c -I/usr/local/python/include fpectlmodule.c */ /* ld -b -o fpectlmodule.sl fpectlmodule.o -lm */ #include <math.h> fpsetdefaults(); PyOS_setsig(SIGFPE, handler); /*-- IBM AIX --------------------------------------------------------------*/ #elif defined(__AIX) || defined(_AIX) /* References: fp_trap, fp_enable man pages */ #include <fptrap.h> fp_trap(FP_TRAP_SYNC); fp_enable(TRP_INVALID | TRP_DIV_BY_ZERO | TRP_OVERFLOW); PyOS_setsig(SIGFPE, handler); /*-- DEC ALPHA OSF --------------------------------------------------------*/ #elif defined(__alpha) && defined(__osf__) /* References: exception_intro, ieee man pages */ /* cc -c -I/usr/local/python/include fpectlmodule.c */ /* ld -shared -o fpectlmodule.so fpectlmodule.o */ #include <machine/fpu.h> unsigned long fp_control = IEEE_TRAP_ENABLE_INV | IEEE_TRAP_ENABLE_DZE | IEEE_TRAP_ENABLE_OVF; ieee_set_fp_control(fp_control); PyOS_setsig(SIGFPE, handler); /*-- DEC ALPHA LINUX ------------------------------------------------------*/ #elif defined(__alpha) && defined(linux) #include <asm/fpu.h> unsigned long fp_control = IEEE_TRAP_ENABLE_INV | IEEE_TRAP_ENABLE_DZE | IEEE_TRAP_ENABLE_OVF; ieee_set_fp_control(fp_control); PyOS_setsig(SIGFPE, handler); /*-- DEC ALPHA VMS --------------------------------------------------------*/ #elif defined(__ALPHA) && defined(__VMS) IEEE clrmsk; IEEE setmsk; clrmsk.ieee$q_flags = IEEE$M_TRAP_ENABLE_UNF | IEEE$M_TRAP_ENABLE_INE | IEEE$M_MAP_UMZ; setmsk.ieee$q_flags = IEEE$M_TRAP_ENABLE_INV | IEEE$M_TRAP_ENABLE_DZE | IEEE$M_TRAP_ENABLE_OVF; sys$ieee_set_fp_control(&clrmsk, &setmsk, 0); PyOS_setsig(SIGFPE, handler); /*-- HP IA64 VMS --------------------------------------------------------*/ #elif defined(__ia64) && defined(__VMS) PyOS_setsig(SIGFPE, handler); /*-- Cray Unicos ----------------------------------------------------------*/ #elif defined(cray) /* UNICOS delivers SIGFPE by default, but no matherr */ #ifdef HAS_LIBMSET libmset(-1); #endif PyOS_setsig(SIGFPE, handler); /*-- FreeBSD ----------------------------------------------------------------*/ #elif defined(__FreeBSD__) fpresetsticky(fpgetsticky()); fpsetmask(FP_X_INV | FP_X_DZ | FP_X_OFL); PyOS_setsig(SIGFPE, handler); /*-- Linux ----------------------------------------------------------------*/ #elif defined(linux) #ifdef __GLIBC__ #include <fpu_control.h> #else #include <i386/fpu_control.h> #endif #ifdef _FPU_SETCW { fpu_control_t cw = 0x1372; _FPU_SETCW(cw); } #else __setfpucw(0x1372); #endif PyOS_setsig(SIGFPE, handler); /*-- Microsoft Windows, NT ------------------------------------------------*/ #elif defined(_MSC_VER) /* Reference: Visual C++ Books Online 4.2, Run-Time Library Reference, _control87, _controlfp */ #include <float.h> unsigned int cw = _EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW; (void)_controlfp(0, cw); PyOS_setsig(SIGFPE, handler); /*-- Give Up --------------------------------------------------------------*/ #else fputs("Operation not implemented\n", stderr); #endif }
void op(double num1, double num2, OPERATOR op, int dir, FILE *fp, int *nopdiffs, int *nansdiffs, int *nxdiffs, int *nclsdiffs) { double ans1; char snum1[(DBL2CHR * 2) + 1], snum2[(DBL2CHR * 2) + 1], sans1[(DBL2CHR * 2) + 1]; fp_except x; fp_pctl pc; pc = fpsetprecision(FP_PC_DBL); fpsetsticky(0); if(dir >= 0 && dir <= 3) { fpsetround(fpdir[dir]); } else { abort(); } switch(op) { case PLUS: ans1 = num1 + num2; break; case MINUS: ans1 = num1 - num2; break; case DIVIDE: ans1 = num1 / num2; break; case MULTIPLY: ans1 = num1 * num2; break; default: abort(); } x = fpgetsticky(); fpsetprecision(pc); print(num1, snum1); print(num2, snum2); print(ans1, sans1); if(fp == NULL) { printf("%s %s %s %s = %s [ %s ]", snum1, operators[op], rnddir[dir], snum2, sans1, fpcls[fpclass(ans1)]); if(x & FP_X_INV) printf(" INV"); if(x & FP_X_DZ) printf(" DZ"); if(x & FP_X_OFL) printf(" OFL"); if(x & FP_X_UFL) printf(" UFL"); if(x & FP_X_IMP) printf(" IMP"); #ifdef FP_X_DNML if(x & FP_X_DNML) printf(" DNML"); #endif printf(" end\n"); } else { char fp_op[MAXOPLEN], fp_rnd[MAXRNDLEN]; char fp_num1[(DBL2CHR * 2) + 1], fp_num2[(DBL2CHR * 2) + 1], fp_ans1[(DBL2CHR * 2) + 1]; char fp_cls[MAXFPCLS]; char xbuf[MAXXLEN]; int inv = 0, dz = 0, ofl = 0, ufl = 0, imp = 0, dnml = 0; int thisopdiff = 0, thisansdiff = 0, thisxdiff = 0, thisclsdiff = 0; fpclass_t thiscls; if(fscanf(fp, "%s %s %s %s = %s [ %s ]", fp_num1, fp_op, fp_rnd, fp_num2, fp_ans1, fp_cls) != 6) { fprintf(stderr, "Problem reading comparison file\n"); abort(); } if(strcmp(operators[op], fp_op) != 0) { fprintf(stderr, "Operator mismatch in comparison file " "(expecting %s found %s)\n", operators[op], fp_op); abort(); } if(strcmp(rnddir[dir], fp_rnd) != 0) { fprintf(stderr, "Rounding direction mismatch in comparison file " "(expecting %s found %s)\n", rnddir[dir], fp_rnd); abort(); } if(strcmp(fp_num1, snum1) != 0) { thisopdiff = 1; } if(strcmp(fp_num2, snum2) != 0) { thisopdiff = 1; } if(strcmp(fp_ans1, sans1) != 0) { thisansdiff = 1; } thiscls = fpclass(ans1); if(strcmp(fp_cls, fpcls[thiscls]) != 0) { thisclsdiff = 1; } do { if(fscanf(fp, "%s", xbuf) != 1) { fprintf(stderr, "Problem reading comparison file"); abort(); } if(strcmp(xbuf, "INV") == 0) inv = FP_X_INV; else if(strcmp(xbuf, "DZ") == 0) dz = FP_X_DZ; else if(strcmp(xbuf, "UFL") == 0) ufl = FP_X_UFL; else if(strcmp(xbuf, "OFL") == 0) ofl = FP_X_OFL; else if(strcmp(xbuf, "IMP") == 0) imp = FP_X_IMP; #ifdef FP_X_DNML else if(strcmp(xbuf, "DNML") == 0) dnml = FP_X_DNML; #else else if(strcmp(xbuf, "DNML") == 0) dnml = -1; #endif else if(strcmp(xbuf, "end") != 0) { fprintf(stderr, "Problem reading comparison file"); abort(); } } while(strcmp(xbuf, "end") != 0); if(inv != (x & FP_X_INV)) thisxdiff = 1; if(dz != (x & FP_X_DZ)) thisxdiff = 1; if(ufl != (x & FP_X_UFL)) thisxdiff = 1; if(ofl != (x & FP_X_OFL)) thisxdiff = 1; if(imp != (x & FP_X_IMP)) thisxdiff = 1; #ifdef FP_X_DNML if(dnml != (x & FP_X_DNML)) thisxdiff = 1; #else if(dnml == -1) thisxdiff = 1; #endif if(thisansdiff || thisxdiff || thisclsdiff) { printf("In calculation %g %s %g = %g (rounding %s):\n", num1, operators[op], num2, ans1, rnddir[dir]); if(thisansdiff && thisopdiff) { printf("\tOperators differ leading to different answer:\n"); printf("\t\tFILE: op1=%s op2=%s ans=%s (%g)\n" "\t\tHERE: op1=%s op2=%s ans=%s\n", fp_num1, fp_num2, fp_ans1, input(fp_ans1), snum1, snum2, sans1); } else if(thisansdiff) { printf("\tDifferent answer:\n\t\tFILE: ans=%s (%g)\n" "\t\tHERE: ans=%s\n", fp_ans1, input(fp_ans1), sans1); } else if(thisclsdiff) { printf("\tDifferent class:\n" "\t\tFILE: %s\n\t\tHERE: %s\n", fp_cls, fpcls[thiscls]); } if(thisxdiff) { printf("\tDifferent exceptions raised:\n" "\t\tFILE: %s %s %s %s %s %s\n" "\t\tHERE: %s %s %s %s %s %s\n", inv ? "I" : "-", dz ? "Z" : "-", ufl ? "U" : "-", ofl ? "O" : "-", imp ? "P" : "-", dnml ? "D" : "-", (x & FP_X_INV) ? "I" : "-", (x & FP_X_DZ) ? "Z" : "-", (x & FP_X_UFL) ? "U" : "-", (x & FP_X_OFL) ? "O" : "-", (x & FP_X_IMP) ? "P" : "-", #ifdef FP_X_DNML (x & FP_X_DNML) ? "D" : "-" #else "-" #endif ); } } if(thisopdiff) (*nopdiffs)++; else if(thisansdiff) (*nansdiffs)++; else { if(thisxdiff) (*nxdiffs)++; if(thisclsdiff) (*nclsdiffs)++; } } }
bool FPEnvironmentImpl::isFlagImpl(FlagImpl flag) { return (fpgetsticky() & flag) != 0; }
int main(int argc, char *argv[]) { struct sigaction sa; volatile double x; if (argc != 2) { fprintf(stderr, "usage: %s condition\n", argv[0]); exit(1); } /* * check to make sure that all exceptions are masked and * that the accumulated exception status is clear. */ assert(fpgetmask() == 0); assert(fpgetsticky() == 0); memset(&sa, 0, sizeof(sa)); sa.sa_sigaction = sigfpe; sa.sa_flags = SA_SIGINFO; sigaction(SIGFPE, &sa, NULL); signal_status = 1; if (strcmp(argv[1], "fltdiv") == 0) { /* trip divide by zero */ x = one / zero; assert(fpgetsticky() & FP_X_DZ); fpsetsticky(0); /* and now unmask to get a signal */ signal_status = 0; fpsetmask(FP_X_DZ); x = one / zero; } else if (strcmp(argv[1], "fltinv") == 0) { /* trip invalid operation */ x = zero / zero; assert(fpgetsticky() & FP_X_INV); fpsetsticky(0); /* and now unmask to get a signal */ signal_status = 0; fpsetmask(FP_X_INV); x = zero / zero; } else if (strcmp(argv[1], "fltovf") == 0) { /* trip overflow */ x = huge * huge; assert(fpgetsticky() & FP_X_OFL); fpsetsticky(0); /* and now unmask to get a signal */ signal_status = 0; fpsetmask(FP_X_OFL); x = huge * huge; } else if (strcmp(argv[1], "fltund") == 0) { /* trip underflow */ x = tiny * tiny; assert(fpgetsticky() & FP_X_UFL); fpsetsticky(0); /* and now unmask to get a signal */ signal_status = 0; fpsetmask(FP_X_UFL); x = tiny * tiny; } else { errx(1, "unrecognized condition %s", argv[1]); } /* * attempt to trigger the exception on machines where * floating-point exceptions are deferred. */ x = one * one; errx(1, "signal wasn't caught"); }