Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1693727 > unrolled thread
| Started by | Aleksandar Markovic <aleksandar.markovic@rt-rk.com> |
|---|---|
| First post | 2017-07-21 16:20 +0200 |
| Last post | 2017-07-24 14:50 +0200 |
| Articles | 3 — 3 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
[PATCH v3 11/16] MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Fix NaN propagation Aleksandar Markovic <aleksandar.markovic@rt-rk.com> - 2017-07-21 16:20 +0200
Re: [PATCH v3 11/16] MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Fix NaN propagation James Hogan <james.hogan@imgtec.com> - 2017-07-24 12:30 +0200
RE: [PATCH v3 11/16] MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Fix NaN propagation Aleksandar Markovic <Aleksandar.Markovic@imgtec.com> - 2017-07-24 14:50 +0200
| From | Aleksandar Markovic <aleksandar.markovic@rt-rk.com> |
|---|---|
| Date | 2017-07-21 16:20 +0200 |
| Subject | [PATCH v3 11/16] MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Fix NaN propagation |
| Message-ID | <u5GWB-5Tl-15@gated-at.bofh.it> |
From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
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).
Signed-off-by: Miodrag Dinic <miodrag.dinic@imgtec.com>
Signed-off-by: Goran Ferenc <goran.ferenc@imgtec.com>
Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
---
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))) {
+ /* 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;
+ }
- 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
[toc] | [next] | [standalone]
| From | James Hogan <james.hogan@imgtec.com> |
|---|---|
| Date | 2017-07-24 12:30 +0200 |
| Subject | Re: [PATCH v3 11/16] MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Fix NaN propagation |
| Message-ID | <u6IMF-3rL-11@gated-at.bofh.it> |
| In reply to | #1693727 |
[Multipart message — attachments visible in raw view] — view raw
On Fri, Jul 21, 2017 at 04:09:09PM +0200, Aleksandar Markovic wrote:
> From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
>
> 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@imgtec.com>
> Signed-off-by: Goran Ferenc <goran.ferenc@imgtec.com>
> Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
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@imgtec.com>
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
>
[toc] | [prev] | [next] | [standalone]
| From | Aleksandar Markovic <Aleksandar.Markovic@imgtec.com> |
|---|---|
| Date | 2017-07-24 14:50 +0200 |
| Subject | RE: [PATCH v3 11/16] MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Fix NaN propagation |
| Message-ID | <u6KYa-4Ul-27@gated-at.bofh.it> |
| In reply to | #1694600 |
> _______________________________________
> From: James Hogan
> Sent: Monday, July 24, 2017 3:24 AM
> To: Aleksandar Markovic
> Cc: linux-mips@linux-mips.org; Aleksandar Markovic; Miodrag Dinic; Goran Ferenc; Douglas Leung; linux-> kernel@vger.kernel.org; Paul Burton; Petar Jovanovic; Raghu Gandham; Ralf Baechle
> Subject: Re: [PATCH v3 11/16] MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Fix NaN propagation
>
> On Fri, Jul 21, 2017 at 04:09:09PM +0200, Aleksandar Markovic wrote:
> > From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
> >
> > 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")
>
In v4, I will add these lines to commit messages of all MADDF/MSUBF patches from this series.
> > Signed-off-by: Miodrag Dinic <miodrag.dinic@imgtec.com>
> > Signed-off-by: Goran Ferenc <goran.ferenc@imgtec.com>
> > Signed-off-by: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
>
> > 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).
I am going to tag all MADDF/MSUBF patches "stable 4.7+" and all MIN/MAX/MINA/MAXA patches "stable 4.3+" in v4.
> > ---
> > arch/mips/math-emu/dp_maddf.c | 71 ++++++++++++++-----------------------------
> > arch/mips/math-emu/sp_maddf.c | 69 ++++++++++++++---------------------------
> > 2 files changed, 46 insertions(+), 94 deletions(-)
> ...
> > + /* 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)?
You are right. I am going to reorganize the code as you suggested in v4.
Regards,
Aleksandar
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web