target-mips: Sign-extend the result of LWR
authorRichard Sandiford <rdsandiford@googlemail.com>
Sun, 20 Jan 2013 19:30:54 +0000 (19:30 +0000)
committerAurelien Jarno <aurelien@aurel32.net>
Thu, 31 Jan 2013 22:40:52 +0000 (23:40 +0100)
Sign-extend the result of LWR, as is already done for LWL.  This is necessary
in the case where LWR loads the full word (i.e. the address is actually
aligned).  In the other cases, it is implementation defined whether the
upper 32 bits of the result are unchanged or a copy of bit 31.  The latter
seems easier to implement.

Previously the code used:

    (oldval & (0xfffffffe << (31 - bitshift))) | (newval >> bitshift)

which zeroed the upper bits of the register, losing any previous sign
extension in the unaligned cases.

Signed-off-by: Richard Sandiford <rdsandiford@googlemail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
target-mips/translate.c

index 8520d285193f493f7d359f9bbee5d0b7c7632cad..e58d916b040faa50d689b663c48dd4b2388436a0 100644 (file)
@@ -1745,6 +1745,7 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
         tcg_temp_free(t2);
         tcg_gen_or_tl(t0, t0, t1);
         tcg_temp_free(t1);
+        tcg_gen_ext32s_tl(t0, t0);
         gen_store_gpr(t0, rt);
         opn = "lwr";
         break;