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 {