On Fri, Jul 21, 2017 at 04:09:09PM +0200, Aleksandar Markovic wrote: > From: Aleksandar Markovic <aleksandar.markovic@xxxxxxxxxx> > > Fix the cases of <MADDF|MSUBF>.<D|S> when any of three inputs is any > NaN. Correct behavior of <MADDF|MSUBF>.<D|S> fd, fs, ft is following: > > - if any of inputs is sNaN, return a sNaN using following rules: if > only one input is sNaN, return that one; if more than one input is > sNaN, order of precedence for return value is fd, fs, ft > - if no input is sNaN, but at least one of inputs is qNaN, return a > qNaN using following rules: if only one input is qNaN, return that > one; if more than one input is qNaN, order of precedence for > return value is fd, fs, ft > > The previous code contained handling of some above cases, but not all. > Also, such handling was scattered into various cases of > "switch (CLPAIR(xc, yc))" statement and elsewhere. With this patch, > this logic is placed in one place, and "switch (CLPAIR(xc, yc))" is > significantly simplified. > > The relevant example: > > MADDF.S fd,fs,ft: > If fs contains qNaN1, ft contains qNaN2, and fd contains qNaN3, fd > is going to contain qNaN3 (without this patch, it used to contain > qNaN1). > Fixes: e24c3bec3e8e ("MIPS: math-emu: Add support for the MIPS R6 MADDF FPU instruction") Fixes: 83d43305a1df ("MIPS: math-emu: Add support for the MIPS R6 MSUBF FPU instruction") > Signed-off-by: Miodrag Dinic <miodrag.dinic@xxxxxxxxxx> > Signed-off-by: Goran Ferenc <goran.ferenc@xxxxxxxxxx> > Signed-off-by: Aleksandar Markovic <aleksandar.markovic@xxxxxxxxxx> If backported, I suspect commits: 6162051e87f6 ("MIPS: math-emu: Unify ieee754sp_m{add,sub}f") and d728f6709bcc ("MIPS: math-emu: Unify ieee754dp_m{add,sub}f") in 4.7 will require manual backporting between 4.3 and 4.7 (due to separation of maddf/msubf before that point), so I suppose tagging stable 4.7+ and backporting is best (assuming you consider this fix worth backporting). > --- > arch/mips/math-emu/dp_maddf.c | 71 ++++++++++++++----------------------------- > arch/mips/math-emu/sp_maddf.c | 69 ++++++++++++++--------------------------- > 2 files changed, 46 insertions(+), 94 deletions(-) > > diff --git a/arch/mips/math-emu/dp_maddf.c b/arch/mips/math-emu/dp_maddf.c > index caa62f2..4f2e783 100644 > --- a/arch/mips/math-emu/dp_maddf.c > +++ b/arch/mips/math-emu/dp_maddf.c > @@ -48,52 +48,35 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, > > ieee754_clearcx(); > > - switch (zc) { > - case IEEE754_CLASS_SNAN: > - ieee754_setcx(IEEE754_INVALID_OPERATION); > - return ieee754dp_nanxcpt(z); > - case IEEE754_CLASS_DNORM: > - DPDNORMZ; > - /* QNAN and ZERO cases are handled separately below */ > - } > - > - switch (CLPAIR(xc, yc)) { > - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): > - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): > - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): > - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): > - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): > - return ieee754dp_nanxcpt(y); > - > - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): > - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): > - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): > - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): > - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): > - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): > - return ieee754dp_nanxcpt(x); > - > - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): > - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): > - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): > - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): > + /* handle the cases when at least one of x, y or z is a NaN */ > + if (((xc == IEEE754_CLASS_SNAN) || (xc == IEEE754_CLASS_QNAN)) || > + ((yc == IEEE754_CLASS_SNAN) || (yc == IEEE754_CLASS_QNAN)) || > + ((zc == IEEE754_CLASS_SNAN) || (zc == IEEE754_CLASS_QNAN))) { This condition basically covers all of the cases below. Any particular reason not to skip it ... > + /* order of precedence is z, x, y */ > + if (zc == IEEE754_CLASS_SNAN) > + return ieee754dp_nanxcpt(z); > + if (xc == IEEE754_CLASS_SNAN) > + return ieee754dp_nanxcpt(x); > + if (yc == IEEE754_CLASS_SNAN) > + return ieee754dp_nanxcpt(y); > + if (zc == IEEE754_CLASS_QNAN) > + return z; > + if (xc == IEEE754_CLASS_QNAN) > + return x; > return y; ... and make this return conditional on (yc == IEEE754_CLASS_QNAN)? Same for sp_maddf.c too. Otherwise: Reviewed-by: James Hogan <james.hogan@xxxxxxxxxx> Cheers James > + } > > - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): > - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): > - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): > - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): > - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): > - return x; > + if (zc == IEEE754_CLASS_DNORM) > + DPDNORMZ; > + /* ZERO z cases are handled separately below */ > > + switch (CLPAIR(xc, yc)) { > > /* > * Infinity handling > */ > case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): > case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): > - if (zc == IEEE754_CLASS_QNAN) > - return z; > ieee754_setcx(IEEE754_INVALID_OPERATION); > return ieee754dp_indef(); > > @@ -102,8 +85,6 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, > case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): > case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): > case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): > - if (zc == IEEE754_CLASS_QNAN) > - return z; > return ieee754dp_inf(xs ^ ys); > > case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): > @@ -120,25 +101,19 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x, > DPDNORMX; > > case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): > - if (zc == IEEE754_CLASS_QNAN) > - return z; > - else if (zc == IEEE754_CLASS_INF) > + if (zc == IEEE754_CLASS_INF) > return ieee754dp_inf(zs); > DPDNORMY; > break; > > case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): > - if (zc == IEEE754_CLASS_QNAN) > - return z; > - else if (zc == IEEE754_CLASS_INF) > + if (zc == IEEE754_CLASS_INF) > return ieee754dp_inf(zs); > DPDNORMX; > break; > > case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): > - if (zc == IEEE754_CLASS_QNAN) > - return z; > - else if (zc == IEEE754_CLASS_INF) > + if (zc == IEEE754_CLASS_INF) > return ieee754dp_inf(zs); > /* fall through to real computations */ > } > diff --git a/arch/mips/math-emu/sp_maddf.c b/arch/mips/math-emu/sp_maddf.c > index c91d5e5..9fd2035 100644 > --- a/arch/mips/math-emu/sp_maddf.c > +++ b/arch/mips/math-emu/sp_maddf.c > @@ -48,51 +48,36 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x, > > ieee754_clearcx(); > > - switch (zc) { > - case IEEE754_CLASS_SNAN: > - ieee754_setcx(IEEE754_INVALID_OPERATION); > - return ieee754sp_nanxcpt(z); > - case IEEE754_CLASS_DNORM: > - SPDNORMZ; > - /* QNAN and ZERO cases are handled separately below */ > + /* handle the cases when at least one of x, y or z is a NaN */ > + if (((xc == IEEE754_CLASS_SNAN) || (xc == IEEE754_CLASS_QNAN)) || > + ((yc == IEEE754_CLASS_SNAN) || (yc == IEEE754_CLASS_QNAN)) || > + ((zc == IEEE754_CLASS_SNAN) || (zc == IEEE754_CLASS_QNAN))) { > + /* order of precedence is z, x, y */ > + if (zc == IEEE754_CLASS_SNAN) > + return ieee754sp_nanxcpt(z); > + if (xc == IEEE754_CLASS_SNAN) > + return ieee754sp_nanxcpt(x); > + if (yc == IEEE754_CLASS_SNAN) > + return ieee754sp_nanxcpt(y); > + if (zc == IEEE754_CLASS_QNAN) > + return z; > + if (xc == IEEE754_CLASS_QNAN) > + return x; > + return y; > } > > + if (zc == IEEE754_CLASS_DNORM) > + SPDNORMZ; > + /* ZERO z cases are handled separately below */ > + > switch (CLPAIR(xc, yc)) { > - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): > - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): > - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): > - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): > - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): > - return ieee754sp_nanxcpt(y); > - > - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): > - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): > - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): > - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): > - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): > - case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): > - return ieee754sp_nanxcpt(x); > - > - case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): > - case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): > - case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): > - case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): > - return y; > > - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): > - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): > - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): > - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): > - case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): > - return x; > > /* > * Infinity handling > */ > case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): > case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): > - if (zc == IEEE754_CLASS_QNAN) > - return z; > ieee754_setcx(IEEE754_INVALID_OPERATION); > return ieee754sp_indef(); > > @@ -101,8 +86,6 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x, > case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): > case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): > case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): > - if (zc == IEEE754_CLASS_QNAN) > - return z; > return ieee754sp_inf(xs ^ ys); > > case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): > @@ -119,25 +102,19 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x, > SPDNORMX; > > case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): > - if (zc == IEEE754_CLASS_QNAN) > - return z; > - else if (zc == IEEE754_CLASS_INF) > + if (zc == IEEE754_CLASS_INF) > return ieee754sp_inf(zs); > SPDNORMY; > break; > > case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): > - if (zc == IEEE754_CLASS_QNAN) > - return z; > - else if (zc == IEEE754_CLASS_INF) > + if (zc == IEEE754_CLASS_INF) > return ieee754sp_inf(zs); > SPDNORMX; > break; > > case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): > - if (zc == IEEE754_CLASS_QNAN) > - return z; > - else if (zc == IEEE754_CLASS_INF) > + if (zc == IEEE754_CLASS_INF) > return ieee754sp_inf(zs); > /* fall through to real computations */ > } > -- > 2.7.4 >
Attachment:
signature.asc
Description: Digital signature