]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 21 Sep 2017 13:54:30 +0000 (15:54 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 21 Sep 2017 13:54:30 +0000 (15:54 +0200)
added patches:
input-i8042-add-gigabyte-p57-to-the-keyboard-reset-table.patch
mips-math-emu-handle-zero-accumulator-case-in-maddf-and-msubf-separately.patch
mips-math-emu-maddf-msubf-.-d-s-clean-up-maddf_flags-enumeration.patch
mips-math-emu-maddf-msubf-.-d-s-fix-nan-propagation.patch
mips-math-emu-maddf-msubf-.-d-s-fix-some-cases-of-infinite-inputs.patch
mips-math-emu-maddf-msubf-.-d-s-fix-some-cases-of-zero-inputs.patch
mips-math-emu-maddf-msubf-.d-fix-accuracy-64-bit-case.patch
mips-math-emu-maddf-msubf-.s-fix-accuracy-32-bit-case.patch
mips-math-emu-max-maxa-min-mina-.-d-s-fix-cases-of-both-inputs-zero.patch
mips-math-emu-max-maxa-min-mina-.-d-s-fix-quiet-nan-propagation.patch
mips-math-emu-max-min-.-d-s-fix-cases-of-both-inputs-negative.patch
mips-math-emu-maxa-mina-.-d-s-fix-cases-of-both-infinite-inputs.patch
mips-math-emu-maxa-mina-.-d-s-fix-cases-of-input-values-with-opposite-signs.patch
mips-math-emu-mina.-d-s-fix-some-cases-of-infinity-and-zero-inputs.patch

15 files changed:
queue-4.9/input-i8042-add-gigabyte-p57-to-the-keyboard-reset-table.patch [new file with mode: 0644]
queue-4.9/mips-math-emu-handle-zero-accumulator-case-in-maddf-and-msubf-separately.patch [new file with mode: 0644]
queue-4.9/mips-math-emu-maddf-msubf-.-d-s-clean-up-maddf_flags-enumeration.patch [new file with mode: 0644]
queue-4.9/mips-math-emu-maddf-msubf-.-d-s-fix-nan-propagation.patch [new file with mode: 0644]
queue-4.9/mips-math-emu-maddf-msubf-.-d-s-fix-some-cases-of-infinite-inputs.patch [new file with mode: 0644]
queue-4.9/mips-math-emu-maddf-msubf-.-d-s-fix-some-cases-of-zero-inputs.patch [new file with mode: 0644]
queue-4.9/mips-math-emu-maddf-msubf-.d-fix-accuracy-64-bit-case.patch [new file with mode: 0644]
queue-4.9/mips-math-emu-maddf-msubf-.s-fix-accuracy-32-bit-case.patch [new file with mode: 0644]
queue-4.9/mips-math-emu-max-maxa-min-mina-.-d-s-fix-cases-of-both-inputs-zero.patch [new file with mode: 0644]
queue-4.9/mips-math-emu-max-maxa-min-mina-.-d-s-fix-quiet-nan-propagation.patch [new file with mode: 0644]
queue-4.9/mips-math-emu-max-min-.-d-s-fix-cases-of-both-inputs-negative.patch [new file with mode: 0644]
queue-4.9/mips-math-emu-maxa-mina-.-d-s-fix-cases-of-both-infinite-inputs.patch [new file with mode: 0644]
queue-4.9/mips-math-emu-maxa-mina-.-d-s-fix-cases-of-input-values-with-opposite-signs.patch [new file with mode: 0644]
queue-4.9/mips-math-emu-mina.-d-s-fix-some-cases-of-infinity-and-zero-inputs.patch [new file with mode: 0644]
queue-4.9/series

diff --git a/queue-4.9/input-i8042-add-gigabyte-p57-to-the-keyboard-reset-table.patch b/queue-4.9/input-i8042-add-gigabyte-p57-to-the-keyboard-reset-table.patch
new file mode 100644 (file)
index 0000000..e36d5f7
--- /dev/null
@@ -0,0 +1,37 @@
+From 697c5d8a36768b36729533fb44622b35d56d6ad0 Mon Sep 17 00:00:00 2001
+From: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Date: Fri, 15 Sep 2017 09:36:16 -0700
+Subject: Input: i8042 - add Gigabyte P57 to the keyboard reset table
+
+From: Kai-Heng Feng <kai.heng.feng@canonical.com>
+
+commit 697c5d8a36768b36729533fb44622b35d56d6ad0 upstream.
+
+Similar to other Gigabyte laptops, the touchpad on P57 requires a
+keyboard reset to detect Elantech touchpad correctly.
+
+BugLink: https://bugs.launchpad.net/bugs/1594214
+Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/input/serio/i8042-x86ia64io.h |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/input/serio/i8042-x86ia64io.h
++++ b/drivers/input/serio/i8042-x86ia64io.h
+@@ -905,6 +905,13 @@ static const struct dmi_system_id __init
+               },
+       },
+       {
++              /* Gigabyte P57 - Elantech touchpad */
++              .matches = {
++                      DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
++                      DMI_MATCH(DMI_PRODUCT_NAME, "P57"),
++              },
++      },
++      {
+               /* Schenker XMG C504 - Elantech touchpad */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "XMG"),
diff --git a/queue-4.9/mips-math-emu-handle-zero-accumulator-case-in-maddf-and-msubf-separately.patch b/queue-4.9/mips-math-emu-handle-zero-accumulator-case-in-maddf-and-msubf-separately.patch
new file mode 100644 (file)
index 0000000..800dc78
--- /dev/null
@@ -0,0 +1,74 @@
+From ddbfff7429a75d954bf5bdff9f2222bceb4c236a Mon Sep 17 00:00:00 2001
+From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
+Date: Mon, 19 Jun 2017 17:50:12 +0200
+Subject: MIPS: math-emu: Handle zero accumulator case in MADDF and MSUBF separately
+
+From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
+
+commit ddbfff7429a75d954bf5bdff9f2222bceb4c236a upstream.
+
+If accumulator value is zero, just return the value of previously
+calculated product. This brings logic in MADDF/MSUBF implementation
+closer to the logic in ADD/SUB case.
+
+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>
+Cc: James.Hogan@imgtec.com
+Cc: Paul.Burton@imgtec.com
+Cc: Raghu.Gandham@imgtec.com
+Cc: Leonid.Yegoshin@imgtec.com
+Cc: Douglas.Leung@imgtec.com
+Cc: Petar.Jovanovic@imgtec.com
+Cc: linux-mips@linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/16512/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/math-emu/dp_maddf.c |    5 ++++-
+ arch/mips/math-emu/sp_maddf.c |    5 ++++-
+ 2 files changed, 8 insertions(+), 2 deletions(-)
+
+--- a/arch/mips/math-emu/dp_maddf.c
++++ b/arch/mips/math-emu/dp_maddf.c
+@@ -54,7 +54,7 @@ static union ieee754dp _dp_maddf(union i
+               return ieee754dp_nanxcpt(z);
+       case IEEE754_CLASS_DNORM:
+               DPDNORMZ;
+-      /* QNAN is handled separately below */
++      /* QNAN and ZERO cases are handled separately below */
+       }
+       switch (CLPAIR(xc, yc)) {
+@@ -210,6 +210,9 @@ static union ieee754dp _dp_maddf(union i
+       }
+       assert(rm & (DP_HIDDEN_BIT << 3));
++      if (zc == IEEE754_CLASS_ZERO)
++              return ieee754dp_format(rs, re, rm);
++
+       /* And now the addition */
+       assert(zm & DP_HIDDEN_BIT);
+--- a/arch/mips/math-emu/sp_maddf.c
++++ b/arch/mips/math-emu/sp_maddf.c
+@@ -54,7 +54,7 @@ static union ieee754sp _sp_maddf(union i
+               return ieee754sp_nanxcpt(z);
+       case IEEE754_CLASS_DNORM:
+               SPDNORMZ;
+-      /* QNAN is handled separately below */
++      /* QNAN and ZERO cases are handled separately below */
+       }
+       switch (CLPAIR(xc, yc)) {
+@@ -203,6 +203,9 @@ static union ieee754sp _sp_maddf(union i
+       }
+       assert(rm & (SP_HIDDEN_BIT << 3));
++      if (zc == IEEE754_CLASS_ZERO)
++              return ieee754sp_format(rs, re, rm);
++
+       /* And now the addition */
+       assert(zm & SP_HIDDEN_BIT);
diff --git a/queue-4.9/mips-math-emu-maddf-msubf-.-d-s-clean-up-maddf_flags-enumeration.patch b/queue-4.9/mips-math-emu-maddf-msubf-.-d-s-clean-up-maddf_flags-enumeration.patch
new file mode 100644 (file)
index 0000000..13747f2
--- /dev/null
@@ -0,0 +1,177 @@
+From ae11c0619973ffd73a496308d8a1cb5e1a353737 Mon Sep 17 00:00:00 2001
+From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
+Date: Thu, 27 Jul 2017 18:08:57 +0200
+Subject: MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Clean up "maddf_flags" enumeration
+
+From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
+
+commit ae11c0619973ffd73a496308d8a1cb5e1a353737 upstream.
+
+Fix definition and usage of "maddf_flags" enumeration. Avoid duplicate
+definition and apply more common capitalization.
+
+This patch does not change any scenario. It just makes MADDF and
+MSUBF emulation code more readable and easier to maintain, and
+hopefully prevents future bugs as well.
+
+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>
+Reviewed-by: James Hogan <james.hogan@imgtec.com>
+Cc: Bo Hu <bohu@google.com>
+Cc: Douglas Leung <douglas.leung@imgtec.com>
+Cc: Jin Qian <jinqian@google.com>
+Cc: Paul Burton <paul.burton@imgtec.com>
+Cc: Petar Jovanovic <petar.jovanovic@imgtec.com>
+Cc: Raghu Gandham <raghu.gandham@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Cc: linux-kernel@vger.kernel.org
+Patchwork: https://patchwork.linux-mips.org/patch/16889/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/math-emu/dp_maddf.c   |   19 ++++++++-----------
+ arch/mips/math-emu/ieee754int.h |    4 ++++
+ arch/mips/math-emu/sp_maddf.c   |   19 ++++++++-----------
+ 3 files changed, 20 insertions(+), 22 deletions(-)
+
+--- a/arch/mips/math-emu/dp_maddf.c
++++ b/arch/mips/math-emu/dp_maddf.c
+@@ -14,9 +14,6 @@
+ #include "ieee754dp.h"
+-enum maddf_flags {
+-      maddf_negate_product    = 1 << 0,
+-};
+ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x,
+                                union ieee754dp y, enum maddf_flags flags)
+@@ -85,8 +82,8 @@ static union ieee754dp _dp_maddf(union i
+       case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
+       case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+               if ((zc == IEEE754_CLASS_INF) &&
+-                  ((!(flags & maddf_negate_product) && (zs != (xs ^ ys))) ||
+-                   ((flags & maddf_negate_product) && (zs == (xs ^ ys))))) {
++                  ((!(flags & MADDF_NEGATE_PRODUCT) && (zs != (xs ^ ys))) ||
++                   ((flags & MADDF_NEGATE_PRODUCT) && (zs == (xs ^ ys))))) {
+                       /*
+                        * Cases of addition of infinities with opposite signs
+                        * or subtraction of infinities with same signs.
+@@ -99,9 +96,9 @@ static union ieee754dp _dp_maddf(union i
+                * same sign as product (x*y) (in case of MADDF.D instruction)
+                * or product -(x*y) (in MSUBF.D case). The result must be an
+                * infinity, and its sign is determined only by the value of
+-               * (flags & maddf_negate_product) and the signs of x and y.
++               * (flags & MADDF_NEGATE_PRODUCT) and the signs of x and y.
+                */
+-              if (flags & maddf_negate_product)
++              if (flags & MADDF_NEGATE_PRODUCT)
+                       return ieee754dp_inf(1 ^ (xs ^ ys));
+               else
+                       return ieee754dp_inf(xs ^ ys);
+@@ -115,9 +112,9 @@ static union ieee754dp _dp_maddf(union i
+                       return ieee754dp_inf(zs);
+               if (zc == IEEE754_CLASS_ZERO) {
+                       /* Handle cases +0 + (-0) and similar ones. */
+-                      if ((!(flags & maddf_negate_product)
++                      if ((!(flags & MADDF_NEGATE_PRODUCT)
+                                       && (zs == (xs ^ ys))) ||
+-                          ((flags & maddf_negate_product)
++                          ((flags & MADDF_NEGATE_PRODUCT)
+                                       && (zs != (xs ^ ys))))
+                               /*
+                                * Cases of addition of zeros of equal signs
+@@ -167,7 +164,7 @@ static union ieee754dp _dp_maddf(union i
+       re = xe + ye;
+       rs = xs ^ ys;
+-      if (flags & maddf_negate_product)
++      if (flags & MADDF_NEGATE_PRODUCT)
+               rs ^= 1;
+       /* shunt to top of word */
+@@ -291,5 +288,5 @@ union ieee754dp ieee754dp_maddf(union ie
+ union ieee754dp ieee754dp_msubf(union ieee754dp z, union ieee754dp x,
+                               union ieee754dp y)
+ {
+-      return _dp_maddf(z, x, y, maddf_negate_product);
++      return _dp_maddf(z, x, y, MADDF_NEGATE_PRODUCT);
+ }
+--- a/arch/mips/math-emu/ieee754int.h
++++ b/arch/mips/math-emu/ieee754int.h
+@@ -26,6 +26,10 @@
+ #define CLPAIR(x, y)  ((x)*6+(y))
++enum maddf_flags {
++      MADDF_NEGATE_PRODUCT    = 1 << 0,
++};
++
+ static inline void ieee754_clearcx(void)
+ {
+       ieee754_csr.cx = 0;
+--- a/arch/mips/math-emu/sp_maddf.c
++++ b/arch/mips/math-emu/sp_maddf.c
+@@ -14,9 +14,6 @@
+ #include "ieee754sp.h"
+-enum maddf_flags {
+-      maddf_negate_product    = 1 << 0,
+-};
+ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x,
+                                union ieee754sp y, enum maddf_flags flags)
+@@ -86,8 +83,8 @@ static union ieee754sp _sp_maddf(union i
+       case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
+       case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+               if ((zc == IEEE754_CLASS_INF) &&
+-                  ((!(flags & maddf_negate_product) && (zs != (xs ^ ys))) ||
+-                   ((flags & maddf_negate_product) && (zs == (xs ^ ys))))) {
++                  ((!(flags & MADDF_NEGATE_PRODUCT) && (zs != (xs ^ ys))) ||
++                   ((flags & MADDF_NEGATE_PRODUCT) && (zs == (xs ^ ys))))) {
+                       /*
+                        * Cases of addition of infinities with opposite signs
+                        * or subtraction of infinities with same signs.
+@@ -100,9 +97,9 @@ static union ieee754sp _sp_maddf(union i
+                * same sign as product (x*y) (in case of MADDF.D instruction)
+                * or product -(x*y) (in MSUBF.D case). The result must be an
+                * infinity, and its sign is determined only by the value of
+-               * (flags & maddf_negate_product) and the signs of x and y.
++               * (flags & MADDF_NEGATE_PRODUCT) and the signs of x and y.
+                */
+-              if (flags & maddf_negate_product)
++              if (flags & MADDF_NEGATE_PRODUCT)
+                       return ieee754sp_inf(1 ^ (xs ^ ys));
+               else
+                       return ieee754sp_inf(xs ^ ys);
+@@ -116,9 +113,9 @@ static union ieee754sp _sp_maddf(union i
+                       return ieee754sp_inf(zs);
+               if (zc == IEEE754_CLASS_ZERO) {
+                       /* Handle cases +0 + (-0) and similar ones. */
+-                      if ((!(flags & maddf_negate_product)
++                      if ((!(flags & MADDF_NEGATE_PRODUCT)
+                                       && (zs == (xs ^ ys))) ||
+-                          ((flags & maddf_negate_product)
++                          ((flags & MADDF_NEGATE_PRODUCT)
+                                       && (zs != (xs ^ ys))))
+                               /*
+                                * Cases of addition of zeros of equal signs
+@@ -170,7 +167,7 @@ static union ieee754sp _sp_maddf(union i
+       re = xe + ye;
+       rs = xs ^ ys;
+-      if (flags & maddf_negate_product)
++      if (flags & MADDF_NEGATE_PRODUCT)
+               rs ^= 1;
+       /* shunt to top of word */
+@@ -287,5 +284,5 @@ union ieee754sp ieee754sp_maddf(union ie
+ union ieee754sp ieee754sp_msubf(union ieee754sp z, union ieee754sp x,
+                               union ieee754sp y)
+ {
+-      return _sp_maddf(z, x, y, maddf_negate_product);
++      return _sp_maddf(z, x, y, MADDF_NEGATE_PRODUCT);
+ }
diff --git a/queue-4.9/mips-math-emu-maddf-msubf-.-d-s-fix-nan-propagation.patch b/queue-4.9/mips-math-emu-maddf-msubf-.-d-s-fix-nan-propagation.patch
new file mode 100644 (file)
index 0000000..1d7e09d
--- /dev/null
@@ -0,0 +1,277 @@
+From e840be6e7057757befc3581e1699e30fe7f0dd51 Mon Sep 17 00:00:00 2001
+From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
+Date: Thu, 27 Jul 2017 18:08:54 +0200
+Subject: MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Fix NaN propagation
+
+From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
+
+commit e840be6e7057757befc3581e1699e30fe7f0dd51 upstream.
+
+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 correct 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.
+
+A 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>
+Reviewed-by: James Hogan <james.hogan@imgtec.com>
+Cc: Bo Hu <bohu@google.com>
+Cc: Douglas Leung <douglas.leung@imgtec.com>
+Cc: Jin Qian <jinqian@google.com>
+Cc: Paul Burton <paul.burton@imgtec.com>
+Cc: Petar Jovanovic <petar.jovanovic@imgtec.com>
+Cc: Raghu Gandham <raghu.gandham@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Cc: linux-kernel@vger.kernel.org
+Patchwork: https://patchwork.linux-mips.org/patch/16886/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/math-emu/dp_maddf.c |   66 ++++++++++++------------------------------
+ arch/mips/math-emu/sp_maddf.c |   66 +++++++++++++-----------------------------
+ 2 files changed, 41 insertions(+), 91 deletions(-)
+
+--- a/arch/mips/math-emu/dp_maddf.c
++++ b/arch/mips/math-emu/dp_maddf.c
+@@ -48,52 +48,34 @@ static union ieee754dp _dp_maddf(union i
+       ieee754_clearcx();
+-      switch (zc) {
+-      case IEEE754_CLASS_SNAN:
+-              ieee754_setcx(IEEE754_INVALID_OPERATION);
++      /*
++       * Handle the cases when at least one of x, y or z is a NaN.
++       * Order of precedence is sNaN, qNaN and z, x, y.
++       */
++      if (zc == IEEE754_CLASS_SNAN)
+               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):
++      if (xc == IEEE754_CLASS_SNAN)
+               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):
++      if (yc == IEEE754_CLASS_SNAN)
++              return ieee754dp_nanxcpt(y);
++      if (zc == IEEE754_CLASS_QNAN)
++              return z;
++      if (xc == IEEE754_CLASS_QNAN)
++              return x;
++      if (yc == 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;
++      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 +84,6 @@ static union ieee754dp _dp_maddf(union i
+       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 +100,19 @@ static union ieee754dp _dp_maddf(union i
+               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 */
+       }
+--- a/arch/mips/math-emu/sp_maddf.c
++++ b/arch/mips/math-emu/sp_maddf.c
+@@ -48,51 +48,35 @@ static union ieee754sp _sp_maddf(union i
+       ieee754_clearcx();
+-      switch (zc) {
+-      case IEEE754_CLASS_SNAN:
+-              ieee754_setcx(IEEE754_INVALID_OPERATION);
++      /*
++       * Handle the cases when at least one of x, y or z is a NaN.
++       * Order of precedence is sNaN, qNaN and z, x, y.
++       */
++      if (zc == IEEE754_CLASS_SNAN)
+               return ieee754sp_nanxcpt(z);
+-      case IEEE754_CLASS_DNORM:
+-              SPDNORMZ;
+-      /* 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):
++      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;
++      if (yc == IEEE754_CLASS_QNAN)
++              return 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);
++      if (zc == IEEE754_CLASS_DNORM)
++              SPDNORMZ;
++      /* ZERO z cases are handled separately below */
+-      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;
++      switch (CLPAIR(xc, yc)) {
+-      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 +85,6 @@ static union ieee754sp _sp_maddf(union i
+       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 +101,19 @@ static union ieee754sp _sp_maddf(union i
+               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 */
+       }
diff --git a/queue-4.9/mips-math-emu-maddf-msubf-.-d-s-fix-some-cases-of-infinite-inputs.patch b/queue-4.9/mips-math-emu-maddf-msubf-.-d-s-fix-some-cases-of-infinite-inputs.patch
new file mode 100644 (file)
index 0000000..4bea1f1
--- /dev/null
@@ -0,0 +1,114 @@
+From 0c64fe6348687f0e1cea9a608eae9d351124a73a Mon Sep 17 00:00:00 2001
+From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
+Date: Thu, 27 Jul 2017 18:08:55 +0200
+Subject: MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Fix some cases of infinite inputs
+
+From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
+
+commit 0c64fe6348687f0e1cea9a608eae9d351124a73a upstream.
+
+Fix the cases of <MADDF|MSUBF>.<D|S> when any of two multiplicands is
+infinity. The correct behavior in such cases is affected by the nature
+of third input. Cases of addition of infinities with opposite signs
+and subtraction of infinities with same signs may arise and must be
+handles separately. Also, the value od flags argument (that determines
+whether the instruction is MADDF or MSUBF) affects the outcome.
+
+Relevant examples:
+
+MADDF.S fd,fs,ft:
+  If fs contains +inf, ft contains +inf, and fd contains -inf, fd is
+  going to contain indef (without this patch, it used to contain
+  -inf).
+
+MSUBF.S fd,fs,ft:
+  If fs contains +inf, ft contains 1.0, and fd contains +0.0, fd is
+  going to contain -inf (without this patch, it used to contain +inf).
+
+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: Douglas Leung <douglas.leung@imgtec.com>
+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>
+Reviewed-by: James Hogan <james.hogan@imgtec.com>
+Cc: Douglas Leung <douglas.leung@imgtec.com>
+Cc: Bo Hu <bohu@google.com>
+Cc: Jin Qian <jinqian@google.com>
+Cc: Paul Burton <paul.burton@imgtec.com>
+Cc: Petar Jovanovic <petar.jovanovic@imgtec.com>
+Cc: Raghu Gandham <raghu.gandham@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Cc: linux-kernel@vger.kernel.org
+Patchwork: https://patchwork.linux-mips.org/patch/16887/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/math-emu/dp_maddf.c |   22 +++++++++++++++++++++-
+ arch/mips/math-emu/sp_maddf.c |   22 +++++++++++++++++++++-
+ 2 files changed, 42 insertions(+), 2 deletions(-)
+
+--- a/arch/mips/math-emu/dp_maddf.c
++++ b/arch/mips/math-emu/dp_maddf.c
+@@ -84,7 +84,27 @@ static union ieee754dp _dp_maddf(union i
+       case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
+       case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
+       case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+-              return ieee754dp_inf(xs ^ ys);
++              if ((zc == IEEE754_CLASS_INF) &&
++                  ((!(flags & maddf_negate_product) && (zs != (xs ^ ys))) ||
++                   ((flags & maddf_negate_product) && (zs == (xs ^ ys))))) {
++                      /*
++                       * Cases of addition of infinities with opposite signs
++                       * or subtraction of infinities with same signs.
++                       */
++                      ieee754_setcx(IEEE754_INVALID_OPERATION);
++                      return ieee754dp_indef();
++              }
++              /*
++               * z is here either not an infinity, or an infinity having the
++               * same sign as product (x*y) (in case of MADDF.D instruction)
++               * or product -(x*y) (in MSUBF.D case). The result must be an
++               * infinity, and its sign is determined only by the value of
++               * (flags & maddf_negate_product) and the signs of x and y.
++               */
++              if (flags & maddf_negate_product)
++                      return ieee754dp_inf(1 ^ (xs ^ ys));
++              else
++                      return ieee754dp_inf(xs ^ ys);
+       case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
+       case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
+--- a/arch/mips/math-emu/sp_maddf.c
++++ b/arch/mips/math-emu/sp_maddf.c
+@@ -85,7 +85,27 @@ static union ieee754sp _sp_maddf(union i
+       case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
+       case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
+       case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+-              return ieee754sp_inf(xs ^ ys);
++              if ((zc == IEEE754_CLASS_INF) &&
++                  ((!(flags & maddf_negate_product) && (zs != (xs ^ ys))) ||
++                   ((flags & maddf_negate_product) && (zs == (xs ^ ys))))) {
++                      /*
++                       * Cases of addition of infinities with opposite signs
++                       * or subtraction of infinities with same signs.
++                       */
++                      ieee754_setcx(IEEE754_INVALID_OPERATION);
++                      return ieee754sp_indef();
++              }
++              /*
++               * z is here either not an infinity, or an infinity having the
++               * same sign as product (x*y) (in case of MADDF.D instruction)
++               * or product -(x*y) (in MSUBF.D case). The result must be an
++               * infinity, and its sign is determined only by the value of
++               * (flags & maddf_negate_product) and the signs of x and y.
++               */
++              if (flags & maddf_negate_product)
++                      return ieee754sp_inf(1 ^ (xs ^ ys));
++              else
++                      return ieee754sp_inf(xs ^ ys);
+       case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
+       case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
diff --git a/queue-4.9/mips-math-emu-maddf-msubf-.-d-s-fix-some-cases-of-zero-inputs.patch b/queue-4.9/mips-math-emu-maddf-msubf-.-d-s-fix-some-cases-of-zero-inputs.patch
new file mode 100644 (file)
index 0000000..dea4e4e
--- /dev/null
@@ -0,0 +1,97 @@
+From 7cf64ce4d37f1b4f44365fcf77f565d523819dcd Mon Sep 17 00:00:00 2001
+From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
+Date: Thu, 27 Jul 2017 18:08:56 +0200
+Subject: MIPS: math-emu: <MADDF|MSUBF>.<D|S>: Fix some cases of zero inputs
+
+From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
+
+commit 7cf64ce4d37f1b4f44365fcf77f565d523819dcd upstream.
+
+Fix the cases of <MADDF|MSUBF>.<D|S> when any of two multiplicands is
++0 or -0, and the third input is also +0 or -0. Depending on the signs
+of inputs, certain special cases must be handled.
+
+A relevant example:
+
+MADDF.S fd,fs,ft:
+  If fs contains +0.0, ft contains -0.0, and fd contains 0.0, fd is
+  going to contain +0.0 (without this patch, it used to contain -0.0).
+
+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>
+Reviewed-by: James Hogan <james.hogan@imgtec.com>
+Cc: Bo Hu <bohu@google.com>
+Cc: Douglas Leung <douglas.leung@imgtec.com>
+Cc: Jin Qian <jinqian@google.com>
+Cc: Paul Burton <paul.burton@imgtec.com>
+Cc: Petar Jovanovic <petar.jovanovic@imgtec.com>
+Cc: Raghu Gandham <raghu.gandham@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Cc: linux-kernel@vger.kernel.org
+Patchwork: https://patchwork.linux-mips.org/patch/16888/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/math-emu/dp_maddf.c |   18 +++++++++++++++++-
+ arch/mips/math-emu/sp_maddf.c |   18 +++++++++++++++++-
+ 2 files changed, 34 insertions(+), 2 deletions(-)
+
+--- a/arch/mips/math-emu/dp_maddf.c
++++ b/arch/mips/math-emu/dp_maddf.c
+@@ -113,7 +113,23 @@ static union ieee754dp _dp_maddf(union i
+       case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
+               if (zc == IEEE754_CLASS_INF)
+                       return ieee754dp_inf(zs);
+-              /* Multiplication is 0 so just return z */
++              if (zc == IEEE754_CLASS_ZERO) {
++                      /* Handle cases +0 + (-0) and similar ones. */
++                      if ((!(flags & maddf_negate_product)
++                                      && (zs == (xs ^ ys))) ||
++                          ((flags & maddf_negate_product)
++                                      && (zs != (xs ^ ys))))
++                              /*
++                               * Cases of addition of zeros of equal signs
++                               * or subtraction of zeroes of opposite signs.
++                               * The sign of the resulting zero is in any
++                               * such case determined only by the sign of z.
++                               */
++                              return z;
++
++                      return ieee754dp_zero(ieee754_csr.rm == FPU_CSR_RD);
++              }
++              /* x*y is here 0, and z is not 0, so just return z */
+               return z;
+       case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
+--- a/arch/mips/math-emu/sp_maddf.c
++++ b/arch/mips/math-emu/sp_maddf.c
+@@ -114,7 +114,23 @@ static union ieee754sp _sp_maddf(union i
+       case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
+               if (zc == IEEE754_CLASS_INF)
+                       return ieee754sp_inf(zs);
+-              /* Multiplication is 0 so just return z */
++              if (zc == IEEE754_CLASS_ZERO) {
++                      /* Handle cases +0 + (-0) and similar ones. */
++                      if ((!(flags & maddf_negate_product)
++                                      && (zs == (xs ^ ys))) ||
++                          ((flags & maddf_negate_product)
++                                      && (zs != (xs ^ ys))))
++                              /*
++                               * Cases of addition of zeros of equal signs
++                               * or subtraction of zeroes of opposite signs.
++                               * The sign of the resulting zero is in any
++                               * such case determined only by the sign of z.
++                               */
++                              return z;
++
++                      return ieee754sp_zero(ieee754_csr.rm == FPU_CSR_RD);
++              }
++              /* x*y is here 0, and z is not 0, so just return z */
+               return z;
+       case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
diff --git a/queue-4.9/mips-math-emu-maddf-msubf-.d-fix-accuracy-64-bit-case.patch b/queue-4.9/mips-math-emu-maddf-msubf-.d-fix-accuracy-64-bit-case.patch
new file mode 100644 (file)
index 0000000..4ec2242
--- /dev/null
@@ -0,0 +1,255 @@
+From 2cfa58259f4b65b33ebe8f167019a1f89c6c3289 Mon Sep 17 00:00:00 2001
+From: Douglas Leung <douglas.leung@imgtec.com>
+Date: Thu, 27 Jul 2017 18:08:59 +0200
+Subject: MIPS: math-emu: <MADDF|MSUBF>.D: Fix accuracy (64-bit case)
+
+From: Douglas Leung <douglas.leung@imgtec.com>
+
+commit 2cfa58259f4b65b33ebe8f167019a1f89c6c3289 upstream.
+
+Implement fused multiply-add with correct accuracy.
+
+Fused multiply-add operation has better accuracy than respective
+sequential execution of multiply and add operations applied on the
+same inputs. This is because accuracy errors accumulate in latter
+case.
+
+This patch implements fused multiply-add with the same accuracy
+as it is implemented in hardware, using 128-bit intermediate
+calculations.
+
+One test case example (raw bits) that this patch fixes:
+
+MADDF.D fd,fs,ft:
+  fd = 0x00000ca000000000
+  fs = ft = 0x3f40624dd2f1a9fc
+
+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: Douglas Leung <douglas.leung@imgtec.com>
+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>
+Cc: Douglas Leung <douglas.leung@imgtec.com>
+Cc: Bo Hu <bohu@google.com>
+Cc: James Hogan <james.hogan@imgtec.com>
+Cc: Jin Qian <jinqian@google.com>
+Cc: Paul Burton <paul.burton@imgtec.com>
+Cc: Petar Jovanovic <petar.jovanovic@imgtec.com>
+Cc: Raghu Gandham <raghu.gandham@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Cc: linux-kernel@vger.kernel.org
+Patchwork: https://patchwork.linux-mips.org/patch/16891/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/math-emu/dp_maddf.c |  133 +++++++++++++++++++++++++++++-------------
+ 1 file changed, 94 insertions(+), 39 deletions(-)
+
+--- a/arch/mips/math-emu/dp_maddf.c
++++ b/arch/mips/math-emu/dp_maddf.c
+@@ -15,18 +15,44 @@
+ #include "ieee754dp.h"
++/* 128 bits shift right logical with rounding. */
++void srl128(u64 *hptr, u64 *lptr, int count)
++{
++      u64 low;
++
++      if (count >= 128) {
++              *lptr = *hptr != 0 || *lptr != 0;
++              *hptr = 0;
++      } else if (count >= 64) {
++              if (count == 64) {
++                      *lptr = *hptr | (*lptr != 0);
++              } else {
++                      low = *lptr;
++                      *lptr = *hptr >> (count - 64);
++                      *lptr |= (*hptr << (128 - count)) != 0 || low != 0;
++              }
++              *hptr = 0;
++      } else {
++              low = *lptr;
++              *lptr = low >> count | *hptr << (64 - count);
++              *lptr |= (low << (64 - count)) != 0;
++              *hptr = *hptr >> count;
++      }
++}
++
+ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x,
+                                union ieee754dp y, enum maddf_flags flags)
+ {
+       int re;
+       int rs;
+-      u64 rm;
+       unsigned lxm;
+       unsigned hxm;
+       unsigned lym;
+       unsigned hym;
+       u64 lrm;
+       u64 hrm;
++      u64 lzm;
++      u64 hzm;
+       u64 t;
+       u64 at;
+       int s;
+@@ -172,7 +198,7 @@ static union ieee754dp _dp_maddf(union i
+       ym <<= 64 - (DP_FBITS + 1);
+       /*
+-       * Multiply 64 bits xm, ym to give high 64 bits rm with stickness.
++       * Multiply 64 bits xm and ym to give 128 bits result in hrm:lrm.
+        */
+       /* 32 * 32 => 64 */
+@@ -202,81 +228,110 @@ static union ieee754dp _dp_maddf(union i
+       hrm = hrm + (t >> 32);
+-      rm = hrm | (lrm != 0);
+-
+-      /*
+-       * Sticky shift down to normal rounding precision.
+-       */
+-      if ((s64) rm < 0) {
+-              rm = (rm >> (64 - (DP_FBITS + 1 + 3))) |
+-                   ((rm << (DP_FBITS + 1 + 3)) != 0);
++      /* Put explicit bit at bit 126 if necessary */
++      if ((int64_t)hrm < 0) {
++              lrm = (hrm << 63) | (lrm >> 1);
++              hrm = hrm >> 1;
+               re++;
+-      } else {
+-              rm = (rm >> (64 - (DP_FBITS + 1 + 3 + 1))) |
+-                   ((rm << (DP_FBITS + 1 + 3 + 1)) != 0);
+       }
+-      assert(rm & (DP_HIDDEN_BIT << 3));
+-      if (zc == IEEE754_CLASS_ZERO)
+-              return ieee754dp_format(rs, re, rm);
++      assert(hrm & (1 << 62));
+-      /* And now the addition */
+-      assert(zm & DP_HIDDEN_BIT);
++      if (zc == IEEE754_CLASS_ZERO) {
++              /*
++               * Move explicit bit from bit 126 to bit 55 since the
++               * ieee754dp_format code expects the mantissa to be
++               * 56 bits wide (53 + 3 rounding bits).
++               */
++              srl128(&hrm, &lrm, (126 - 55));
++              return ieee754dp_format(rs, re, lrm);
++      }
+-      /*
+-       * Provide guard,round and stick bit space.
+-       */
+-      zm <<= 3;
++      /* Move explicit bit from bit 52 to bit 126 */
++      lzm = 0;
++      hzm = zm << 10;
++      assert(hzm & (1 << 62));
++      /* Make the exponents the same */
+       if (ze > re) {
+               /*
+                * Have to shift y fraction right to align.
+                */
+               s = ze - re;
+-              rm = XDPSRS(rm, s);
++              srl128(&hrm, &lrm, s);
+               re += s;
+       } else if (re > ze) {
+               /*
+                * Have to shift x fraction right to align.
+                */
+               s = re - ze;
+-              zm = XDPSRS(zm, s);
++              srl128(&hzm, &lzm, s);
+               ze += s;
+       }
+       assert(ze == re);
+       assert(ze <= DP_EMAX);
++      /* Do the addition */
+       if (zs == rs) {
+               /*
+-               * Generate 28 bit result of adding two 27 bit numbers
+-               * leaving result in xm, xs and xe.
++               * Generate 128 bit result by adding two 127 bit numbers
++               * leaving result in hzm:lzm, zs and ze.
+                */
+-              zm = zm + rm;
+-
+-              if (zm >> (DP_FBITS + 1 + 3)) { /* carry out */
+-                      zm = XDPSRS1(zm);
++              hzm = hzm + hrm + (lzm > (lzm + lrm));
++              lzm = lzm + lrm;
++              if ((int64_t)hzm < 0) {        /* carry out */
++                      srl128(&hzm, &lzm, 1);
+                       ze++;
+               }
+       } else {
+-              if (zm >= rm) {
+-                      zm = zm - rm;
++              if (hzm > hrm || (hzm == hrm && lzm >= lrm)) {
++                      hzm = hzm - hrm - (lzm < lrm);
++                      lzm = lzm - lrm;
+               } else {
+-                      zm = rm - zm;
++                      hzm = hrm - hzm - (lrm < lzm);
++                      lzm = lrm - lzm;
+                       zs = rs;
+               }
+-              if (zm == 0)
++              if (lzm == 0 && hzm == 0)
+                       return ieee754dp_zero(ieee754_csr.rm == FPU_CSR_RD);
+               /*
+-               * Normalize to rounding precision.
++               * Put explicit bit at bit 126 if necessary.
+                */
+-              while ((zm >> (DP_FBITS + 3)) == 0) {
+-                      zm <<= 1;
+-                      ze--;
++              if (hzm == 0) {
++                      /* left shift by 63 or 64 bits */
++                      if ((int64_t)lzm < 0) {
++                              /* MSB of lzm is the explicit bit */
++                              hzm = lzm >> 1;
++                              lzm = lzm << 63;
++                              ze -= 63;
++                      } else {
++                              hzm = lzm;
++                              lzm = 0;
++                              ze -= 64;
++                      }
++              }
++
++              t = 0;
++              while ((hzm >> (62 - t)) == 0)
++                      t++;
++
++              assert(t <= 62);
++              if (t) {
++                      hzm = hzm << t | lzm >> (64 - t);
++                      lzm = lzm << t;
++                      ze -= t;
+               }
+       }
+-      return ieee754dp_format(zs, ze, zm);
++      /*
++       * Move explicit bit from bit 126 to bit 55 since the
++       * ieee754dp_format code expects the mantissa to be
++       * 56 bits wide (53 + 3 rounding bits).
++       */
++      srl128(&hzm, &lzm, (126 - 55));
++
++      return ieee754dp_format(zs, ze, lzm);
+ }
+ union ieee754dp ieee754dp_maddf(union ieee754dp z, union ieee754dp x,
diff --git a/queue-4.9/mips-math-emu-maddf-msubf-.s-fix-accuracy-32-bit-case.patch b/queue-4.9/mips-math-emu-maddf-msubf-.s-fix-accuracy-32-bit-case.patch
new file mode 100644 (file)
index 0000000..ef4e106
--- /dev/null
@@ -0,0 +1,236 @@
+From b3b8e1eb27c523e32b6a8aa7ec8ac4754456af57 Mon Sep 17 00:00:00 2001
+From: Douglas Leung <douglas.leung@imgtec.com>
+Date: Thu, 27 Jul 2017 18:08:58 +0200
+Subject: MIPS: math-emu: <MADDF|MSUBF>.S: Fix accuracy (32-bit case)
+
+From: Douglas Leung <douglas.leung@imgtec.com>
+
+commit b3b8e1eb27c523e32b6a8aa7ec8ac4754456af57 upstream.
+
+Implement fused multiply-add with correct accuracy.
+
+Fused multiply-add operation has better accuracy than respective
+sequential execution of multiply and add operations applied on the
+same inputs. This is because accuracy errors accumulate in latter
+case.
+
+This patch implements fused multiply-add with the same accuracy
+as it is implemented in hardware, using 64-bit intermediate
+calculations.
+
+One test case example (raw bits) that this patch fixes:
+
+MADDF.S fd,fs,ft:
+  fd = 0x22575225
+  fs = ft = 0x3727c5ac
+
+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: Douglas Leung <douglas.leung@imgtec.com>
+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>
+Cc: Douglas Leung <douglas.leung@imgtec.com>
+Cc: Bo Hu <bohu@google.com>
+Cc: James Hogan <james.hogan@imgtec.com>
+Cc: Jin Qian <jinqian@google.com>
+Cc: Paul Burton <paul.burton@imgtec.com>
+Cc: Petar Jovanovic <petar.jovanovic@imgtec.com>
+Cc: Raghu Gandham <raghu.gandham@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Cc: linux-kernel@vger.kernel.org
+Patchwork: https://patchwork.linux-mips.org/patch/16890/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/math-emu/ieee754sp.h |    4 +
+ arch/mips/math-emu/sp_maddf.c  |  116 ++++++++++++++++-------------------------
+ 2 files changed, 50 insertions(+), 70 deletions(-)
+
+--- a/arch/mips/math-emu/ieee754sp.h
++++ b/arch/mips/math-emu/ieee754sp.h
+@@ -45,6 +45,10 @@ static inline int ieee754sp_finite(union
+       return SPBEXP(x) != SP_EMAX + 1 + SP_EBIAS;
+ }
++/* 64 bit right shift with rounding */
++#define XSPSRS64(v, rs)                                               \
++      (((rs) >= 64) ? ((v) != 0) : ((v) >> (rs)) | ((v) << (64-(rs)) != 0))
++
+ /* 3bit extended single precision sticky right shift */
+ #define XSPSRS(v, rs)                                         \
+       ((rs > (SP_FBITS+3))?1:((v) >> (rs)) | ((v) << (32-(rs)) != 0))
+--- a/arch/mips/math-emu/sp_maddf.c
++++ b/arch/mips/math-emu/sp_maddf.c
+@@ -21,14 +21,8 @@ static union ieee754sp _sp_maddf(union i
+       int re;
+       int rs;
+       unsigned rm;
+-      unsigned short lxm;
+-      unsigned short hxm;
+-      unsigned short lym;
+-      unsigned short hym;
+-      unsigned lrm;
+-      unsigned hrm;
+-      unsigned t;
+-      unsigned at;
++      uint64_t rm64;
++      uint64_t zm64;
+       int s;
+       COMPXSP;
+@@ -170,108 +164,90 @@ static union ieee754sp _sp_maddf(union i
+       if (flags & MADDF_NEGATE_PRODUCT)
+               rs ^= 1;
+-      /* shunt to top of word */
+-      xm <<= 32 - (SP_FBITS + 1);
+-      ym <<= 32 - (SP_FBITS + 1);
++      /* Multiple 24 bit xm and ym to give 48 bit results */
++      rm64 = (uint64_t)xm * ym;
+-      /*
+-       * Multiply 32 bits xm, ym to give high 32 bits rm with stickness.
+-       */
+-      lxm = xm & 0xffff;
+-      hxm = xm >> 16;
+-      lym = ym & 0xffff;
+-      hym = ym >> 16;
+-
+-      lrm = lxm * lym;        /* 16 * 16 => 32 */
+-      hrm = hxm * hym;        /* 16 * 16 => 32 */
+-
+-      t = lxm * hym; /* 16 * 16 => 32 */
+-      at = lrm + (t << 16);
+-      hrm += at < lrm;
+-      lrm = at;
+-      hrm = hrm + (t >> 16);
+-
+-      t = hxm * lym; /* 16 * 16 => 32 */
+-      at = lrm + (t << 16);
+-      hrm += at < lrm;
+-      lrm = at;
+-      hrm = hrm + (t >> 16);
+-
+-      rm = hrm | (lrm != 0);
++      /* Shunt to top of word */
++      rm64 = rm64 << 16;
+-      /*
+-       * Sticky shift down to normal rounding precision.
+-       */
+-      if ((int) rm < 0) {
+-              rm = (rm >> (32 - (SP_FBITS + 1 + 3))) |
+-                  ((rm << (SP_FBITS + 1 + 3)) != 0);
++      /* Put explicit bit at bit 62 if necessary */
++      if ((int64_t) rm64 < 0) {
++              rm64 = rm64 >> 1;
+               re++;
+-      } else {
+-              rm = (rm >> (32 - (SP_FBITS + 1 + 3 + 1))) |
+-                   ((rm << (SP_FBITS + 1 + 3 + 1)) != 0);
+       }
+-      assert(rm & (SP_HIDDEN_BIT << 3));
+-
+-      if (zc == IEEE754_CLASS_ZERO)
+-              return ieee754sp_format(rs, re, rm);
+-      /* And now the addition */
++      assert(rm64 & (1 << 62));
+-      assert(zm & SP_HIDDEN_BIT);
++      if (zc == IEEE754_CLASS_ZERO) {
++              /*
++               * Move explicit bit from bit 62 to bit 26 since the
++               * ieee754sp_format code expects the mantissa to be
++               * 27 bits wide (24 + 3 rounding bits).
++               */
++              rm = XSPSRS64(rm64, (62 - 26));
++              return ieee754sp_format(rs, re, rm);
++      }
+-      /*
+-       * Provide guard,round and stick bit space.
+-       */
+-      zm <<= 3;
++      /* Move explicit bit from bit 23 to bit 62 */
++      zm64 = (uint64_t)zm << (62 - 23);
++      assert(zm64 & (1 << 62));
++      /* Make the exponents the same */
+       if (ze > re) {
+               /*
+                * Have to shift r fraction right to align.
+                */
+               s = ze - re;
+-              rm = XSPSRS(rm, s);
++              rm64 = XSPSRS64(rm64, s);
+               re += s;
+       } else if (re > ze) {
+               /*
+                * Have to shift z fraction right to align.
+                */
+               s = re - ze;
+-              zm = XSPSRS(zm, s);
++              zm64 = XSPSRS64(zm64, s);
+               ze += s;
+       }
+       assert(ze == re);
+       assert(ze <= SP_EMAX);
++      /* Do the addition */
+       if (zs == rs) {
+               /*
+-               * Generate 28 bit result of adding two 27 bit numbers
+-               * leaving result in zm, zs and ze.
++               * Generate 64 bit result by adding two 63 bit numbers
++               * leaving result in zm64, zs and ze.
+                */
+-              zm = zm + rm;
+-
+-              if (zm >> (SP_FBITS + 1 + 3)) { /* carry out */
+-                      zm = XSPSRS1(zm);
++              zm64 = zm64 + rm64;
++              if ((int64_t)zm64 < 0) {        /* carry out */
++                      zm64 = XSPSRS1(zm64);
+                       ze++;
+               }
+       } else {
+-              if (zm >= rm) {
+-                      zm = zm - rm;
++              if (zm64 >= rm64) {
++                      zm64 = zm64 - rm64;
+               } else {
+-                      zm = rm - zm;
++                      zm64 = rm64 - zm64;
+                       zs = rs;
+               }
+-              if (zm == 0)
++              if (zm64 == 0)
+                       return ieee754sp_zero(ieee754_csr.rm == FPU_CSR_RD);
+               /*
+-               * Normalize in extended single precision
++               * Put explicit bit at bit 62 if necessary.
+                */
+-              while ((zm >> (SP_MBITS + 3)) == 0) {
+-                      zm <<= 1;
++              while ((zm64 >> 62) == 0) {
++                      zm64 <<= 1;
+                       ze--;
+               }
+-
+       }
++
++      /*
++       * Move explicit bit from bit 62 to bit 26 since the
++       * ieee754sp_format code expects the mantissa to be
++       * 27 bits wide (24 + 3 rounding bits).
++       */
++      zm = XSPSRS64(zm64, (62 - 26));
++
+       return ieee754sp_format(zs, ze, zm);
+ }
diff --git a/queue-4.9/mips-math-emu-max-maxa-min-mina-.-d-s-fix-cases-of-both-inputs-zero.patch b/queue-4.9/mips-math-emu-max-maxa-min-mina-.-d-s-fix-cases-of-both-inputs-zero.patch
new file mode 100644 (file)
index 0000000..37214c6
--- /dev/null
@@ -0,0 +1,152 @@
+From 15560a58bfd4ff82cdd16b2270d4ef9b06d2cc4d Mon Sep 17 00:00:00 2001
+From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
+Date: Thu, 27 Jul 2017 18:08:49 +0200
+Subject: MIPS: math-emu: <MAX|MAXA|MIN|MINA>.<D|S>: Fix cases of both inputs zero
+
+From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
+
+commit 15560a58bfd4ff82cdd16b2270d4ef9b06d2cc4d upstream.
+
+Fix the value returned by <MAX|MAXA|MIN|MINA>.<D|S>, if both inputs
+are zeros. The right behavior in such cases is stated in instruction
+reference manual and is as follows:
+
+   fs  ft       MAX     MIN       MAXA    MINA
+  ---------------------------------------------
+    0   0        0       0         0       0
+    0  -0        0      -0         0      -0
+   -0   0        0      -0         0      -0
+   -0  -0       -0      -0        -0      -0
+
+Prior to this patch, some of the above cases were yielding correct
+results. However, for the sake of code consistency, all such cases
+are rewritten in this patch.
+
+A relevant example:
+
+MAX.S fd,fs,ft:
+  If fs contains +0.0, and ft contains -0.0, fd is going to contain
+  +0.0 (without this patch, it used to contain -0.0).
+
+Fixes: a79f5f9ba508 ("MIPS: math-emu: Add support for the MIPS R6 MAX{, A} FPU instruction")
+Fixes: 4e9561b20e2f ("MIPS: math-emu: Add support for the MIPS R6 MIN{, A} 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>
+Reviewed-by: James Hogan <james.hogan@imgtec.com>
+Cc: Bo Hu <bohu@google.com>
+Cc: Douglas Leung <douglas.leung@imgtec.com>
+Cc: Jin Qian <jinqian@google.com>
+Cc: Paul Burton <paul.burton@imgtec.com>
+Cc: Petar Jovanovic <petar.jovanovic@imgtec.com>
+Cc: Raghu Gandham <raghu.gandham@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Cc: linux-kernel@vger.kernel.org
+Patchwork: https://patchwork.linux-mips.org/patch/16881/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/math-emu/dp_fmax.c |    8 ++------
+ arch/mips/math-emu/dp_fmin.c |    8 ++------
+ arch/mips/math-emu/sp_fmax.c |    8 ++------
+ arch/mips/math-emu/sp_fmin.c |    8 ++------
+ 4 files changed, 8 insertions(+), 24 deletions(-)
+
+--- a/arch/mips/math-emu/dp_fmax.c
++++ b/arch/mips/math-emu/dp_fmax.c
+@@ -92,9 +92,7 @@ union ieee754dp ieee754dp_fmax(union iee
+               return ys ? x : y;
+       case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
+-              if (xs == ys)
+-                      return x;
+-              return ieee754dp_zero(1);
++              return ieee754dp_zero(xs & ys);
+       case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
+               DPDNORMX;
+@@ -204,9 +202,7 @@ union ieee754dp ieee754dp_fmaxa(union ie
+               return y;
+       case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
+-              if (xs == ys)
+-                      return x;
+-              return ieee754dp_zero(1);
++              return ieee754dp_zero(xs & ys);
+       case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
+               DPDNORMX;
+--- a/arch/mips/math-emu/dp_fmin.c
++++ b/arch/mips/math-emu/dp_fmin.c
+@@ -92,9 +92,7 @@ union ieee754dp ieee754dp_fmin(union iee
+               return ys ? y : x;
+       case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
+-              if (xs == ys)
+-                      return x;
+-              return ieee754dp_zero(1);
++              return ieee754dp_zero(xs | ys);
+       case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
+               DPDNORMX;
+@@ -204,9 +202,7 @@ union ieee754dp ieee754dp_fmina(union ie
+               return y;
+       case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
+-              if (xs == ys)
+-                      return x;
+-              return ieee754dp_zero(1);
++              return ieee754dp_zero(xs | ys);
+       case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
+               DPDNORMX;
+--- a/arch/mips/math-emu/sp_fmax.c
++++ b/arch/mips/math-emu/sp_fmax.c
+@@ -92,9 +92,7 @@ union ieee754sp ieee754sp_fmax(union iee
+               return ys ? x : y;
+       case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
+-              if (xs == ys)
+-                      return x;
+-              return ieee754sp_zero(1);
++              return ieee754sp_zero(xs & ys);
+       case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
+               SPDNORMX;
+@@ -204,9 +202,7 @@ union ieee754sp ieee754sp_fmaxa(union ie
+               return y;
+       case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
+-              if (xs == ys)
+-                      return x;
+-              return ieee754sp_zero(1);
++              return ieee754sp_zero(xs & ys);
+       case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
+               SPDNORMX;
+--- a/arch/mips/math-emu/sp_fmin.c
++++ b/arch/mips/math-emu/sp_fmin.c
+@@ -92,9 +92,7 @@ union ieee754sp ieee754sp_fmin(union iee
+               return ys ? y : x;
+       case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
+-              if (xs == ys)
+-                      return x;
+-              return ieee754sp_zero(1);
++              return ieee754sp_zero(xs | ys);
+       case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
+               SPDNORMX;
+@@ -204,9 +202,7 @@ union ieee754sp ieee754sp_fmina(union ie
+               return y;
+       case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
+-              if (xs == ys)
+-                      return x;
+-              return ieee754sp_zero(1);
++              return ieee754sp_zero(xs | ys);
+       case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
+               SPDNORMX;
diff --git a/queue-4.9/mips-math-emu-max-maxa-min-mina-.-d-s-fix-quiet-nan-propagation.patch b/queue-4.9/mips-math-emu-max-maxa-min-mina-.-d-s-fix-quiet-nan-propagation.patch
new file mode 100644 (file)
index 0000000..617624c
--- /dev/null
@@ -0,0 +1,286 @@
+From e78bf0dc4789bdea1453595ae89e8db65918e22e Mon Sep 17 00:00:00 2001
+From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
+Date: Thu, 27 Jul 2017 18:08:48 +0200
+Subject: MIPS: math-emu: <MAX|MAXA|MIN|MINA>.<D|S>: Fix quiet NaN propagation
+
+From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
+
+commit e78bf0dc4789bdea1453595ae89e8db65918e22e upstream.
+
+Fix the value returned by <MAX|MAXA|MIN|MINA>.<D|S> fd,fs,ft, if both
+inputs are quiet NaNs. The <MAX|MAXA|MIN|MINA>.<D|S> specifications
+state that the returned value in such cases should be the quiet NaN
+contained in register fs.
+
+A relevant example:
+
+MAX.S fd,fs,ft:
+  If fs contains qNaN1, and ft contains qNaN2, fd is going to contain
+  qNaN1 (without this patch, it used to contain qNaN2).
+
+Fixes: a79f5f9ba508 ("MIPS: math-emu: Add support for the MIPS R6 MAX{, A} FPU instruction")
+Fixes: 4e9561b20e2f ("MIPS: math-emu: Add support for the MIPS R6 MIN{, A} 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>
+Reviewed-by: James Hogan <james.hogan@imgtec.com>
+Cc: Bo Hu <bohu@google.com>
+Cc: Douglas Leung <douglas.leung@imgtec.com>
+Cc: Jin Qian <jinqian@google.com>
+Cc: Paul Burton <paul.burton@imgtec.com>
+Cc: Petar Jovanovic <petar.jovanovic@imgtec.com>
+Cc: Raghu Gandham <raghu.gandham@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Cc: linux-kernel@vger.kernel.org
+Patchwork: https://patchwork.linux-mips.org/patch/16880/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/math-emu/dp_fmax.c |   32 ++++++++++++++++++++++++++++----
+ arch/mips/math-emu/dp_fmin.c |   32 ++++++++++++++++++++++++++++----
+ arch/mips/math-emu/sp_fmax.c |   32 ++++++++++++++++++++++++++++----
+ arch/mips/math-emu/sp_fmin.c |   32 ++++++++++++++++++++++++++++----
+ 4 files changed, 112 insertions(+), 16 deletions(-)
+
+--- a/arch/mips/math-emu/dp_fmax.c
++++ b/arch/mips/math-emu/dp_fmax.c
+@@ -47,14 +47,26 @@ union ieee754dp ieee754dp_fmax(union iee
+       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
+               return ieee754dp_nanxcpt(x);
+-      /* numbers are preferred to NaNs */
++      /*
++       * Quiet NaN handling
++       */
++
++      /*
++       *    The case of both inputs quiet NaNs
++       */
++      case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
++              return x;
++
++      /*
++       *    The cases of exactly one input quiet NaN (numbers
++       *    are here preferred as returned values to NaNs)
++       */
+       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 x;
+-      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):
+@@ -147,14 +159,26 @@ union ieee754dp ieee754dp_fmaxa(union ie
+       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
+               return ieee754dp_nanxcpt(x);
+-      /* numbers are preferred to NaNs */
++      /*
++       * Quiet NaN handling
++       */
++
++      /*
++       *    The case of both inputs quiet NaNs
++       */
++      case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
++              return x;
++
++      /*
++       *    The cases of exactly one input quiet NaN (numbers
++       *    are here preferred as returned values to NaNs)
++       */
+       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 x;
+-      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):
+--- a/arch/mips/math-emu/dp_fmin.c
++++ b/arch/mips/math-emu/dp_fmin.c
+@@ -47,14 +47,26 @@ union ieee754dp ieee754dp_fmin(union iee
+       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
+               return ieee754dp_nanxcpt(x);
+-      /* numbers are preferred to NaNs */
++      /*
++       * Quiet NaN handling
++       */
++
++      /*
++       *    The case of both inputs quiet NaNs
++       */
++      case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
++              return x;
++
++      /*
++       *    The cases of exactly one input quiet NaN (numbers
++       *    are here preferred as returned values to NaNs)
++       */
+       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 x;
+-      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):
+@@ -147,14 +159,26 @@ union ieee754dp ieee754dp_fmina(union ie
+       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
+               return ieee754dp_nanxcpt(x);
+-      /* numbers are preferred to NaNs */
++      /*
++       * Quiet NaN handling
++       */
++
++      /*
++       *    The case of both inputs quiet NaNs
++       */
++      case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
++              return x;
++
++      /*
++       *    The cases of exactly one input quiet NaN (numbers
++       *    are here preferred as returned values to NaNs)
++       */
+       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 x;
+-      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):
+--- a/arch/mips/math-emu/sp_fmax.c
++++ b/arch/mips/math-emu/sp_fmax.c
+@@ -47,14 +47,26 @@ union ieee754sp ieee754sp_fmax(union iee
+       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
+               return ieee754sp_nanxcpt(x);
+-      /* numbers are preferred to NaNs */
++      /*
++       * Quiet NaN handling
++       */
++
++      /*
++       *    The case of both inputs quiet NaNs
++       */
++      case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
++              return x;
++
++      /*
++       *    The cases of exactly one input quiet NaN (numbers
++       *    are here preferred as returned values to NaNs)
++       */
+       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 x;
+-      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):
+@@ -147,14 +159,26 @@ union ieee754sp ieee754sp_fmaxa(union ie
+       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
+               return ieee754sp_nanxcpt(x);
+-      /* numbers are preferred to NaNs */
++      /*
++       * Quiet NaN handling
++       */
++
++      /*
++       *    The case of both inputs quiet NaNs
++       */
++      case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
++              return x;
++
++      /*
++       *    The cases of exactly one input quiet NaN (numbers
++       *    are here preferred as returned values to NaNs)
++       */
+       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 x;
+-      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):
+--- a/arch/mips/math-emu/sp_fmin.c
++++ b/arch/mips/math-emu/sp_fmin.c
+@@ -47,14 +47,26 @@ union ieee754sp ieee754sp_fmin(union iee
+       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
+               return ieee754sp_nanxcpt(x);
+-      /* numbers are preferred to NaNs */
++      /*
++       * Quiet NaN handling
++       */
++
++      /*
++       *    The case of both inputs quiet NaNs
++       */
++      case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
++              return x;
++
++      /*
++       *    The cases of exactly one input quiet NaN (numbers
++       *    are here preferred as returned values to NaNs)
++       */
+       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 x;
+-      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):
+@@ -147,14 +159,26 @@ union ieee754sp ieee754sp_fmina(union ie
+       case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
+               return ieee754sp_nanxcpt(x);
+-      /* numbers are preferred to NaNs */
++      /*
++       * Quiet NaN handling
++       */
++
++      /*
++       *    The case of both inputs quiet NaNs
++       */
++      case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
++              return x;
++
++      /*
++       *    The cases of exactly one input quiet NaN (numbers
++       *    are here preferred as returned values to NaNs)
++       */
+       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 x;
+-      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):
diff --git a/queue-4.9/mips-math-emu-max-min-.-d-s-fix-cases-of-both-inputs-negative.patch b/queue-4.9/mips-math-emu-max-min-.-d-s-fix-cases-of-both-inputs-negative.patch
new file mode 100644 (file)
index 0000000..c5c3d4a
--- /dev/null
@@ -0,0 +1,219 @@
+From aabf5cf02e22ebc4e541adf835910f388b6c3e65 Mon Sep 17 00:00:00 2001
+From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
+Date: Thu, 27 Jul 2017 18:08:50 +0200
+Subject: MIPS: math-emu: <MAX|MIN>.<D|S>: Fix cases of both inputs negative
+
+From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
+
+commit aabf5cf02e22ebc4e541adf835910f388b6c3e65 upstream.
+
+Fix the value returned by <MAX|MIN>.<D|S>, if both inputs are negative
+normal fp numbers. The previous logic did not take into account that
+if both inputs have the same sign, there should be separate treatment
+of the cases when both inputs are negative and when both inputs are
+positive.
+
+A relevant example:
+
+MAX.S fd,fs,ft:
+  If fs contains -5.0, and ft contains -7.0, fd is going to contain
+  -5.0 (without this patch, it used to contain -7.0).
+
+Fixes: a79f5f9ba508 ("MIPS: math-emu: Add support for the MIPS R6 MAX{, A} FPU instruction")
+Fixes: 4e9561b20e2f ("MIPS: math-emu: Add support for the MIPS R6 MIN{, A} 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>
+Reviewed-by: James Hogan <james.hogan@imgtec.com>
+Cc: Bo Hu <bohu@google.com>
+Cc: Douglas Leung <douglas.leung@imgtec.com>
+Cc: Jin Qian <jinqian@google.com>
+Cc: Paul Burton <paul.burton@imgtec.com>
+Cc: Petar Jovanovic <petar.jovanovic@imgtec.com>
+Cc: Raghu Gandham <raghu.gandham@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Cc: linux-kernel@vger.kernel.org
+Patchwork: https://patchwork.linux-mips.org/patch/16882/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/math-emu/dp_fmax.c |   32 ++++++++++++++++++++++++--------
+ arch/mips/math-emu/dp_fmin.c |   32 ++++++++++++++++++++++++--------
+ arch/mips/math-emu/sp_fmax.c |   32 ++++++++++++++++++++++++--------
+ arch/mips/math-emu/sp_fmin.c |   32 ++++++++++++++++++++++++--------
+ 4 files changed, 96 insertions(+), 32 deletions(-)
+
+--- a/arch/mips/math-emu/dp_fmax.c
++++ b/arch/mips/math-emu/dp_fmax.c
+@@ -116,16 +116,32 @@ union ieee754dp ieee754dp_fmax(union iee
+       else if (xs < ys)
+               return x;
+-      /* Compare exponent */
+-      if (xe > ye)
+-              return x;
+-      else if (xe < ye)
+-              return y;
++      /* Signs of inputs are equal, let's compare exponents */
++      if (xs == 0) {
++              /* Inputs are both positive */
++              if (xe > ye)
++                      return x;
++              else if (xe < ye)
++                      return y;
++      } else {
++              /* Inputs are both negative */
++              if (xe > ye)
++                      return y;
++              else if (xe < ye)
++                      return x;
++      }
+-      /* Compare mantissa */
++      /* Signs and exponents of inputs are equal, let's compare mantissas */
++      if (xs == 0) {
++              /* Inputs are both positive, with equal signs and exponents */
++              if (xm <= ym)
++                      return y;
++              return x;
++      }
++      /* Inputs are both negative, with equal signs and exponents */
+       if (xm <= ym)
+-              return y;
+-      return x;
++              return x;
++      return y;
+ }
+ union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y)
+--- a/arch/mips/math-emu/dp_fmin.c
++++ b/arch/mips/math-emu/dp_fmin.c
+@@ -116,16 +116,32 @@ union ieee754dp ieee754dp_fmin(union iee
+       else if (xs < ys)
+               return y;
+-      /* Compare exponent */
+-      if (xe > ye)
+-              return y;
+-      else if (xe < ye)
+-              return x;
++      /* Signs of inputs are the same, let's compare exponents */
++      if (xs == 0) {
++              /* Inputs are both positive */
++              if (xe > ye)
++                      return y;
++              else if (xe < ye)
++                      return x;
++      } else {
++              /* Inputs are both negative */
++              if (xe > ye)
++                      return x;
++              else if (xe < ye)
++                      return y;
++      }
+-      /* Compare mantissa */
++      /* Signs and exponents of inputs are equal, let's compare mantissas */
++      if (xs == 0) {
++              /* Inputs are both positive, with equal signs and exponents */
++              if (xm <= ym)
++                      return x;
++              return y;
++      }
++      /* Inputs are both negative, with equal signs and exponents */
+       if (xm <= ym)
+-              return x;
+-      return y;
++              return y;
++      return x;
+ }
+ union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y)
+--- a/arch/mips/math-emu/sp_fmax.c
++++ b/arch/mips/math-emu/sp_fmax.c
+@@ -116,16 +116,32 @@ union ieee754sp ieee754sp_fmax(union iee
+       else if (xs < ys)
+               return x;
+-      /* Compare exponent */
+-      if (xe > ye)
+-              return x;
+-      else if (xe < ye)
+-              return y;
++      /* Signs of inputs are equal, let's compare exponents */
++      if (xs == 0) {
++              /* Inputs are both positive */
++              if (xe > ye)
++                      return x;
++              else if (xe < ye)
++                      return y;
++      } else {
++              /* Inputs are both negative */
++              if (xe > ye)
++                      return y;
++              else if (xe < ye)
++                      return x;
++      }
+-      /* Compare mantissa */
++      /* Signs and exponents of inputs are equal, let's compare mantissas */
++      if (xs == 0) {
++              /* Inputs are both positive, with equal signs and exponents */
++              if (xm <= ym)
++                      return y;
++              return x;
++      }
++      /* Inputs are both negative, with equal signs and exponents */
+       if (xm <= ym)
+-              return y;
+-      return x;
++              return x;
++      return y;
+ }
+ union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y)
+--- a/arch/mips/math-emu/sp_fmin.c
++++ b/arch/mips/math-emu/sp_fmin.c
+@@ -116,16 +116,32 @@ union ieee754sp ieee754sp_fmin(union iee
+       else if (xs < ys)
+               return y;
+-      /* Compare exponent */
+-      if (xe > ye)
+-              return y;
+-      else if (xe < ye)
+-              return x;
++      /* Signs of inputs are the same, let's compare exponents */
++      if (xs == 0) {
++              /* Inputs are both positive */
++              if (xe > ye)
++                      return y;
++              else if (xe < ye)
++                      return x;
++      } else {
++              /* Inputs are both negative */
++              if (xe > ye)
++                      return x;
++              else if (xe < ye)
++                      return y;
++      }
+-      /* Compare mantissa */
++      /* Signs and exponents of inputs are equal, let's compare mantissas */
++      if (xs == 0) {
++              /* Inputs are both positive, with equal signs and exponents */
++              if (xm <= ym)
++                      return x;
++              return y;
++      }
++      /* Inputs are both negative, with equal signs and exponents */
+       if (xm <= ym)
+-              return x;
+-      return y;
++              return y;
++      return x;
+ }
+ union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y)
diff --git a/queue-4.9/mips-math-emu-maxa-mina-.-d-s-fix-cases-of-both-infinite-inputs.patch b/queue-4.9/mips-math-emu-maxa-mina-.-d-s-fix-cases-of-both-infinite-inputs.patch
new file mode 100644 (file)
index 0000000..6d0b011
--- /dev/null
@@ -0,0 +1,133 @@
+From 3444c4eb534c20e44f0d6670b34263efaf8b531f Mon Sep 17 00:00:00 2001
+From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
+Date: Thu, 27 Jul 2017 18:08:52 +0200
+Subject: MIPS: math-emu: <MAXA|MINA>.<D|S>: Fix cases of both infinite inputs
+
+From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
+
+commit 3444c4eb534c20e44f0d6670b34263efaf8b531f upstream.
+
+Fix the value returned by <MAXA|MINA>.<D|S> fd,fs,ft, if both inputs
+are infinite. The previous implementation returned always the value
+contained in ft in such cases. The correct behavior is specified
+in Mips instruction set manual and is as follows:
+
+    fs    ft        MAXA     MINA
+  ---------------------------------
+    inf   inf        inf      inf
+    inf  -inf        inf     -inf
+   -inf   inf        inf     -inf
+   -inf  -inf       -inf     -inf
+
+A relevant example:
+
+MAXA.S fd,fs,ft:
+  If fs contains +inf, and ft contains -inf, fd is going to contain
+  +inf (without this patch, it used to contain -inf).
+
+Fixes: a79f5f9ba508 ("MIPS: math-emu: Add support for the MIPS R6 MAX{, A} FPU instruction")
+Fixes: 4e9561b20e2f ("MIPS: math-emu: Add support for the MIPS R6 MIN{, A} 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>
+Reviewed-by: James Hogan <james.hogan@imgtec.com>
+Cc: Bo Hu <bohu@google.com>
+Cc: Douglas Leung <douglas.leung@imgtec.com>
+Cc: Jin Qian <jinqian@google.com>
+Cc: Paul Burton <paul.burton@imgtec.com>
+Cc: Petar Jovanovic <petar.jovanovic@imgtec.com>
+Cc: Raghu Gandham <raghu.gandham@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Cc: linux-kernel@vger.kernel.org
+Patchwork: https://patchwork.linux-mips.org/patch/16884/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/math-emu/dp_fmax.c |    4 +++-
+ arch/mips/math-emu/dp_fmin.c |    4 +++-
+ arch/mips/math-emu/sp_fmax.c |    4 +++-
+ arch/mips/math-emu/sp_fmin.c |    4 +++-
+ 4 files changed, 12 insertions(+), 4 deletions(-)
+
+--- a/arch/mips/math-emu/dp_fmax.c
++++ b/arch/mips/math-emu/dp_fmax.c
+@@ -202,6 +202,9 @@ union ieee754dp ieee754dp_fmaxa(union ie
+       /*
+        * Infinity and zero handling
+        */
++      case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
++              return ieee754dp_inf(xs & ys);
++
+       case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
+       case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
+       case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
+@@ -209,7 +212,6 @@ union ieee754dp ieee754dp_fmaxa(union ie
+       case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
+               return x;
+-      case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+       case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
+       case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
+       case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
+--- a/arch/mips/math-emu/dp_fmin.c
++++ b/arch/mips/math-emu/dp_fmin.c
+@@ -202,6 +202,9 @@ union ieee754dp ieee754dp_fmina(union ie
+       /*
+        * Infinity and zero handling
+        */
++      case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
++              return ieee754dp_inf(xs | ys);
++
+       case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
+       case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
+       case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
+@@ -209,7 +212,6 @@ union ieee754dp ieee754dp_fmina(union ie
+       case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
+               return x;
+-      case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+       case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
+       case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
+       case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
+--- a/arch/mips/math-emu/sp_fmax.c
++++ b/arch/mips/math-emu/sp_fmax.c
+@@ -202,6 +202,9 @@ union ieee754sp ieee754sp_fmaxa(union ie
+       /*
+        * Infinity and zero handling
+        */
++      case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
++              return ieee754sp_inf(xs & ys);
++
+       case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
+       case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
+       case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
+@@ -209,7 +212,6 @@ union ieee754sp ieee754sp_fmaxa(union ie
+       case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
+               return x;
+-      case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+       case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
+       case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
+       case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
+--- a/arch/mips/math-emu/sp_fmin.c
++++ b/arch/mips/math-emu/sp_fmin.c
+@@ -202,6 +202,9 @@ union ieee754sp ieee754sp_fmina(union ie
+       /*
+        * Infinity and zero handling
+        */
++      case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
++              return ieee754sp_inf(xs | ys);
++
+       case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
+       case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
+       case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
+@@ -209,7 +212,6 @@ union ieee754sp ieee754sp_fmina(union ie
+       case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
+               return x;
+-      case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
+       case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
+       case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
+       case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
diff --git a/queue-4.9/mips-math-emu-maxa-mina-.-d-s-fix-cases-of-input-values-with-opposite-signs.patch b/queue-4.9/mips-math-emu-maxa-mina-.-d-s-fix-cases-of-input-values-with-opposite-signs.patch
new file mode 100644 (file)
index 0000000..026e1ec
--- /dev/null
@@ -0,0 +1,106 @@
+From 1a41b3b441508ae63b1a9ec699ec94065739eb60 Mon Sep 17 00:00:00 2001
+From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
+Date: Thu, 27 Jul 2017 18:08:51 +0200
+Subject: MIPS: math-emu: <MAXA|MINA>.<D|S>: Fix cases of input values with opposite signs
+
+From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
+
+commit 1a41b3b441508ae63b1a9ec699ec94065739eb60 upstream.
+
+Fix the value returned by <MAXA|MINA>.<D|S>, if the inputs are normal
+fp numbers of the same absolute value, but opposite signs.
+
+A relevant example:
+
+MAXA.S fd,fs,ft:
+  If fs contains -3.0, and ft contains +3.0, fd is going to contain
+  +3.0 (without this patch, it used to contain -3.0).
+
+Fixes: a79f5f9ba508 ("MIPS: math-emu: Add support for the MIPS R6 MAX{, A} FPU instruction")
+Fixes: 4e9561b20e2f ("MIPS: math-emu: Add support for the MIPS R6 MIN{, A} 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>
+Reviewed-by: James Hogan <james.hogan@imgtec.com>
+Cc: Bo Hu <bohu@google.com>
+Cc: Douglas Leung <douglas.leung@imgtec.com>
+Cc: Jin Qian <jinqian@google.com>
+Cc: Paul Burton <paul.burton@imgtec.com>
+Cc: Petar Jovanovic <petar.jovanovic@imgtec.com>
+Cc: Raghu Gandham <raghu.gandham@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Cc: linux-kernel@vger.kernel.org
+Patchwork: https://patchwork.linux-mips.org/patch/16883/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/math-emu/dp_fmax.c |    8 ++++++--
+ arch/mips/math-emu/dp_fmin.c |    6 +++++-
+ arch/mips/math-emu/sp_fmax.c |    8 ++++++--
+ arch/mips/math-emu/sp_fmin.c |    6 +++++-
+ 4 files changed, 22 insertions(+), 6 deletions(-)
+
+--- a/arch/mips/math-emu/dp_fmax.c
++++ b/arch/mips/math-emu/dp_fmax.c
+@@ -243,7 +243,11 @@ union ieee754dp ieee754dp_fmaxa(union ie
+               return y;
+       /* Compare mantissa */
+-      if (xm <= ym)
++      if (xm < ym)
+               return y;
+-      return x;
++      else if (xm > ym)
++              return x;
++      else if (xs == 0)
++              return x;
++      return y;
+ }
+--- a/arch/mips/math-emu/dp_fmin.c
++++ b/arch/mips/math-emu/dp_fmin.c
+@@ -243,7 +243,11 @@ union ieee754dp ieee754dp_fmina(union ie
+               return x;
+       /* Compare mantissa */
+-      if (xm <= ym)
++      if (xm < ym)
++              return x;
++      else if (xm > ym)
++              return y;
++      else if (xs == 1)
+               return x;
+       return y;
+ }
+--- a/arch/mips/math-emu/sp_fmax.c
++++ b/arch/mips/math-emu/sp_fmax.c
+@@ -243,7 +243,11 @@ union ieee754sp ieee754sp_fmaxa(union ie
+               return y;
+       /* Compare mantissa */
+-      if (xm <= ym)
++      if (xm < ym)
+               return y;
+-      return x;
++      else if (xm > ym)
++              return x;
++      else if (xs == 0)
++              return x;
++      return y;
+ }
+--- a/arch/mips/math-emu/sp_fmin.c
++++ b/arch/mips/math-emu/sp_fmin.c
+@@ -243,7 +243,11 @@ union ieee754sp ieee754sp_fmina(union ie
+               return x;
+       /* Compare mantissa */
+-      if (xm <= ym)
++      if (xm < ym)
++              return x;
++      else if (xm > ym)
++              return y;
++      else if (xs == 1)
+               return x;
+       return y;
+ }
diff --git a/queue-4.9/mips-math-emu-mina.-d-s-fix-some-cases-of-infinity-and-zero-inputs.patch b/queue-4.9/mips-math-emu-mina.-d-s-fix-some-cases-of-infinity-and-zero-inputs.patch
new file mode 100644 (file)
index 0000000..02bfdd5
--- /dev/null
@@ -0,0 +1,88 @@
+From 304bfe473e70523e591fb1c9223289d355e0bdcb Mon Sep 17 00:00:00 2001
+From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
+Date: Thu, 27 Jul 2017 18:08:53 +0200
+Subject: MIPS: math-emu: MINA.<D|S>: Fix some cases of infinity and zero inputs
+
+From: Aleksandar Markovic <aleksandar.markovic@imgtec.com>
+
+commit 304bfe473e70523e591fb1c9223289d355e0bdcb upstream.
+
+Fix following special cases for MINA>.<D|S>:
+
+  - if one of the inputs is zero, and the other is subnormal, normal,
+    or infinity, the  value of the former should be returned (that is,
+    a zero).
+  - if one of the inputs is infinity, and the other input is normal,
+    or subnormal, the value of the latter should be returned.
+
+The previous implementation's logic for such cases was incorrect - it
+appears as if it implements MAXA, and not MINA instruction.
+
+A relevant example:
+
+MINA.S fd,fs,ft:
+  If fs contains 100.0, and ft contains 0.0, fd is going to contain
+  0.0 (without this patch, it used to contain 100.0).
+
+Fixes: a79f5f9ba508 ("MIPS: math-emu: Add support for the MIPS R6 MAX{, A} FPU instruction")
+Fixes: 4e9561b20e2f ("MIPS: math-emu: Add support for the MIPS R6 MIN{, A} 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>
+Reviewed-by: James Hogan <james.hogan@imgtec.com>
+Cc: Bo Hu <bohu@google.com>
+Cc: Douglas Leung <douglas.leung@imgtec.com>
+Cc: Jin Qian <jinqian@google.com>
+Cc: Paul Burton <paul.burton@imgtec.com>
+Cc: Petar Jovanovic <petar.jovanovic@imgtec.com>
+Cc: Raghu Gandham <raghu.gandham@imgtec.com>
+Cc: linux-mips@linux-mips.org
+Cc: linux-kernel@vger.kernel.org
+Patchwork: https://patchwork.linux-mips.org/patch/16885/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/math-emu/dp_fmin.c |    4 ++--
+ arch/mips/math-emu/sp_fmin.c |    4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/arch/mips/math-emu/dp_fmin.c
++++ b/arch/mips/math-emu/dp_fmin.c
+@@ -210,14 +210,14 @@ union ieee754dp ieee754dp_fmina(union ie
+       case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
+       case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
+       case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
+-              return x;
++              return y;
+       case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
+       case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
+       case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
+       case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
+       case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
+-              return y;
++              return x;
+       case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
+               return ieee754dp_zero(xs | ys);
+--- a/arch/mips/math-emu/sp_fmin.c
++++ b/arch/mips/math-emu/sp_fmin.c
+@@ -210,14 +210,14 @@ union ieee754sp ieee754sp_fmina(union ie
+       case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
+       case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
+       case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
+-              return x;
++              return y;
+       case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
+       case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
+       case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
+       case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
+       case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
+-              return y;
++              return x;
+       case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
+               return ieee754sp_zero(xs | ys);
index 2fa533bb5a7e4b39ec1f2efc4749b5b3316f8e53..5b1881ce4b2d2235ee28ec23f22323da82271476 100644 (file)
@@ -9,3 +9,17 @@ tty-improve-tty_insert_flip_char-fast-path.patch
 tty-improve-tty_insert_flip_char-slow-path.patch
 tty-fix-__tty_insert_flip_char-regression.patch
 pinctrl-amd-save-pin-registers-over-suspend-resume.patch
+input-i8042-add-gigabyte-p57-to-the-keyboard-reset-table.patch
+mips-math-emu-max-maxa-min-mina-.-d-s-fix-quiet-nan-propagation.patch
+mips-math-emu-max-maxa-min-mina-.-d-s-fix-cases-of-both-inputs-zero.patch
+mips-math-emu-max-min-.-d-s-fix-cases-of-both-inputs-negative.patch
+mips-math-emu-maxa-mina-.-d-s-fix-cases-of-input-values-with-opposite-signs.patch
+mips-math-emu-maxa-mina-.-d-s-fix-cases-of-both-infinite-inputs.patch
+mips-math-emu-mina.-d-s-fix-some-cases-of-infinity-and-zero-inputs.patch
+mips-math-emu-handle-zero-accumulator-case-in-maddf-and-msubf-separately.patch
+mips-math-emu-maddf-msubf-.-d-s-fix-nan-propagation.patch
+mips-math-emu-maddf-msubf-.-d-s-fix-some-cases-of-infinite-inputs.patch
+mips-math-emu-maddf-msubf-.-d-s-fix-some-cases-of-zero-inputs.patch
+mips-math-emu-maddf-msubf-.-d-s-clean-up-maddf_flags-enumeration.patch
+mips-math-emu-maddf-msubf-.s-fix-accuracy-32-bit-case.patch
+mips-math-emu-maddf-msubf-.d-fix-accuracy-64-bit-case.patch