target/ppc: Fix rlwinm on ppc64
rlwinm cannot just AND with Mask if shift value is zero on ppc64 when Mask Begin is greater than Mask End and high bits are set to 1. Note that PowerISA 3.0B says that for `rlwinm' ROTL32 is used, and ROTL32 is defined (in 3.3.14) so that rotated value should have two copies of lower word of the source value. This seems to be another incarnation of the fix from820724d170
("target-ppc: Fix rlwimi, rlwinm, rlwnm again"), except I leave optimization when Mask value is less than 32 bits. Fixes:7b4d326f47
("target-ppc: Use the new deposit and extract ops") Cc: qemu-stable@nongnu.org Signed-off-by: Vitaly Chikunov <vt@altlinux.org> Message-Id: <20200309204557.14836-1-vt@altlinux.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
parent
52d3403d1e
commit
94f040aaec
@ -1938,15 +1938,17 @@ static void gen_rlwinm(DisasContext *ctx)
|
||||
me += 32;
|
||||
#endif
|
||||
mask = MASK(mb, me);
|
||||
if (sh == 0) {
|
||||
tcg_gen_andi_tl(t_ra, t_rs, mask);
|
||||
} else if (mask <= 0xffffffffu) {
|
||||
TCGv_i32 t0 = tcg_temp_new_i32();
|
||||
tcg_gen_trunc_tl_i32(t0, t_rs);
|
||||
tcg_gen_rotli_i32(t0, t0, sh);
|
||||
tcg_gen_andi_i32(t0, t0, mask);
|
||||
tcg_gen_extu_i32_tl(t_ra, t0);
|
||||
tcg_temp_free_i32(t0);
|
||||
if (mask <= 0xffffffffu) {
|
||||
if (sh == 0) {
|
||||
tcg_gen_andi_tl(t_ra, t_rs, mask);
|
||||
} else {
|
||||
TCGv_i32 t0 = tcg_temp_new_i32();
|
||||
tcg_gen_trunc_tl_i32(t0, t_rs);
|
||||
tcg_gen_rotli_i32(t0, t0, sh);
|
||||
tcg_gen_andi_i32(t0, t0, mask);
|
||||
tcg_gen_extu_i32_tl(t_ra, t0);
|
||||
tcg_temp_free_i32(t0);
|
||||
}
|
||||
} else {
|
||||
#if defined(TARGET_PPC64)
|
||||
tcg_gen_deposit_i64(t_ra, t_rs, t_rs, 32, 32);
|
||||
|
Loading…
Reference in New Issue
Block a user