MIPS: math-emu: <MAX|MIN>.<D|S>: Fix cases of both inputs negative
authorAleksandar Markovic <aleksandar.markovic@imgtec.com>
Thu, 27 Jul 2017 16:08:50 +0000 (18:08 +0200)
committerRalf Baechle <ralf@linux-mips.org>
Tue, 29 Aug 2017 13:21:55 +0000 (15:21 +0200)
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: <stable@vger.kernel.org> # 4.3+
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>
arch/mips/math-emu/dp_fmax.c
arch/mips/math-emu/dp_fmin.c
arch/mips/math-emu/sp_fmax.c
arch/mips/math-emu/sp_fmin.c

index 31f091a7819bbbf9b080ad6c8c3f343eb31b50c0..0b53c786110161203b85e5abedd6cc39937fc529 100644 (file)
@@ -116,16 +116,32 @@ union ieee754dp ieee754dp_fmax(union ieee754dp x, union ieee754dp y)
        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)
index e607d55208ad0fd2b94311b586a47590c7c6ff7d..099e6bd553532490fff63d76513a36794376ee9a 100644 (file)
@@ -116,16 +116,32 @@ union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y)
        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)
index 3ca5b204e9d01be6ce079593a98cb859ccf9515c..7efa7729bd851852882f5a9d57bb615532bf4829 100644 (file)
@@ -116,16 +116,32 @@ union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y)
        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)
index c982647df39a20f5bfacf00dd8a55389d1440bea..e2c554359f7b8d8d2849bef4e6be52dfe9dea656 100644 (file)
@@ -116,16 +116,32 @@ union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y)
        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)