From: aurel32 Date: Sat, 30 Aug 2008 13:55:14 +0000 (+0000) Subject: SH4: convert some more arithmetics ops to TCG X-Git-Tag: 0.10.0-0maemo1~1227 X-Git-Url: http://git.maemo.org/git/?a=commitdiff_plain;h=6f06939b6877bdfcac7d466e876022889d2fe59c;p=qemu SH4: convert some more arithmetics ops to TCG Signed-off-by: Aurelien Jarno git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5116 c046a42c-6fe2-441c-8c8c-71466251a162 --- diff --git a/target-sh4/exec.h b/target-sh4/exec.h index 544dc0f..3135874 100644 --- a/target-sh4/exec.h +++ b/target-sh4/exec.h @@ -71,23 +71,12 @@ int find_itlb_entry(CPUState * env, target_ulong address, int use_asid, int update); int find_utlb_entry(CPUState * env, target_ulong address, int use_asid); -void helper_addc_T0_T1(void); -void helper_addv_T0_T1(void); void helper_div1_T0_T1(void); -void helper_dmulsl_T0_T1(void); -void helper_dmulul_T0_T1(void); -void helper_macl_T0_T1(void); -void helper_macw_T0_T1(void); -void helper_negc_T0(void); -void helper_subc_T0_T1(void); -void helper_subv_T0_T1(void); void helper_rotcl(uint32_t * addr); void helper_rotcr(uint32_t * addr); -void helper_ldtlb(void); void do_interrupt(CPUState * env); void cpu_loop_exit(void); -void do_raise_exception(void); #endif /* _EXEC_SH4_H */ diff --git a/target-sh4/helper.h b/target-sh4/helper.h index 4d0e269..ca64968 100644 --- a/target-sh4/helper.h +++ b/target-sh4/helper.h @@ -8,3 +8,11 @@ DEF_HELPER(void, helper_raise_slot_illegal_instruction, (void)) DEF_HELPER(void, helper_debug, (void)) DEF_HELPER(void, helper_sleep, (void)) DEF_HELPER(void, helper_trapa, (uint32_t)) + +DEF_HELPER(uint32_t, helper_addv, (uint32_t, uint32_t)) +DEF_HELPER(uint32_t, helper_addc, (uint32_t, uint32_t)) +DEF_HELPER(uint32_t, helper_subv, (uint32_t, uint32_t)) +DEF_HELPER(uint32_t, helper_subc, (uint32_t, uint32_t)) +DEF_HELPER(uint32_t, helper_negc, (uint32_t)) +DEF_HELPER(void, helper_macl, (uint32_t, uint32_t)) +DEF_HELPER(void, helper_macw, (uint32_t, uint32_t)) diff --git a/target-sh4/op.c b/target-sh4/op.c index d6bb520..a2c602a 100644 --- a/target-sh4/op.c +++ b/target-sh4/op.c @@ -37,30 +37,6 @@ static inline void cond_t(int cond) clr_t(); } -void OPPROTO op_frchg(void) -{ - env->fpscr ^= FPSCR_FR; - RETURN(); -} - -void OPPROTO op_fschg(void) -{ - env->fpscr ^= FPSCR_SZ; - RETURN(); -} - -void OPPROTO op_addc_T0_T1(void) -{ - helper_addc_T0_T1(); - RETURN(); -} - -void OPPROTO op_addv_T0_T1(void) -{ - helper_addv_T0_T1(); - RETURN(); -} - void OPPROTO op_cmp_str_T0_T1(void) { cond_t((T0 & 0x000000ff) == (T1 & 0x000000ff) || @@ -90,54 +66,6 @@ void OPPROTO op_div1_T0_T1(void) RETURN(); } -void OPPROTO op_dmulsl_T0_T1(void) -{ - helper_dmulsl_T0_T1(); - RETURN(); -} - -void OPPROTO op_dmulul_T0_T1(void) -{ - helper_dmulul_T0_T1(); - RETURN(); -} - -void OPPROTO op_macl_T0_T1(void) -{ - helper_macl_T0_T1(); - RETURN(); -} - -void OPPROTO op_macw_T0_T1(void) -{ - helper_macw_T0_T1(); - RETURN(); -} - -void OPPROTO op_mull_T0_T1(void) -{ - env->macl = (T0 * T1) & 0xffffffff; - RETURN(); -} - -void OPPROTO op_mulsw_T0_T1(void) -{ - env->macl = (int32_t)(int16_t) T0 *(int32_t)(int16_t) T1; - RETURN(); -} - -void OPPROTO op_muluw_T0_T1(void) -{ - env->macl = (uint32_t)(uint16_t) T0 *(uint32_t)(uint16_t) T1; - RETURN(); -} - -void OPPROTO op_negc_T0(void) -{ - helper_negc_T0(); - RETURN(); -} - void OPPROTO op_shad_T0_T1(void) { if ((T0 & 0x80000000) == 0) @@ -160,25 +88,6 @@ void OPPROTO op_shld_T0_T1(void) RETURN(); } -void OPPROTO op_subc_T0_T1(void) -{ - helper_subc_T0_T1(); - RETURN(); -} - -void OPPROTO op_subv_T0_T1(void) -{ - helper_subv_T0_T1(); - RETURN(); -} - -void OPPROTO op_ldcl_rMplus_rN_bank(void) -{ - env->gregs[PARAM2] = env->gregs[PARAM1]; - env->gregs[PARAM1] += 4; - RETURN(); -} - void OPPROTO op_ldc_T0_sr(void) { env->sr = T0 & 0x700083f3; @@ -237,7 +146,7 @@ void OPPROTO op_rotcr_Rn(void) RETURN(); } -void OPPROTO op_rotl_Rn(void) +void OPPROTO op_rotl_Rn(void) { cond_t(env->gregs[PARAM1] & 0x80000000); env->gregs[PARAM1] = (env->gregs[PARAM1] << 1) | (env->sr & SR_T); diff --git a/target-sh4/op_helper.c b/target-sh4/op_helper.c index 8504115..e3f9527 100644 --- a/target-sh4/op_helper.c +++ b/target-sh4/op_helper.c @@ -108,36 +108,37 @@ void helper_trapa(uint32_t tra) cpu_loop_exit(); } -void helper_addc_T0_T1(void) +uint32_t helper_addc(uint32_t arg0, uint32_t arg1) { uint32_t tmp0, tmp1; - tmp1 = T0 + T1; - tmp0 = T1; - T1 = tmp1 + (env->sr & 1); + tmp1 = arg0 + arg1; + tmp0 = arg1; + arg1 = tmp1 + (env->sr & 1); if (tmp0 > tmp1) env->sr |= SR_T; else env->sr &= ~SR_T; - if (tmp1 > T1) + if (tmp1 > arg1) env->sr |= SR_T; + return arg1; } -void helper_addv_T0_T1(void) +uint32_t helper_addv(uint32_t arg0, uint32_t arg1) { uint32_t dest, src, ans; - if ((int32_t) T1 >= 0) + if ((int32_t) arg1 >= 0) dest = 0; else dest = 1; - if ((int32_t) T0 >= 0) + if ((int32_t) arg0 >= 0) src = 0; else src = 1; src += dest; - T1 += T0; - if ((int32_t) T1 >= 0) + arg1 += arg0; + if ((int32_t) arg1 >= 0) ans = 0; else ans = 1; @@ -149,6 +150,7 @@ void helper_addv_T0_T1(void) env->sr &= ~SR_T; } else env->sr &= ~SR_T; + return arg1; } #define T (env->sr & SR_T) @@ -268,30 +270,12 @@ void helper_div1_T0_T1(void) //printf("Output: T1=0x%08x M=%d Q=%d T=%d\n", T1, M, Q, T); } -void helper_dmulsl_T0_T1() -{ - int64_t res; - - res = (int64_t) (int32_t) T0 *(int64_t) (int32_t) T1; - env->mach = (res >> 32) & 0xffffffff; - env->macl = res & 0xffffffff; -} - -void helper_dmulul_T0_T1() -{ - uint64_t res; - - res = (uint64_t) (uint32_t) T0 *(uint64_t) (uint32_t) T1; - env->mach = (res >> 32) & 0xffffffff; - env->macl = res & 0xffffffff; -} - -void helper_macl_T0_T1() +void helper_macl(uint32_t arg0, uint32_t arg1) { int64_t res; res = ((uint64_t) env->mach << 32) | env->macl; - res += (int64_t) (int32_t) T0 *(int64_t) (int32_t) T1; + res += (int64_t) (int32_t) arg0 *(int64_t) (int32_t) arg1; env->mach = (res >> 32) & 0xffffffff; env->macl = res & 0xffffffff; if (env->sr & SR_S) { @@ -302,12 +286,12 @@ void helper_macl_T0_T1() } } -void helper_macw_T0_T1() +void helper_macw(uint32_t arg0, uint32_t arg1) { int64_t res; res = ((uint64_t) env->mach << 32) | env->macl; - res += (int64_t) (int16_t) T0 *(int64_t) (int16_t) T1; + res += (int64_t) (int16_t) arg0 *(int64_t) (int16_t) arg1; env->mach = (res >> 32) & 0xffffffff; env->macl = res & 0xffffffff; if (env->sr & SR_S) { @@ -321,50 +305,52 @@ void helper_macw_T0_T1() } } -void helper_negc_T0() +uint32_t helper_negc(uint32_t arg) { uint32_t temp; - temp = -T0; - T0 = temp - (env->sr & SR_T); + temp = -arg; + arg = temp - (env->sr & SR_T); if (0 < temp) env->sr |= SR_T; else env->sr &= ~SR_T; - if (temp < T0) + if (temp < arg) env->sr |= SR_T; + return arg; } -void helper_subc_T0_T1() +uint32_t helper_subc(uint32_t arg0, uint32_t arg1) { uint32_t tmp0, tmp1; - tmp1 = T1 - T0; - tmp0 = T1; - T1 = tmp1 - (env->sr & SR_T); + tmp1 = arg1 - arg0; + tmp0 = arg1; + arg1 = tmp1 - (env->sr & SR_T); if (tmp0 < tmp1) env->sr |= SR_T; else env->sr &= ~SR_T; - if (tmp1 < T1) + if (tmp1 < arg1) env->sr |= SR_T; + return arg1; } -void helper_subv_T0_T1() +uint32_t helper_subv(uint32_t arg0, uint32_t arg1) { int32_t dest, src, ans; - if ((int32_t) T1 >= 0) + if ((int32_t) arg1 >= 0) dest = 0; else dest = 1; - if ((int32_t) T0 >= 0) + if ((int32_t) arg0 >= 0) src = 0; else src = 1; src += dest; - T1 -= T0; - if ((int32_t) T1 >= 0) + arg1 -= arg0; + if ((int32_t) arg1 >= 0) ans = 0; else ans = 1; @@ -376,6 +362,7 @@ void helper_subv_T0_T1() env->sr &= ~SR_T; } else env->sr &= ~SR_T; + return arg1; } void helper_rotcl(uint32_t * addr) diff --git a/target-sh4/translate.c b/target-sh4/translate.c index 19486d7..9f1c357 100644 --- a/target-sh4/translate.c +++ b/target-sh4/translate.c @@ -417,11 +417,11 @@ void _decode_opc(DisasContext * ctx) gen_set_t(); return; case 0xfbfd: /* frchg */ - gen_op_frchg(); + tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_FR); ctx->bstate = BS_STOP; return; case 0xf3fd: /* fschg */ - gen_op_fschg(); + tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_SZ); ctx->bstate = BS_STOP; return; case 0x0009: /* nop */ @@ -632,16 +632,10 @@ void _decode_opc(DisasContext * ctx) tcg_gen_add_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]); return; case 0x300e: /* addc Rm,Rn */ - tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]); - tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]); - gen_op_addc_T0_T1(); - tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]); + tcg_gen_helper_1_2(helper_addc, cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)], cpu_gregs[REG(B11_8)]); return; case 0x300f: /* addv Rm,Rn */ - tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]); - tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]); - gen_op_addv_T0_T1(); - tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]); + tcg_gen_helper_1_2(helper_addv, cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)], cpu_gregs[REG(B11_8)]); return; case 0x2009: /* and Rm,Rn */ tcg_gen_and_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]); @@ -688,14 +682,36 @@ void _decode_opc(DisasContext * ctx) tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]); return; case 0x300d: /* dmuls.l Rm,Rn */ - tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]); - tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]); - gen_op_dmulsl_T0_T1(); + { + TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64); + TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64); + + tcg_gen_ext_i32_i64(tmp1, cpu_gregs[REG(B7_4)]); + tcg_gen_ext_i32_i64(tmp2, cpu_gregs[REG(B11_8)]); + tcg_gen_mul_i64(tmp1, tmp1, tmp2); + tcg_gen_trunc_i64_i32(cpu_macl, tmp1); + tcg_gen_shri_i64(tmp1, tmp1, 32); + tcg_gen_trunc_i64_i32(cpu_mach, tmp1); + + tcg_temp_free(tmp1); + tcg_temp_free(tmp2); + } return; case 0x3005: /* dmulu.l Rm,Rn */ - tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]); - tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]); - gen_op_dmulul_T0_T1(); + { + TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64); + TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64); + + tcg_gen_extu_i32_i64(tmp1, cpu_gregs[REG(B7_4)]); + tcg_gen_extu_i32_i64(tmp2, cpu_gregs[REG(B11_8)]); + tcg_gen_mul_i64(tmp1, tmp1, tmp2); + tcg_gen_trunc_i64_i32(cpu_macl, tmp1); + tcg_gen_shri_i64(tmp1, tmp1, 32); + tcg_gen_trunc_i64_i32(cpu_mach, tmp1); + + tcg_temp_free(tmp1); + tcg_temp_free(tmp2); + } return; case 0x600e: /* exts.b Rm,Rn */ tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]); @@ -725,7 +741,7 @@ void _decode_opc(DisasContext * ctx) tcg_gen_mov_i32(cpu_T[1], cpu_T[0]); tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]); gen_op_ldl_T0_T0(ctx); - gen_op_macl_T0_T1(); + tcg_gen_helper_0_2(helper_macl, cpu_T[0], cpu_T[1]); tcg_gen_addi_i32(cpu_gregs[REG(B7_4)], cpu_gregs[REG(B7_4)], 4); tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 4); return; @@ -735,38 +751,28 @@ void _decode_opc(DisasContext * ctx) tcg_gen_mov_i32(cpu_T[1], cpu_T[0]); tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]); gen_op_ldl_T0_T0(ctx); - gen_op_macw_T0_T1(); + tcg_gen_helper_0_2(helper_macw, cpu_T[0], cpu_T[1]); tcg_gen_addi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 2); tcg_gen_addi_i32(cpu_gregs[REG(B7_4)], cpu_gregs[REG(B7_4)], 2); return; case 0x0007: /* mul.l Rm,Rn */ - tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]); - tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]); - gen_op_mull_T0_T1(); + tcg_gen_mul_i32(cpu_macl, cpu_gregs[REG(B7_4)], cpu_gregs[REG(B11_8)]); return; case 0x200f: /* muls.w Rm,Rn */ - tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]); - tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff); - tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]); - tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]); - tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff); - tcg_gen_ext16s_i32(cpu_T[1], cpu_T[1]); - gen_op_mulsw_T0_T1(); + tcg_gen_ext16s_i32(cpu_T[0], cpu_gregs[REG(B7_4)]); + tcg_gen_ext16s_i32(cpu_T[1], cpu_gregs[REG(B11_8)]); + tcg_gen_mul_i32(cpu_macl, cpu_T[0], cpu_T[1]); return; case 0x200e: /* mulu.w Rm,Rn */ - tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]); - tcg_gen_andi_i32(cpu_T[0], cpu_T[0], 0xffff); - tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]); - tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0xffff); - gen_op_muluw_T0_T1(); + tcg_gen_ext16u_i32(cpu_T[0], cpu_gregs[REG(B7_4)]); + tcg_gen_ext16u_i32(cpu_T[1], cpu_gregs[REG(B11_8)]); + tcg_gen_mul_i32(cpu_macl, cpu_T[0], cpu_T[1]); return; case 0x600b: /* neg Rm,Rn */ tcg_gen_neg_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]); return; case 0x600a: /* negc Rm,Rn */ - tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]); - gen_op_negc_T0(); - tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[0]); + tcg_gen_helper_1_1(helper_negc, cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]); return; case 0x6007: /* not Rm,Rn */ tcg_gen_not_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]); @@ -790,16 +796,10 @@ void _decode_opc(DisasContext * ctx) tcg_gen_sub_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]); return; case 0x300a: /* subc Rm,Rn */ - tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]); - tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]); - gen_op_subc_T0_T1(); - tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]); + tcg_gen_helper_1_2(helper_subc, cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)], cpu_gregs[REG(B11_8)]); return; case 0x300b: /* subv Rm,Rn */ - tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]); - tcg_gen_mov_i32(cpu_T[1], cpu_gregs[REG(B11_8)]); - gen_op_subv_T0_T1(); - tcg_gen_mov_i32(cpu_gregs[REG(B11_8)], cpu_T[1]); + tcg_gen_helper_1_2(helper_subv, cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)], cpu_gregs[REG(B11_8)]); return; case 0x2008: /* tst Rm,Rn */ tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]);