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.

Backports commit 9cb4e398c2f95c1e837fe9c570e124a55259f725 from qemu
This commit is contained in:
Alex Bennée 2018-04-18 09:19:15 -04:00 committed by Lioncash
parent fe353764e9
commit af6a0b7c14
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7

View file

@ -1146,6 +1146,11 @@ static FloatParts div_floats(FloatParts a, FloatParts b, float_status *s)
a.cls = float_class_dnan; a.cls = float_class_dnan;
return a; 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 */ /* Div 0 => Inf */
if (b.cls == float_class_zero) { if (b.cls == float_class_zero) {
s->float_exception_flags |= float_flag_divbyzero; 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; a.sign = sign;
return a; 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 */ /* Div by Inf */
if (b.cls == float_class_inf) { if (b.cls == float_class_inf) {
a.cls = float_class_zero; a.cls = float_class_zero;