Commit db57f29d authored by Paul Burton's avatar Paul Burton Committed by Ralf Baechle

MIPS: math-emu: Fix m{add,sub}.s shifts

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: default avatarPaul Burton <paul.burton@imgtec.com>
Fixes: e24c3bec ("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: default avatarRalf Baechle <ralf@linux-mips.org>
parent 5c18c936
...@@ -141,7 +141,8 @@ union ieee754sp ieee754sp_format(int sn, int xe, unsigned xm) ...@@ -141,7 +141,8 @@ union ieee754sp ieee754sp_format(int sn, int xe, unsigned xm)
} else { } else {
/* sticky right shift es bits /* sticky right shift es bits
*/ */
SPXSRSXn(es); xm = XSPSRS(xm, es);
xe += es;
assert((xm & (SP_HIDDEN_BIT << 3)) == 0); assert((xm & (SP_HIDDEN_BIT << 3)) == 0);
assert(xe == SP_EMIN); assert(xe == SP_EMIN);
} }
......
...@@ -46,19 +46,17 @@ static inline int ieee754sp_finite(union ieee754sp x) ...@@ -46,19 +46,17 @@ static inline int ieee754sp_finite(union ieee754sp x)
} }
/* 3bit extended single precision sticky right shift */ /* 3bit extended single precision sticky right shift */
#define SPXSRSXn(rs) \ #define XSPSRS(v, rs) \
(xe += rs, \ ((rs > (SP_FBITS+3))?1:((v) >> (rs)) | ((v) << (32-(rs)) != 0))
xm = (rs > (SP_FBITS+3))?1:((xm) >> (rs)) | ((xm) << (32-(rs)) != 0))
#define SPXSRSX1() \ #define XSPSRS1(m) \
(xe++, (xm = (xm >> 1) | (xm & 1))) ((m >> 1) | (m & 1))
#define SPXSRSYn(rs) \ #define SPXSRSX1() \
(ye+=rs, \ (xe++, (xm = XSPSRS1(xm)))
ym = (rs > (SP_FBITS+3))?1:((ym) >> (rs)) | ((ym) << (32-(rs)) != 0))
#define SPXSRSY1() \ #define SPXSRSY1() \
(ye++, (ym = (ym >> 1) | (ym & 1))) (ye++, (ym = XSPSRS1(ym)))
/* convert denormal to normalized with extended exponent */ /* convert denormal to normalized with extended exponent */
#define SPDNORMx(m,e) \ #define SPDNORMx(m,e) \
......
...@@ -132,13 +132,15 @@ union ieee754sp ieee754sp_add(union ieee754sp x, union ieee754sp y) ...@@ -132,13 +132,15 @@ union ieee754sp ieee754sp_add(union ieee754sp x, union ieee754sp y)
* Have to shift y fraction right to align. * Have to shift y fraction right to align.
*/ */
s = xe - ye; s = xe - ye;
SPXSRSYn(s); ym = XSPSRS(ym, s);
ye += s;
} else if (ye > xe) { } else if (ye > xe) {
/* /*
* Have to shift x fraction right to align. * Have to shift x fraction right to align.
*/ */
s = ye - xe; s = ye - xe;
SPXSRSXn(s); xm = XSPSRS(xm, s);
xe += s;
} }
assert(xe == ye); assert(xe == ye);
assert(xe <= SP_EMAX); assert(xe <= SP_EMAX);
......
...@@ -214,16 +214,18 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x, ...@@ -214,16 +214,18 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x,
if (ze > re) { if (ze > re) {
/* /*
* Have to shift y fraction right to align. * Have to shift r fraction right to align.
*/ */
s = ze - re; s = ze - re;
SPXSRSYn(s); rm = XSPSRS(rm, s);
re += s;
} else if (re > ze) { } else if (re > ze) {
/* /*
* Have to shift x fraction right to align. * Have to shift z fraction right to align.
*/ */
s = re - ze; s = re - ze;
SPXSRSYn(s); zm = XSPSRS(zm, s);
ze += s;
} }
assert(ze == re); assert(ze == re);
assert(ze <= SP_EMAX); assert(ze <= SP_EMAX);
...@@ -236,7 +238,8 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x, ...@@ -236,7 +238,8 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x,
zm = zm + rm; zm = zm + rm;
if (zm >> (SP_FBITS + 1 + 3)) { /* carry out */ if (zm >> (SP_FBITS + 1 + 3)) { /* carry out */
SPXSRSX1(); zm = XSPSRS1(zm);
ze++;
} }
} else { } else {
if (zm >= rm) { if (zm >= rm) {
......
...@@ -134,13 +134,15 @@ union ieee754sp ieee754sp_sub(union ieee754sp x, union ieee754sp y) ...@@ -134,13 +134,15 @@ union ieee754sp ieee754sp_sub(union ieee754sp x, union ieee754sp y)
* have to shift y fraction right to align * have to shift y fraction right to align
*/ */
s = xe - ye; s = xe - ye;
SPXSRSYn(s); ym = XSPSRS(ym, s);
ye += s;
} else if (ye > xe) { } else if (ye > xe) {
/* /*
* have to shift x fraction right to align * have to shift x fraction right to align
*/ */
s = ye - xe; s = ye - xe;
SPXSRSXn(s); xm = XSPSRS(xm, s);
xe += s;
} }
assert(xe == ye); assert(xe == ye);
assert(xe <= SP_EMAX); assert(xe <= SP_EMAX);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment