Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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);
		}
+7 −9
Original line number Diff line number Diff line
@@ -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) \
+4 −2
Original line number Diff line number Diff line
@@ -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);
+8 −5
Original line number Diff line number Diff line
@@ -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) {
+4 −2
Original line number Diff line number Diff line
@@ -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);