mirror of
https://github.com/xemu-project/xemu.git
synced 2025-02-02 18:25:52 +00:00
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
This commit is contained in:
parent
f617a9a6bb
commit
22478e79f2
@ -64,7 +64,7 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
|
||||
env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111;
|
||||
env->vfp.xregs[ARM_VFP_MVFR1] = 0x00000000;
|
||||
memcpy(env->cp15.c0_c1, arm1136_cp15_c0_c1, 8 * sizeof(uint32_t));
|
||||
memcpy(env->cp15.c0_c1, arm1136_cp15_c0_c2, 8 * sizeof(uint32_t));
|
||||
memcpy(env->cp15.c0_c2, arm1136_cp15_c0_c2, 8 * sizeof(uint32_t));
|
||||
env->cp15.c0_cachetype = 0x1dd20d2;
|
||||
break;
|
||||
case ARM_CPUID_ARM11MPCORE:
|
||||
@ -76,7 +76,7 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
|
||||
env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111;
|
||||
env->vfp.xregs[ARM_VFP_MVFR1] = 0x00000000;
|
||||
memcpy(env->cp15.c0_c1, mpcore_cp15_c0_c1, 8 * sizeof(uint32_t));
|
||||
memcpy(env->cp15.c0_c1, mpcore_cp15_c0_c2, 8 * sizeof(uint32_t));
|
||||
memcpy(env->cp15.c0_c2, mpcore_cp15_c0_c2, 8 * sizeof(uint32_t));
|
||||
env->cp15.c0_cachetype = 0x1dd20d2;
|
||||
break;
|
||||
case ARM_CPUID_CORTEXA8:
|
||||
@ -92,7 +92,7 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
|
||||
env->vfp.xregs[ARM_VFP_MVFR0] = 0x11110222;
|
||||
env->vfp.xregs[ARM_VFP_MVFR1] = 0x00011100;
|
||||
memcpy(env->cp15.c0_c1, cortexa8_cp15_c0_c1, 8 * sizeof(uint32_t));
|
||||
memcpy(env->cp15.c0_c1, cortexa8_cp15_c0_c2, 8 * sizeof(uint32_t));
|
||||
memcpy(env->cp15.c0_c2, cortexa8_cp15_c0_c2, 8 * sizeof(uint32_t));
|
||||
env->cp15.c0_cachetype = 0x1dd20d2;
|
||||
break;
|
||||
case ARM_CPUID_CORTEXM3:
|
||||
|
@ -185,7 +185,6 @@ static inline uint32_t do_ssat(int32_t val, int shift)
|
||||
int32_t top;
|
||||
uint32_t mask;
|
||||
|
||||
shift = PARAM1;
|
||||
top = val >> shift;
|
||||
mask = (1u << shift) - 1;
|
||||
if (top > 0) {
|
||||
@ -203,7 +202,6 @@ static inline uint32_t do_usat(int32_t val, int shift)
|
||||
{
|
||||
uint32_t max;
|
||||
|
||||
shift = PARAM1;
|
||||
max = (1u << shift) - 1;
|
||||
if (val < 0) {
|
||||
env->QF = 1;
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user