MIPS: math-emu: Fix m{add,sub}.s shifts
authorPaul Burton <paul.burton@imgtec.com>
Thu, 21 Apr 2016 13:04:54 +0000 (14:04 +0100)
committerRalf Baechle <ralf@linux-mips.org>
Fri, 13 May 2016 12:02:23 +0000 (14:02 +0200)
The code in _sp_maddf (formerly ieee754sp_madd) appears to have been
copied verbatim from ieee754sp_add, and although it's adding the
unpacked "r" & "z" floats it kept using macros that operate on "x" &
"y". This led to the addition being carried out incorrectly on some
mismash of the product, accumulator & multiplicand fields. Typically
this would lead to the assertions "ze == re" & "ze <= SP_EMAX" failing
since ze & re hadn't been operated upon.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Fixes: e24c3bec3e8e ("MIPS: math-emu: Add support for the MIPS R6 MADDF FPU instruction")
Cc: Adam Buchbinder <adam.buchbinder@gmail.com>
Cc: Maciej W. Rozycki <macro@imgtec.com>
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/13159/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/math-emu/ieee754sp.c
arch/mips/math-emu/ieee754sp.h
arch/mips/math-emu/sp_add.c
arch/mips/math-emu/sp_maddf.c
arch/mips/math-emu/sp_sub.c

index 860e9162097f4f285a86380e75088571bf07a9df..260e68965907283b7f6ef8286f0bbd0f4fc3ad43 100644 (file)
@@ -141,7 +141,8 @@ union ieee754sp ieee754sp_format(int sn, int xe, unsigned xm)
                } else {
                        /* sticky right shift es bits
                         */
-                       SPXSRSXn(es);
+                       xm = XSPSRS(xm, es);
+                       xe += es;
                        assert((xm & (SP_HIDDEN_BIT << 3)) == 0);
                        assert(xe == SP_EMIN);
                }
index b24fdff90f21e05e04b39cf3cd371ac3cacf1687..8476067075fe013331609ed3db1028b04b9d3e66 100644 (file)
@@ -46,19 +46,17 @@ static inline int ieee754sp_finite(union ieee754sp x)
 }
 
 /* 3bit extended single precision sticky right shift */
-#define SPXSRSXn(rs)                                                   \
-       (xe += rs,                                                      \
-        xm = (rs > (SP_FBITS+3))?1:((xm) >> (rs)) | ((xm) << (32-(rs)) != 0))
+#define XSPSRS(v, rs)                                          \
+       ((rs > (SP_FBITS+3))?1:((v) >> (rs)) | ((v) << (32-(rs)) != 0))
 
-#define SPXSRSX1() \
-       (xe++, (xm = (xm >> 1) | (xm & 1)))
+#define XSPSRS1(m) \
+       ((m >> 1) | (m & 1))
 
-#define SPXSRSYn(rs)                                                           \
-       (ye+=rs,                                                                \
-        ym = (rs > (SP_FBITS+3))?1:((ym) >> (rs)) | ((ym) << (32-(rs)) != 0))
+#define SPXSRSX1() \
+       (xe++, (xm = XSPSRS1(xm)))
 
 #define SPXSRSY1() \
-       (ye++, (ym = (ym >> 1) | (ym & 1)))
+       (ye++, (ym = XSPSRS1(ym)))
 
 /* convert denormal to normalized with extended exponent */
 #define SPDNORMx(m,e) \
index f1c87b07d3b4758167628bb087fc21124c8c5f51..c55c0c00bca803b989825397aedb915f28359402 100644 (file)
@@ -132,13 +132,15 @@ union ieee754sp ieee754sp_add(union ieee754sp x, union ieee754sp y)
                 * Have to shift y fraction right to align.
                 */
                s = xe - ye;
-               SPXSRSYn(s);
+               ym = XSPSRS(ym, s);
+               ye += s;
        } else if (ye > xe) {
                /*
                 * Have to shift x fraction right to align.
                 */
                s = ye - xe;
-               SPXSRSXn(s);
+               xm = XSPSRS(xm, s);
+               xe += s;
        }
        assert(xe == ye);
        assert(xe <= SP_EMAX);
index 86e1d0b254460c096992956ec6149080329130e9..a8cd8b4f235eb810db8c0472dea29c82dc2cd173 100644 (file)
@@ -214,16 +214,18 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x,
 
        if (ze > re) {
                /*
-                * Have to shift y fraction right to align.
+                * Have to shift r fraction right to align.
                 */
                s = ze - re;
-               SPXSRSYn(s);
+               rm = XSPSRS(rm, s);
+               re += s;
        } else if (re > ze) {
                /*
-                * Have to shift x fraction right to align.
+                * Have to shift z fraction right to align.
                 */
                s = re - ze;
-               SPXSRSYn(s);
+               zm = XSPSRS(zm, s);
+               ze += s;
        }
        assert(ze == re);
        assert(ze <= SP_EMAX);
@@ -236,7 +238,8 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x,
                zm = zm + rm;
 
                if (zm >> (SP_FBITS + 1 + 3)) { /* carry out */
-                       SPXSRSX1();
+                       zm = XSPSRS1(zm);
+                       ze++;
                }
        } else {
                if (zm >= rm) {
index ec5f937a8b3eeb7ae1e6369bdfdb4c7f42323fd7..dc998ed47295d677ccab8c1a1ea49c3aa09e9795 100644 (file)
@@ -134,13 +134,15 @@ union ieee754sp ieee754sp_sub(union ieee754sp x, union ieee754sp y)
                 * have to shift y fraction right to align
                 */
                s = xe - ye;
-               SPXSRSYn(s);
+               ym = XSPSRS(ym, s);
+               ye += s;
        } else if (ye > xe) {
                /*
                 * have to shift x fraction right to align
                 */
                s = ye - xe;
-               SPXSRSXn(s);
+               xm = XSPSRS(xm, s);
+               xe += s;
        }
        assert(xe == ye);
        assert(xe <= SP_EMAX);