Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

MIPS: math-emu: Reinstate sNaN quieting handlers

Revert the changes made by commit fdffbafb [Lots of FPU bug fixes from
Kjeld Borch Egevang.] to `ieee754sp_nanxcpt' and `ieee754dp_nanxcpt'
sNaN quieting handlers and their callers so that sNaN processing is done
within the handlers againg. Pass the sNaN causing an IEEE 754 invalid
operation exception down to the relevant handler. Pass the sNaN in `fs'
where two sNaNs are supplied to a binary operation.

Set the Invalid Operation FCSR exception bits in the quieting handlers
rather than at their call sites throughout. Make the handlers exclusive
for sNaN processing.

Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/9688/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

authored by

Maciej W. Rozycki and committed by
Ralf Baechle
d5afa7e9 539bfb57

+62 -62
+5 -4
arch/mips/math-emu/dp_add.c
··· 37 37 FLUSHYDP; 38 38 39 39 switch (CLPAIR(xc, yc)) { 40 - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): 41 40 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): 42 - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): 43 41 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): 44 42 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): 45 43 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): 46 44 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): 45 + return ieee754dp_nanxcpt(y); 46 + 47 + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): 48 + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): 47 49 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): 48 50 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): 49 51 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): 50 52 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): 51 - ieee754_setcx(IEEE754_INVALID_OPERATION); 52 - return ieee754dp_nanxcpt(ieee754dp_indef()); 53 + return ieee754dp_nanxcpt(x); 53 54 54 55 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): 55 56 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
+5 -4
arch/mips/math-emu/dp_div.c
··· 39 39 FLUSHYDP; 40 40 41 41 switch (CLPAIR(xc, yc)) { 42 - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): 43 42 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): 44 - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): 45 43 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): 46 44 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): 47 45 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): 48 46 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): 47 + return ieee754dp_nanxcpt(y); 48 + 49 + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): 50 + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): 49 51 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): 50 52 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): 51 53 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): 52 54 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): 53 - ieee754_setcx(IEEE754_INVALID_OPERATION); 54 - return ieee754dp_nanxcpt(ieee754dp_indef()); 55 + return ieee754dp_nanxcpt(x); 55 56 56 57 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): 57 58 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
+1 -2
arch/mips/math-emu/dp_fsp.c
··· 40 40 41 41 switch (xc) { 42 42 case IEEE754_CLASS_SNAN: 43 - ieee754_setcx(IEEE754_INVALID_OPERATION); 44 - return ieee754dp_nanxcpt(ieee754dp_indef()); 43 + return ieee754dp_nanxcpt(ieee754dp_nan_fsp(xs, xm)); 45 44 46 45 case IEEE754_CLASS_QNAN: 47 46 return ieee754dp_nan_fsp(xs, xm);
+5 -4
arch/mips/math-emu/dp_mul.c
··· 47 47 FLUSHYDP; 48 48 49 49 switch (CLPAIR(xc, yc)) { 50 - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): 51 50 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): 52 - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): 53 51 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): 54 52 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): 55 53 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): 56 54 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): 55 + return ieee754dp_nanxcpt(y); 56 + 57 + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): 58 + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): 57 59 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): 58 60 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): 59 61 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): 60 62 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): 61 - ieee754_setcx(IEEE754_INVALID_OPERATION); 62 - return ieee754dp_nanxcpt(ieee754dp_indef()); 63 + return ieee754dp_nanxcpt(x); 63 64 64 65 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): 65 66 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
+3 -4
arch/mips/math-emu/dp_sqrt.c
··· 42 42 43 43 /* x == INF or NAN? */ 44 44 switch (xc) { 45 + case IEEE754_CLASS_SNAN: 46 + return ieee754dp_nanxcpt(x); 47 + 45 48 case IEEE754_CLASS_QNAN: 46 49 /* sqrt(Nan) = Nan */ 47 50 return x; 48 - 49 - case IEEE754_CLASS_SNAN: 50 - ieee754_setcx(IEEE754_INVALID_OPERATION); 51 - return ieee754dp_nanxcpt(ieee754dp_indef()); 52 51 53 52 case IEEE754_CLASS_ZERO: 54 53 /* sqrt(0) = 0 */
+5 -4
arch/mips/math-emu/dp_sub.c
··· 37 37 FLUSHYDP; 38 38 39 39 switch (CLPAIR(xc, yc)) { 40 - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): 41 40 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): 42 - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): 43 41 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): 44 42 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): 45 43 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): 46 44 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): 45 + return ieee754dp_nanxcpt(y); 46 + 47 + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): 48 + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): 47 49 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): 48 50 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): 49 51 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): 50 52 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): 51 - ieee754_setcx(IEEE754_INVALID_OPERATION); 52 - return ieee754dp_nanxcpt(ieee754dp_indef()); 53 + return ieee754dp_nanxcpt(x); 53 54 54 55 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): 55 56 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
+7 -9
arch/mips/math-emu/ieee754dp.c
··· 42 42 } 43 43 44 44 45 + /* 46 + * Raise the Invalid Operation IEEE 754 exception 47 + * and convert the signaling NaN supplied to a quiet NaN. 48 + */ 45 49 union ieee754dp __cold ieee754dp_nanxcpt(union ieee754dp r) 46 50 { 47 - assert(ieee754dp_isnan(r)); 51 + assert(ieee754dp_issnan(r)); 48 52 49 - if (!ieee754dp_issnan(r)) /* QNAN does not cause invalid op !! */ 50 - return r; 51 - 52 - /* If not enabled convert to a quiet NaN. */ 53 - if (!ieee754_setandtestcx(IEEE754_INVALID_OPERATION)) 54 - return ieee754dp_indef(); 55 - 56 - return r; 53 + ieee754_setcx(IEEE754_INVALID_OPERATION); 54 + return ieee754dp_indef(); 57 55 } 58 56 59 57 static u64 ieee754dp_get_rounding(int sn, u64 xm)
+7 -9
arch/mips/math-emu/ieee754sp.c
··· 42 42 } 43 43 44 44 45 + /* 46 + * Raise the Invalid Operation IEEE 754 exception 47 + * and convert the signaling NaN supplied to a quiet NaN. 48 + */ 45 49 union ieee754sp __cold ieee754sp_nanxcpt(union ieee754sp r) 46 50 { 47 - assert(ieee754sp_isnan(r)); 51 + assert(ieee754sp_issnan(r)); 48 52 49 - if (!ieee754sp_issnan(r)) /* QNAN does not cause invalid op !! */ 50 - return r; 51 - 52 - /* If not enabled convert to a quiet NaN. */ 53 - if (!ieee754_setandtestcx(IEEE754_INVALID_OPERATION)) 54 - return ieee754sp_indef(); 55 - 56 - return r; 53 + ieee754_setcx(IEEE754_INVALID_OPERATION); 54 + return ieee754sp_indef(); 57 55 } 58 56 59 57 static unsigned ieee754sp_get_rounding(int sn, unsigned xm)
+5 -4
arch/mips/math-emu/sp_add.c
··· 37 37 FLUSHYSP; 38 38 39 39 switch (CLPAIR(xc, yc)) { 40 - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): 41 40 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): 42 - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): 43 41 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): 44 42 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): 45 43 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): 46 44 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): 45 + return ieee754sp_nanxcpt(y); 46 + 47 + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): 48 + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): 47 49 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): 48 50 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): 49 51 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): 50 52 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): 51 - ieee754_setcx(IEEE754_INVALID_OPERATION); 52 - return ieee754sp_nanxcpt(ieee754sp_indef()); 53 + return ieee754sp_nanxcpt(x); 53 54 54 55 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): 55 56 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
+5 -4
arch/mips/math-emu/sp_div.c
··· 39 39 FLUSHYSP; 40 40 41 41 switch (CLPAIR(xc, yc)) { 42 - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): 43 42 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): 44 - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): 45 43 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): 46 44 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): 47 45 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): 48 46 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): 47 + return ieee754sp_nanxcpt(y); 48 + 49 + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): 50 + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): 49 51 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): 50 52 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): 51 53 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): 52 54 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): 53 - ieee754_setcx(IEEE754_INVALID_OPERATION); 54 - return ieee754sp_nanxcpt(ieee754sp_indef()); 55 + return ieee754sp_nanxcpt(x); 55 56 56 57 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): 57 58 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
+1 -2
arch/mips/math-emu/sp_fdp.c
··· 43 43 44 44 switch (xc) { 45 45 case IEEE754_CLASS_SNAN: 46 - ieee754_setcx(IEEE754_INVALID_OPERATION); 47 - return ieee754sp_nanxcpt(ieee754sp_indef()); 46 + return ieee754sp_nanxcpt(ieee754sp_nan_fdp(xs, xm)); 48 47 49 48 case IEEE754_CLASS_QNAN: 50 49 nan = ieee754sp_nan_fdp(xs, xm);
+5 -4
arch/mips/math-emu/sp_mul.c
··· 47 47 FLUSHYSP; 48 48 49 49 switch (CLPAIR(xc, yc)) { 50 - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): 51 50 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): 52 - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): 53 51 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): 54 52 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): 55 53 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): 56 54 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): 55 + return ieee754sp_nanxcpt(y); 56 + 57 + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): 58 + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): 57 59 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): 58 60 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): 59 61 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): 60 62 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): 61 - ieee754_setcx(IEEE754_INVALID_OPERATION); 62 - return ieee754sp_nanxcpt(ieee754sp_indef()); 63 + return ieee754sp_nanxcpt(x); 63 64 64 65 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): 65 66 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
+3 -4
arch/mips/math-emu/sp_sqrt.c
··· 35 35 36 36 /* x == INF or NAN? */ 37 37 switch (xc) { 38 + case IEEE754_CLASS_SNAN: 39 + return ieee754sp_nanxcpt(x); 40 + 38 41 case IEEE754_CLASS_QNAN: 39 42 /* sqrt(Nan) = Nan */ 40 43 return x; 41 - 42 - case IEEE754_CLASS_SNAN: 43 - ieee754_setcx(IEEE754_INVALID_OPERATION); 44 - return ieee754sp_nanxcpt(ieee754sp_indef()); 45 44 46 45 case IEEE754_CLASS_ZERO: 47 46 /* sqrt(0) = 0 */
+5 -4
arch/mips/math-emu/sp_sub.c
··· 37 37 FLUSHYSP; 38 38 39 39 switch (CLPAIR(xc, yc)) { 40 - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): 41 40 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): 42 - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): 43 41 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): 44 42 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): 45 43 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): 46 44 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): 45 + return ieee754sp_nanxcpt(y); 46 + 47 + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): 48 + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): 47 49 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): 48 50 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): 49 51 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): 50 52 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): 51 - ieee754_setcx(IEEE754_INVALID_OPERATION); 52 - return ieee754sp_nanxcpt(ieee754sp_indef()); 53 + return ieee754sp_nanxcpt(x); 53 54 54 55 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): 55 56 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):