target/mips: Make the results of MOD_<U|S>.<B|H|W|D> the same as on hardware

MSA instructions MOD_<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 255, 256).

[1] 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>
Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Message-Id: <1554207110-9113-3-git-send-email-mateja.marjanovic@rt-rk.com>
This commit is contained in:
Mateja Marjanovic 2019-04-02 14:11:50 +02:00 committed by Aleksandar Markovic
parent d2a40a5f69
commit cf122bf8d2

View File

@ -657,14 +657,14 @@ static inline int64_t msa_mod_s_df(uint32_t df, int64_t arg1, int64_t arg2)
if (arg1 == DF_MIN_INT(df) && arg2 == -1) { if (arg1 == DF_MIN_INT(df) && arg2 == -1) {
return 0; return 0;
} }
return arg2 ? arg1 % arg2 : 0; return arg2 ? arg1 % arg2 : arg1;
} }
static inline int64_t msa_mod_u_df(uint32_t df, int64_t arg1, int64_t arg2) static inline int64_t msa_mod_u_df(uint32_t df, int64_t arg1, int64_t arg2)
{ {
uint64_t u_arg1 = UNSIGNED(arg1, df); uint64_t u_arg1 = UNSIGNED(arg1, df);
uint64_t u_arg2 = UNSIGNED(arg2, df); uint64_t u_arg2 = UNSIGNED(arg2, df);
return u_arg2 ? u_arg1 % u_arg2 : 0; return u_arg2 ? u_arg1 % u_arg2 : u_arg1;
} }
#define SIGNED_EVEN(a, df) \ #define SIGNED_EVEN(a, df) \