void zunder_() { union fpc_csr n; n.fc_word = get_fpc_csr(); n.fc_struct.flush = 1; set_fpc_csr(n.fc_word); }
ulong FPstatus(ulong fsr, ulong mask) { ulong old = getFPstatus(); union fpc_csr csr; csr.fc_word = get_fpc_csr(); fsr = (fsr&mask) | (old&~mask); csr.fc_struct.se_inexact = (fsr&INEX)?1:0; csr.fc_struct.se_overflow = (fsr&OVFL)?1:0; csr.fc_struct.se_underflow = (fsr&UNFL)?1:0; csr.fc_struct.se_divide0 = (fsr&ZDIV)?1:0; csr.fc_struct.se_invalid = (fsr&INVAL)?1:0; set_fpc_csr(csr.fc_word); return(old&mask); }
void enableFPE(void) { union fpc_csr csr; csr.fc_word = get_fpc_csr(); csr.fc_struct.en_divide0 = csr.fc_struct.en_overflow = csr.fc_struct.en_underflow = 1; csr.fc_struct.se_divide0 = 0; fprintf(stderr, "Enabling floating point exceptions.\n"); set_fpc_csr( csr.fc_word ); }
ulong FPcontrol(ulong fcr, ulong mask) { ulong old = getFPcontrol(); union fpc_csr csr; csr.fc_word = get_fpc_csr(); fcr = (fcr&mask) | (old&~mask); csr.fc_struct.en_inexact = (fcr&INEX)?1:0; csr.fc_struct.en_overflow = (fcr&OVFL)?1:0; csr.fc_struct.en_underflow = (fcr&UNFL)?1:0; csr.fc_struct.en_divide0 = (fcr&ZDIV)?1:0; csr.fc_struct.en_invalid = (fcr&INVAL)?1:0; switch(fcr&RND_MASK){ case RND_NR: csr.fc_struct.rounding_mode = ROUND_TO_NEAREST; break; case RND_NINF: csr.fc_struct.rounding_mode = ROUND_TO_MINUS_INFINITY; break; case RND_PINF: csr.fc_struct.rounding_mode = ROUND_TO_PLUS_INFINITY; break; case RND_Z: csr.fc_struct.rounding_mode = ROUND_TO_ZERO; break; } set_fpc_csr(csr.fc_word); return(old&mask); }
/* initialization function for tests using the hardware floats Not very useful now. */ void mpfr_test_init (void) { #ifdef HAVE_FPC_CSR /* to get subnormal numbers on IRIX64 */ union fpc_csr exp; exp.fc_word = get_fpc_csr(); exp.fc_struct.flush = 0; set_fpc_csr(exp.fc_word); #endif #ifdef HAVE_DENORMS { double d = DBL_MIN; if (2.0 * (d / 2.0) != d) { printf ("Error: HAVE_DENORMS defined, but no subnormals.\n"); exit (1); } } #endif /* generate DBL_EPSILON with a loop to avoid that the compiler optimizes the code below in non-IEEE 754 mode, deciding that c = d is always false. */ #if 0 for (eps = 1.0; eps != DBL_EPSILON; eps /= 2.0); c = 1.0 + eps; d = eps * (1.0 - eps) / 2.0; d += c; if (c != d) { printf ("Warning: IEEE 754 standard not fully supported\n" " (maybe extended precision not disabled)\n" " Some tests may fail\n"); } #endif }
qcomplex __cqdiv(long double xqreal, long double xqimag, long double yqreal, long double yqimag) { long double tmp; unsigned int m, n; qcomplex result; if ((xqreal != xqreal) || (xqimag != xqimag) || (yqreal != yqreal) || (yqimag != yqimag)) { result.qreal = __libm_qnan_ld; result.qimag = __libm_qnan_ld; return result; } if ((yqreal == 0.0L) && (yqimag == 0.0L)) { result.qreal = xqreal/__libm_zero_ld; result.qimag = xqimag/__libm_zero_ld; return result; } if (yqreal == 0.0L) { result.qreal = xqimag/yqimag; result.qimag = -(xqreal/yqimag); return result; } if (yqimag == 0.0L) { result.qreal = xqreal/yqreal; result.qimag = xqimag/yqreal; return result; } if (__qabs(yqreal) <= __qabs(yqimag)) { /* turn off traps on underflow while computing yqreal/yqimag */ m = get_fpc_csr(); n = (m & 0xfffffeff); (void)set_fpc_csr(n); tmp = yqreal/yqimag; (void)set_fpc_csr(m); result.qreal = (xqimag + xqreal*tmp)/(yqimag + yqreal*tmp); result.qimag = (-xqreal + xqimag*tmp)/(yqimag + yqreal*tmp); return result; } /* turn off traps on underflow while computing yqimag/yqreal */ m = get_fpc_csr(); n = (m & 0xfffffeff); (void)set_fpc_csr(n); tmp = yqimag/yqreal; (void)set_fpc_csr(m); result.qreal = (xqreal + xqimag*tmp)/(yqreal + yqimag*tmp); result.qimag = (xqimag - xqreal*tmp)/(yqreal + yqimag*tmp); return result; }