In next commit, we update references for failing tests.
One test, test_mips64r6_srav, has an output that is not reproducible
on my host. After checking, it's coming from UNPREDICTABLE case
described by mips64 reference manual.

```
Format: SRAV rd, rt, rs MIPS32
Description: GPR[rd] = GPR[rt] >> GPR[rs] (arithmetic)
The contents of the low-order 32-bit word of GPR rt are shifted right,
duplicating the sign-bit (bit 31) in the emptied
bits; the word result is sign-extended and placed in GPR rd. The
bit-shift amount is specified by the low-order 5 bits
Restrictions:
On 64-bit processors, if GPR rt does not contain a sign-extended 32-bit value 
(bits 63..31 equal), then the result of the
operation is UNPREDICTABLE.
```

Current implementation takes advantage of restriction above and does not
perform sign extension on lower part.

Given this definition: srav(x,y) ((int64_t)((int32_t)(x)>>(y&0b11111)))
srav(0xaaaaaaaaaaaaaaaa, 0xffffffffffffffff) = 0xffffffffffffffff
With qemu-mips64, this instruction returns 0xffffffff55555555 instead.

While this is not wrong following the spec, it can be surprising. To
have a more predictable behavior, always perform sign extension on lower
part. This will give us the advantage of having a test output that can
be checked on any host.

Signed-off-by: Pierrick Bouvier <[email protected]>
---
 target/mips/tcg/translate.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index e3467d15251..936f8c4eddc 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -2853,6 +2853,7 @@ static void gen_shift(DisasContext *ctx, uint32_t opc,
         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
         break;
     case OPC_SRAV:
+        tcg_gen_ext32s_tl(t1, t1);
         tcg_gen_andi_tl(t0, t0, 0x1f);
         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
         break;
-- 
2.43.0


Reply via email to