summaryrefslogtreecommitdiff
path: root/target-arm/translate.c
diff options
context:
space:
mode:
authorbalrog <balrog@c046a42c-6fe2-441c-8c8c-71466251a162>2008-07-19 10:12:22 +0000
committerbalrog <balrog@c046a42c-6fe2-441c-8c8c-71466251a162>2008-07-19 10:12:22 +0000
commit22478e79f2793aa1bc7a5019ae2e48303573e0d5 (patch)
treea736478a7d1cb9670b44dfc9f6015127dc0bbfe4 /target-arm/translate.c
parentf617a9a6bb3b66e93d30f57e966f425e58cef8bc (diff)
downloadqemu-22478e79f2793aa1bc7a5019ae2e48303573e0d5.tar.gz
qemu-22478e79f2793aa1bc7a5019ae2e48303573e0d5.tar.bz2
qemu-22478e79f2793aa1bc7a5019ae2e48303573e0d5.zip
Fix smlald, smlsld, pkhtp, pkhbt, ssat, usat, umul, smul... (Laurent Desnogues).
helper.c - copy reference c0_c2 to runtime c0_c2 and not c0_c1 op_helper.c - remove old code (PARAM1, probably some left over from old dyngen) that broke do_[us]sat translate.c - gen_smul_dual should sign-extend from 16 bit to 32 bit and not from 8 to 32 - disas_arm_insn: * smlalxy: that was completely wrong; now the addition is performed as for smlald * pkhtb: optional ASR not taken into account (similar * to [us]sat) * pkhtb/pkhbt: tmp2 is dead * smlald, smlsld, smuad, smusd, smlad, smlsd: rd * and rn swapped git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4898 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-arm/translate.c')
-rw-r--r--target-arm/translate.c31
1 files changed, 18 insertions, 13 deletions
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 3183ef8ba0..8e3e1695bf 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -250,8 +250,8 @@ static void gen_smul_dual(TCGv a, TCGv b)
{
TCGv tmp1 = new_tmp();
TCGv tmp2 = new_tmp();
- tcg_gen_ext8s_i32(tmp1, a);
- tcg_gen_ext8s_i32(tmp2, b);
+ tcg_gen_ext16s_i32(tmp1, a);
+ tcg_gen_ext16s_i32(tmp2, b);
tcg_gen_mul_i32(tmp1, tmp1, tmp2);
dead_tmp(tmp2);
tcg_gen_sari_i32(a, a, 16);
@@ -5998,10 +5998,11 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
dead_tmp(tmp2);
if (op1 == 2) {
- tmp = tcg_temp_new(TCG_TYPE_I64);
- tcg_gen_ext_i32_i64(tmp, cpu_T[0]);
- gen_addq(s, tmp, rn, rd);
- gen_storeq_reg(s, rn, rd, tmp);
+ tmp2 = tcg_temp_new(TCG_TYPE_I64);
+ tcg_gen_ext_i32_i64(tmp2, tmp);
+ dead_tmp(tmp);
+ gen_addq(s, tmp2, rn, rd);
+ gen_storeq_reg(s, rn, rd, tmp2);
} else {
if (op1 == 0) {
tmp2 = load_reg(s, rn);
@@ -6372,18 +6373,22 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
tmp = load_reg(s, rn);
tmp2 = load_reg(s, rm);
shift = (insn >> 7) & 0x1f;
- if (shift)
- tcg_gen_shli_i32(tmp2, tmp2, shift);
if (insn & (1 << 6)) {
/* pkhtb */
+ if (shift == 0)
+ shift = 31;
+ tcg_gen_sari_i32(tmp2, tmp2, shift);
tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
tcg_gen_ext16u_i32(tmp2, tmp2);
} else {
/* pkhbt */
+ if (shift)
+ tcg_gen_shli_i32(tmp2, tmp2, shift);
tcg_gen_ext16u_i32(tmp, tmp);
tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
}
tcg_gen_or_i32(tmp, tmp, tmp2);
+ dead_tmp(tmp2);
store_reg(s, rd, tmp);
} else if ((insn & 0x00200020) == 0x00200000) {
/* [us]sat */
@@ -6510,17 +6515,17 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
tmp2 = tcg_temp_new(TCG_TYPE_I64);
tcg_gen_ext_i32_i64(tmp2, tmp);
dead_tmp(tmp);
- gen_addq(s, tmp2, rn, rd);
- gen_storeq_reg(s, rn, rd, tmp2);
+ gen_addq(s, tmp2, rd, rn);
+ gen_storeq_reg(s, rd, rn, tmp2);
} else {
/* smuad, smusd, smlad, smlsd */
- if (rn != 15)
+ if (rd != 15)
{
- tmp2 = load_reg(s, rn);
+ tmp2 = load_reg(s, rd);
gen_helper_add_setq(tmp, tmp, tmp2);
dead_tmp(tmp2);
}
- store_reg(s, rd, tmp);
+ store_reg(s, rn, tmp);
}
}
break;