aboutsummaryrefslogtreecommitdiff
path: root/target-ppc
diff options
context:
space:
mode:
authorTom Musta <tommusta@gmail.com>2014-08-12 08:45:03 -0500
committerAlexander Graf <agraf@suse.de>2014-09-08 12:50:49 +0200
commita7f23d0f8bfbe76864a6427c0e21fe794ab9b7ef (patch)
treeea0c224ffcde6644324d901cb3088ea67cb15142 /target-ppc
parent9674a356267ee9cf8230775f88c90c299a4affc9 (diff)
target-ppc: Bug Fix: rlwinm
The rlwinm 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. Example: R3 = F7487D82EC6F75DF rlwinm 3,3,5,12,4 R3 expected : 8DEEBBFD880EBBFD R3 actual : 00000000880EBBFD (without this fix) Signed-off-by: Tom Musta <tommusta@gmail.com> Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'target-ppc')
-rw-r--r--target-ppc/translate.c8
1 files changed, 3 insertions, 5 deletions
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index c07bb01a7a..44a8e1efdc 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -1675,11 +1675,9 @@ static void gen_rlwinm(DisasContext *ctx)
} else {
TCGv t0 = tcg_temp_new();
#if defined(TARGET_PPC64)
- TCGv_i32 t1 = tcg_temp_new_i32();
- tcg_gen_trunc_i64_i32(t1, cpu_gpr[rS(ctx->opcode)]);
- tcg_gen_rotli_i32(t1, t1, sh);
- tcg_gen_extu_i32_i64(t0, t1);
- tcg_temp_free_i32(t1);
+ tcg_gen_deposit_i64(t0, cpu_gpr[rS(ctx->opcode)],
+ cpu_gpr[rS(ctx->opcode)], 32, 32);
+ tcg_gen_rotli_i64(t0, t0, sh);
#else
tcg_gen_rotli_i32(t0, cpu_gpr[rS(ctx->opcode)], sh);
#endif