aboutsummaryrefslogtreecommitdiff
path: root/target-ppc
diff options
context:
space:
mode:
authorTom Musta <tommusta@gmail.com>2014-08-12 08:45:07 -0500
committerAlexander Graf <agraf@suse.de>2014-09-08 12:50:50 +0200
commitf11ebbf8d4308795129bc6651cf701b61b812abf (patch)
treec637d391b3dd5fcbf7ea94bcea033303e3b0d512 /target-ppc
parent6ea7b35c0294b1cc462e3225c4672de31300ed79 (diff)
target-ppc: Bug Fix: mullwo
On 64-bit implementations, the mullwo result is the 64 bit product of the signed 32 bit operands. Fix the implementation to properly deposit the upper 32 bits into the target register. Example: R3 0407DED115077586 R4 53778DF3CA992E09 mullwo 3,3,4 R3 expected : FB9D02730D7735B6 R3 actual : 000000000D7735B6 (without this patch) 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.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index fab4f01d97..dc80b02318 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -1140,11 +1140,20 @@ static void gen_mullwo(DisasContext *ctx)
{
TCGv_i32 t0 = tcg_temp_new_i32();
TCGv_i32 t1 = tcg_temp_new_i32();
+#if defined(TARGET_PPC64)
+ TCGv_i64 t2 = tcg_temp_new_i64();
+#endif
tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);
tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);
tcg_gen_muls2_i32(t0, t1, t0, t1);
tcg_gen_ext_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);
+#if defined(TARGET_PPC64)
+ tcg_gen_ext_i32_tl(t2, t1);
+ tcg_gen_deposit_i64(cpu_gpr[rD(ctx->opcode)],
+ cpu_gpr[rD(ctx->opcode)], t2, 32, 32);
+ tcg_temp_free(t2);
+#endif
tcg_gen_sari_i32(t0, t0, 31);
tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t1);