target-ppc: Bug Fix: rlwimi
The rlwimi specification includes the ROTL32 operation, which is defined to be a left rotation of two copies of the least significant 32 bits of the source GPR. The current implementation is incorrect on 64-bit implementations in that it rotates a single copy of the least significant 32 bits, padding with zeroes in the most significant bits. Fix the code to properly implement this ROTL32 operation. Also fix the special case of MB=31 and ME=0 to copy the entire contents of the source GPR. Examples: R3 FFFFFFFFFFFFFFF0 rlwimi 3,3,29,14,1 R3 expected : 1FFFFFFE3FFFFFFE R3 actual : 000000003FFFFFFE (without this patch) R3 ED7EB4DD824F0853 rlwimi 3,3,10,31,0 R3 expected : 3C214E09024F0853 R3 actual : 00000000024F0853 (without this patch) Signed-off-by: Tom Musta <tommusta@gmail.com> Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
parent
1c0a150f4b
commit
6ea7b35c02
|
@ -1617,17 +1617,19 @@ static void gen_rlwimi(DisasContext *ctx)
|
||||||
me = ME(ctx->opcode);
|
me = ME(ctx->opcode);
|
||||||
sh = SH(ctx->opcode);
|
sh = SH(ctx->opcode);
|
||||||
if (likely(sh == 0 && mb == 0 && me == 31)) {
|
if (likely(sh == 0 && mb == 0 && me == 31)) {
|
||||||
|
#if defined(TARGET_PPC64)
|
||||||
|
tcg_gen_mov_i64(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
|
||||||
|
#else
|
||||||
tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
|
tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
target_ulong mask;
|
target_ulong mask;
|
||||||
TCGv t1;
|
TCGv t1;
|
||||||
TCGv t0 = tcg_temp_new();
|
TCGv t0 = tcg_temp_new();
|
||||||
#if defined(TARGET_PPC64)
|
#if defined(TARGET_PPC64)
|
||||||
TCGv_i32 t2 = tcg_temp_new_i32();
|
tcg_gen_deposit_i64(t0, cpu_gpr[rS(ctx->opcode)],
|
||||||
tcg_gen_trunc_i64_i32(t2, cpu_gpr[rS(ctx->opcode)]);
|
cpu_gpr[rS(ctx->opcode)], 32, 32);
|
||||||
tcg_gen_rotli_i32(t2, t2, sh);
|
tcg_gen_rotli_i64(t0, t0, sh);
|
||||||
tcg_gen_extu_i32_i64(t0, t2);
|
|
||||||
tcg_temp_free_i32(t2);
|
|
||||||
#else
|
#else
|
||||||
tcg_gen_rotli_i32(t0, cpu_gpr[rS(ctx->opcode)], sh);
|
tcg_gen_rotli_i32(t0, cpu_gpr[rS(ctx->opcode)], sh);
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue