summary refs log tree commit diff stats
path: root/fpu/softfloat.c
diff options
context:
space:
mode:
authorAlex Bennée <alex.bennee@linaro.org>2018-04-16 14:54:42 +0100
committerPeter Maydell <peter.maydell@linaro.org>2018-04-16 18:40:48 +0100
commit9cb4e398c2f95c1e837fe9c570e124a55259f725 (patch)
tree774ac24416cac3cfa0933ac7594094d68598ae56 /fpu/softfloat.c
parent2a6b5372d7bad038fe27f9c60e85ef5c8a15e311 (diff)
downloadfocaccia-qemu-9cb4e398c2f95c1e837fe9c570e124a55259f725.tar.gz
focaccia-qemu-9cb4e398c2f95c1e837fe9c570e124a55259f725.zip
fpu/softfloat: check for Inf / x or 0 / x before /0
The re-factoring of div_floats changed the order of checking meaning
an operation like -inf/0 erroneously raises the divbyzero flag.
IEEE-754 (2008) specifies this should only occur for operations on
finite operands.

We fix this by moving the check on the dividend being Inf/0 to before
the divisor is zero check.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-id: 20180416135442.30606-1-alex.bennee@linaro.org
Cc: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Reviewed-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Tested-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'fpu/softfloat.c')
-rw-r--r--fpu/softfloat.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index fb8663f59e..d90d79d777 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1146,6 +1146,11 @@ static FloatParts div_floats(FloatParts a, FloatParts b, float_status *s)
         a.cls = float_class_dnan;
         return a;
     }
+    /* Inf / x or 0 / x */
+    if (a.cls == float_class_inf || a.cls == float_class_zero) {
+        a.sign = sign;
+        return a;
+    }
     /* Div 0 => Inf */
     if (b.cls == float_class_zero) {
         s->float_exception_flags |= float_flag_divbyzero;
@@ -1153,11 +1158,6 @@ static FloatParts div_floats(FloatParts a, FloatParts b, float_status *s)
         a.sign = sign;
         return a;
     }
-    /* Inf / x or 0 / x */
-    if (a.cls == float_class_inf || a.cls == float_class_zero) {
-        a.sign = sign;
-        return a;
-    }
     /* Div by Inf */
     if (b.cls == float_class_inf) {
         a.cls = float_class_zero;