diff options
author | Mateja Marjanovic <Mateja.Marjanovic@rt-rk.com> | 2019-03-19 16:21:56 +0100 |
---|---|---|
committer | Alex Bennée <alex.bennee@linaro.org> | 2019-03-25 10:34:48 +0000 |
commit | 7ca96e1a9cadc32af7df73dcf4438b08667d07a6 (patch) | |
tree | f99f861a9a7433830f66cec1f8a4e3180cf008d0 | |
parent | aec2927dda69f35bab188a9bc577861e62044001 (diff) |
target/mips: Fix minor bug in FPU
Wrong type of NaN was generated for IEEE 754-2008 by MADDF.<D|S> and
MSUBF.<D|S> instructions when the arguments were (Inf, Zero, NaN) or
(Zero, Inf, NaN).
The if-else statement establishes if the system conforms to IEEE
754-1985 or IEEE 754-2008, and defines different behaviors depending
on that. In case of IEEE 754-2008, in mentioned cases of inputs,
<MADDF|MSUBF>.<D|S> returns the input value 'c' [2] (page 53) and
raises floating point exception 'Invalid Operation' [1] (pages 349,
350).
These scenarios were tested and the results in QEMU emulation match
the results obtained on the machine that has a MIPS64R6 CPU.
[1] MIPS Architecture for Programmers Volume II-a: The MIPS64
Instruction Set Reference Manual, Revision 6.06
[2] MIPS Architecture for Programmers Volume IV-j: The MIPS64
SIMD Architecture Module, Revision 1.12
Signed-off-by: Mateja Marjanovic <mateja.marjanovic@rt-rk.com>
Message-Id: <1553008916-15274-2-git-send-email-mateja.marjanovic@rt-rk.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
[AJB: fixed up commit message]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
-rw-r--r-- | fpu/softfloat-specialize.h | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h index 16c0bcb6fa..7b8895726c 100644 --- a/fpu/softfloat-specialize.h +++ b/fpu/softfloat-specialize.h @@ -495,15 +495,15 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls, return 1; } #elif defined(TARGET_MIPS) - /* For MIPS, the (inf,zero,qnan) case sets InvalidOp and returns - * the default NaN - */ - if (infzero) { - float_raise(float_flag_invalid, status); - return 3; - } - if (snan_bit_is_one(status)) { + /* + * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan) + * case sets InvalidOp and returns the default NaN + */ + if (infzero) { + float_raise(float_flag_invalid, status); + return 3; + } /* Prefer sNaN over qNaN, in the a, b, c order. */ if (is_snan(a_cls)) { return 0; @@ -519,6 +519,14 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls, return 2; } } else { + /* + * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan) + * case sets InvalidOp and returns the input value 'c' + */ + if (infzero) { + float_raise(float_flag_invalid, status); + return 2; + } /* Prefer sNaN over qNaN, in the c, a, b order. */ if (is_snan(c_cls)) { return 2; |