Print this page
5224 snprintf rounding under [default] FE_TONEAREST

*** 36,48 **** */ double __mul_set(double x, double y, int *pe) { extern void _putsw(), _getsw(); int sw; ! double z; _putsw(0); z = x * y; _getsw(&sw); if ((sw & 0x3f) == 0) { *pe = 0; } else { --- 36,62 ---- */ double __mul_set(double x, double y, int *pe) { extern void _putsw(), _getsw(); int sw; ! volatile double z; _putsw(0); + /* + * NOTE: By declaring 'z' volatile above, we intend for the + * compiler to not move this after the _getmxcsr() call, whose results + * are only useful if they immediately follow the multiply. + * + * From the C11 spec: + * + * 134 - A volatile declaration may be used to describe an + * object corresponding to a memory-mapped input/output port + * or an object accessed by an asynchronously interrupting + * function. Actions on objects so declared shall by an + * implementation or reordered except as permitted by the + * rules for evaluating expressions." + */ z = x * y; _getsw(&sw); if ((sw & 0x3f) == 0) { *pe = 0; } else {
*** 57,69 **** */ double __div_set(double x, double y, int *pe) { extern void _putsw(), _getsw(); int sw; ! double z; _putsw(0); z = x / y; _getsw(&sw); if ((sw & 0x3f) == 0) { *pe = 0; } else { --- 71,84 ---- */ double __div_set(double x, double y, int *pe) { extern void _putsw(), _getsw(); int sw; ! volatile double z; _putsw(0); + /* NOTE: See __mul_set() above, same principle applies here. */ z = x / y; _getsw(&sw); if ((sw & 0x3f) == 0) { *pe = 0; } else {