|
From: | Mateja Marjanovic |
Subject: | Re: [Qemu-devel] [PATCH v2 1/2] target/mips: Make the results of DIV_<U|S>.<B|H|W|D> the same as on hardware |
Date: | Tue, 2 Apr 2019 17:26:56 +0200 |
User-agent: | Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.6.1 |
On 2.4.19. 17:08, Philippe Mathieu-Daudé wrote:
Hi Mateja, On 4/2/19 2:11 PM, Mateja Marjanovic wrote:From: Mateja Marjanovic <address@hidden> MSA instructions DIV_<U|S>.<B|H|W|D> when dividing by zero, didn't return the same value when executed on a referent hardware (FPGA MIPS 64 r6, little endian) and when executed on QEMU, which is not a real bug, because the result when dividing by zero is UNPREDICTABLE [1] (page 141, 142).I'm surprised by the arch, I'd have expected a MSA floating point exception instead of UNPREDICTABLE.
Our architecture documents do not list any exceptions related to division by zero, for instructions DIV_<U|S>.<B|H|W|D> and MOD_<U|S>.<B|H|W|D>. The only exceptions that are mentioned are:Reserved Instruction Exception, MSA Disabled Exception. [1] (page 141, 142, 254, 255).
So here we decide to follow the FPGA model behavior rather than the architecture... If the community agree, my only request is to add a comment in the code that this is the "FPGA MIPS 64 r6" behavior (else while looking at this code later I'd be tempted to revert to a 0 return value instead of -1/1).[1] MIPS Architecture for Programmers Volume IV-j: The MIPS64 SIMD Architecture Module, Revision 1.12 Signed-off-by: Mateja Marjanovic <address@hidden> --- target/mips/msa_helper.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c index 655148d..8c77f12 100644 --- a/target/mips/msa_helper.c +++ b/target/mips/msa_helper.c @@ -641,14 +641,15 @@ static inline int64_t msa_div_s_df(uint32_t df, int64_t arg1, int64_t arg2) if (arg1 == DF_MIN_INT(df) && arg2 == -1) { return DF_MIN_INT(df); } - return arg2 ? arg1 / arg2 : 0; + return arg2 ? arg1 / arg2 + : arg1 >= 0 ? -1 : 1; }static inline int64_t msa_div_u_df(uint32_t df, int64_t arg1, int64_t arg2){ uint64_t u_arg1 = UNSIGNED(arg1, df); uint64_t u_arg2 = UNSIGNED(arg2, df); - return u_arg2 ? u_arg1 / u_arg2 : 0; + return arg2 ? u_arg1 / u_arg2 : -1; }static inline int64_t msa_mod_s_df(uint32_t df, int64_t arg1, int64_t arg2)
Thanks, Mateja
[Prev in Thread] | Current Thread | [Next in Thread] |