]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - soft-fp/op-4.h
Fix soft-fp shadowing between __FP_FRAC_ADD_3 and _FP_MUL_MEAT_2_wide_3mul (bug 15667).
[thirdparty/glibc.git] / soft-fp / op-4.h
index 34f5098e8c21b624c5b2afca0004535395001868..fd31da90f855a97af7239b1b56972b09b38d152b 100644 (file)
@@ -1,6 +1,6 @@
 /* Software floating-point emulation.
    Basic four-word fraction declaration and manipulation.
-   Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc.
+   Copyright (C) 1997-2013 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Richard Henderson (rth@cygnus.com),
                  Jakub Jelinek (jj@ultra.linux.cz),
@@ -27,9 +27,8 @@
    Lesser General Public License for more details.
 
    You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
-   MA 02110-1301, USA.  */
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
 
 #define _FP_FRAC_DECL_4(X)     _FP_W_TYPE X##_f[4]
 #define _FP_FRAC_COPY_4(D,S)                   \
@@ -82,7 +81,7 @@
   } while (0)
 
 
-/* Right shift with sticky-lsb. 
+/* Right shift with sticky-lsb.
  * What this actually means is that we do a standard right-shift,
  * but that if any of the bits that fall off the right hand side
  * were one then we always set the LSbit.
  * We have just one right now, maybe Newton approximation
  * should be added for those machines where division is fast.
  */
+
 #define _FP_SQRT_MEAT_4(R, S, T, X, q)                         \
   do {                                                         \
     while (q)                                                  \
            S##_f[2] += (T##_f[1] > S##_f[1]);                  \
            S##_f[3] += (T##_f[2] > S##_f[2]);                  \
            __FP_FRAC_DEC_3(X##_f[3], X##_f[2], X##_f[1],       \
-                           T##_f[3], T##_f[2], T##_f[1]);      \
+                           T##_f[3], T##_f[2], T##_f[1]);      \
            R##_f[1] += q;                                      \
          }                                                     \
        _FP_FRAC_SLL_4(X, 1);                                   \
 
 
 /*
- * Internals 
+ * Internals
  */
 
 #define __FP_FRAC_SET_4(X,I3,I2,I1,I0)                                 \
 #ifndef __FP_FRAC_ADD_3
 #define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)            \
   do {                                                         \
-    _FP_W_TYPE _c1, _c2;                                       \
+    _FP_W_TYPE __FP_FRAC_ADD_3_c1, __FP_FRAC_ADD_3_c2;         \
     r0 = x0 + y0;                                              \
-    _c1 = r0 < x0;                                             \
+    __FP_FRAC_ADD_3_c1 = r0 < x0;                              \
     r1 = x1 + y1;                                              \
-    _c2 = r1 < x1;                                             \
-    r1 += _c1;                                                 \
-    _c2 |= r1 < _c1;                                           \
-    r2 = x2 + y2 + _c2;                                                \
+    __FP_FRAC_ADD_3_c2 = r1 < x1;                              \
+    r1 += __FP_FRAC_ADD_3_c1;                                  \
+    __FP_FRAC_ADD_3_c2 |= r1 < __FP_FRAC_ADD_3_c1;             \
+    r2 = x2 + y2 + __FP_FRAC_ADD_3_c2;                         \
   } while (0)
 #endif
 
     r1 = x1 - y1;                                              \
     _c2 = r1 > x1;                                             \
     r1 -= _c1;                                                 \
-    _c2 |= r1 > _c1;                                           \
+    _c2 |= _c1 && (y1 == x1);                                  \
     r2 = x2 - y2 - _c2;                                                \
   } while (0)
 #endif
     r1 = x1 - y1;                                              \
     _c2 = r1 > x1;                                             \
     r1 -= _c1;                                                 \
-    _c2 |= r1 > _c1;                                           \
+    _c2 |= _c1 && (y1 == x1);                                  \
     r2 = x2 - y2;                                              \
     _c3 = r2 > x2;                                             \
     r2 -= _c2;                                                 \
-    _c3 |= r2 > _c2;                                           \
+    _c3 |= _c2 && (y2 == x2);                                  \
     r3 = x3 - y3 - _c3;                                                \
   } while (0)
 #endif
 /* Convert FP values between word sizes. This appears to be more
  * complicated than I'd have expected it to be, so these might be
  * wrong... These macros are in any case somewhat bogus because they
- * use information about what various FRAC_n variables look like 
+ * use information about what various FRAC_n variables look like
  * internally [eg, that 2 word vars are X_f0 and x_f1]. But so do
- * the ones in op-2.h and op-1.h. 
+ * the ones in op-2.h and op-1.h.
  */
 #define _FP_FRAC_COPY_1_4(D, S)                (D##_f = S##_f[0])
 
@@ -631,7 +630,7 @@ do {                                                \
   D##_f1 = S##_f[1];                           \
 } while (0)
 
-/* Assembly/disassembly for converting to/from integral types.  
+/* Assembly/disassembly for converting to/from integral types.
  * No shifting or overflow handled here.
  */
 /* Put the FP value X into r, which is an integer of size rsize. */
@@ -684,3 +683,5 @@ do {                                                \
   D##_f[1] = S##_f1;                           \
   D##_f[2] = D##_f[3] = 0;                     \
 } while (0)
+
+#define _FP_FRAC_COPY_4_4(D,S) _FP_FRAC_COPY_4(D,S)