Print this page
5224 snprintf rounding under [default] FE_TONEAREST

@@ -39,13 +39,27 @@
  */
 double
 __mul_set(double x, double y, int *pe) {
         extern void _putmxcsr(), _getmxcsr();
         int csr;
-        double z;
+        volatile double z;
 
         _putmxcsr(CSR_DEFAULT);
+        /*
+         * 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;
         _getmxcsr(&csr);
         if ((csr & 0x3f) == 0) {
                 *pe = 0;
         } else {

@@ -60,13 +74,14 @@
  */
 double
 __div_set(double x, double y, int *pe) {
         extern void _putmxcsr(), _getmxcsr();
         int csr;
-        double z;
+        volatile double z;
 
         _putmxcsr(CSR_DEFAULT);
+        /* NOTE:  See __mul_set() above, same principle applies here. */
         z = x / y;
         _getmxcsr(&csr);
         if ((csr & 0x3f) == 0) {
                 *pe = 0;
         } else {