From a46256129e80d993d23ed9d95566c79bcfa65e2d Mon Sep 17 00:00:00 2001 From: aurel32 Date: Fri, 29 Aug 2008 20:12:18 +0000 Subject: [PATCH] SH4: convert simple compare instructions to TCG (Shin-ichiro KAWASAKI) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5108 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-sh4/op.c | 72 ------------------------------------------ target-sh4/translate.c | 68 ++++++++++++++++++++++++++++++--------- 2 files changed, 53 insertions(+), 87 deletions(-) diff --git a/target-sh4/op.c b/target-sh4/op.c index 75b53bd24d..69d8e1b66d 100644 --- a/target-sh4/op.c +++ b/target-sh4/op.c @@ -37,12 +37,6 @@ static inline void cond_t(int cond) clr_t(); } -void OPPROTO op_cmp_eq_imm_T0(void) -{ - cond_t((int32_t) T0 == (int32_t) PARAM1); - RETURN(); -} - void OPPROTO op_bf_s(void) { env->delayed_pc = PARAM1; @@ -144,36 +138,6 @@ void OPPROTO op_addv_T0_T1(void) RETURN(); } -void OPPROTO op_cmp_eq_T0_T1(void) -{ - cond_t(T1 == T0); - RETURN(); -} - -void OPPROTO op_cmp_ge_T0_T1(void) -{ - cond_t((int32_t) T1 >= (int32_t) T0); - RETURN(); -} - -void OPPROTO op_cmp_gt_T0_T1(void) -{ - cond_t((int32_t) T1 > (int32_t) T0); - RETURN(); -} - -void OPPROTO op_cmp_hi_T0_T1(void) -{ - cond_t((uint32_t) T1 > (uint32_t) T0); - RETURN(); -} - -void OPPROTO op_cmp_hs_T0_T1(void) -{ - cond_t((uint32_t) T1 >= (uint32_t) T0); - RETURN(); -} - void OPPROTO op_cmp_str_T0_T1(void) { cond_t((T0 & 0x000000ff) == (T1 & 0x000000ff) || @@ -183,12 +147,6 @@ void OPPROTO op_cmp_str_T0_T1(void) RETURN(); } -void OPPROTO op_tst_T0_T1(void) -{ - cond_t((T1 & T0) == 0); - RETURN(); -} - void OPPROTO op_div0s_T0_T1(void) { if (T1 & 0x80000000) @@ -299,18 +257,6 @@ void OPPROTO op_trapa(void) RETURN(); } -void OPPROTO op_cmp_pl_T0(void) -{ - cond_t((int32_t) T0 > 0); - RETURN(); -} - -void OPPROTO op_cmp_pz_T0(void) -{ - cond_t((int32_t) T0 >= 0); - RETURN(); -} - void OPPROTO op_jmp_T0(void) { env->delayed_pc = T0; @@ -610,18 +556,6 @@ void OPPROTO op_fmov_T0_frN(void) RETURN(); } -void OPPROTO op_dt_rN(void) -{ - cond_t((--env->gregs[PARAM1]) == 0); - RETURN(); -} - -void OPPROTO op_tst_imm_rN(void) -{ - cond_t((env->gregs[PARAM2] & PARAM1) == 0); - RETURN(); -} - void OPPROTO op_movl_fpul_FT0(void) { FT0 = *(float32 *)&env->fpul; @@ -656,12 +590,6 @@ void OPPROTO op_movl_delayed_pc_PC(void) RETURN(); } -void OPPROTO op_tst_imm_T0(void) -{ - cond_t((T0 & PARAM1) == 0); - RETURN(); -} - void OPPROTO op_raise_illegal_instruction(void) { env->exception_index = 0x180; diff --git a/target-sh4/translate.c b/target-sh4/translate.c index 76fbe8cfbb..bf82542c61 100644 --- a/target-sh4/translate.c +++ b/target-sh4/translate.c @@ -283,6 +283,40 @@ static void gen_delayed_conditional_jump(DisasContext * ctx) gen_jump(ctx); } +static inline void gen_set_t(void) +{ + tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_T); +} + +static inline void gen_clr_t(void) +{ + tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_T); +} + +static inline void gen_cmp(int cond, TCGv t0, TCGv t1) +{ + int label1 = gen_new_label(); + int label2 = gen_new_label(); + tcg_gen_brcond_i32(cond, t1, t0, label1); + gen_clr_t(); + tcg_gen_br(label2); + gen_set_label(label1); + gen_set_t(); + gen_set_label(label2); +} + +static inline void gen_cmp_imm(int cond, TCGv t0, int32_t imm) +{ + int label1 = gen_new_label(); + int label2 = gen_new_label(); + tcg_gen_brcondi_i32(cond, t0, imm, label1); + gen_clr_t(); + tcg_gen_br(label2); + gen_set_label(label1); + gen_set_t(); + gen_set_label(label2); +} + #define B3_0 (ctx->opcode & 0xf) #define B6_4 ((ctx->opcode >> 4) & 0x7) #define B7_4 ((ctx->opcode >> 4) & 0xf) @@ -331,7 +365,7 @@ void _decode_opc(DisasContext * ctx) tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_S); return; case 0x0008: /* clrt */ - tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_T); + gen_clr_t(); return; case 0x0038: /* ldtlb */ #if defined(CONFIG_USER_ONLY) @@ -349,7 +383,7 @@ void _decode_opc(DisasContext * ctx) tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_S); return; case 0x0018: /* sett */ - tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_T); + gen_set_t(); return; case 0xfbfd: /* frchg */ gen_op_frchg(); @@ -582,27 +616,27 @@ void _decode_opc(DisasContext * ctx) case 0x3000: /* cmp/eq 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_cmp_eq_T0_T1(); + gen_cmp(TCG_COND_EQ, cpu_T[0], cpu_T[1]); return; case 0x3003: /* cmp/ge 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_cmp_ge_T0_T1(); + gen_cmp(TCG_COND_GE, cpu_T[0], cpu_T[1]); return; case 0x3007: /* cmp/gt 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_cmp_gt_T0_T1(); + gen_cmp(TCG_COND_GT, cpu_T[0], cpu_T[1]); return; case 0x3006: /* cmp/hi 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_cmp_hi_T0_T1(); + gen_cmp(TCG_COND_GTU, cpu_T[0], cpu_T[1]); return; case 0x3002: /* cmp/hs 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_cmp_hs_T0_T1(); + gen_cmp(TCG_COND_GEU, cpu_T[0], cpu_T[1]); return; case 0x200c: /* cmp/str Rm,Rn */ tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B7_4)]); @@ -737,7 +771,8 @@ void _decode_opc(DisasContext * ctx) case 0x2008: /* tst 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_tst_T0_T1(); + tcg_gen_and_i32(cpu_T[0], cpu_T[0], cpu_T[1]); + gen_cmp_imm(TCG_COND_EQ, cpu_T[0], 0); return; case 0x200a: /* xor Rm,Rn */ tcg_gen_xor_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], cpu_gregs[REG(B7_4)]); @@ -911,7 +946,7 @@ void _decode_opc(DisasContext * ctx) return; case 0x8800: /* cmp/eq #imm,R0 */ tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]); - gen_op_cmp_eq_imm_T0(B7_0s); + gen_cmp_imm(TCG_COND_EQ, cpu_T[0], B7_0s); return; case 0xc400: /* mov.b @(disp,GBR),R0 */ gen_op_stc_gbr_T0(); @@ -997,13 +1032,15 @@ void _decode_opc(DisasContext * ctx) ctx->bstate = BS_BRANCH; return; case 0xc800: /* tst #imm,R0 */ - gen_op_tst_imm_rN(B7_0, REG(0)); + tcg_gen_andi_i32(cpu_T[0], cpu_gregs[REG(0)], B7_0); + gen_cmp_imm(TCG_COND_EQ, cpu_T[0], 0); return; case 0xcc00: /* tst.b #imm,@(R0,GBR) */ tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(0)]); tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_gbr); gen_op_ldub_T0_T0(ctx); - gen_op_tst_imm_T0(B7_0); + tcg_gen_andi_i32(cpu_T[0], cpu_T[0], B7_0); + gen_cmp_imm(TCG_COND_EQ, cpu_T[0], 0); return; case 0xca00: /* xor #imm,R0 */ tcg_gen_xori_i32(cpu_gregs[REG(0)], cpu_gregs[REG(0)], B7_0); @@ -1058,14 +1095,15 @@ void _decode_opc(DisasContext * ctx) return; case 0x4015: /* cmp/pl Rn */ tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]); - gen_op_cmp_pl_T0(); + gen_cmp_imm(TCG_COND_GT, cpu_T[0], 0); return; case 0x4011: /* cmp/pz Rn */ tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]); - gen_op_cmp_pz_T0(); + gen_cmp_imm(TCG_COND_GE, cpu_T[0], 0); return; case 0x4010: /* dt Rn */ - gen_op_dt_rN(REG(B11_8)); + tcg_gen_subi_i32(cpu_gregs[REG(B11_8)], cpu_gregs[REG(B11_8)], 1); + gen_cmp_imm(TCG_COND_EQ, cpu_gregs[REG(B11_8)], 0); return; case 0x402b: /* jmp @Rn */ CHECK_NOT_DELAY_SLOT tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]); @@ -1187,7 +1225,7 @@ void _decode_opc(DisasContext * ctx) tcg_gen_mov_i32(cpu_T[0], cpu_gregs[REG(B11_8)]); tcg_gen_mov_i32(cpu_T[1], cpu_T[0]); gen_op_ldub_T0_T0(ctx); - gen_op_cmp_eq_imm_T0(0); + gen_cmp_imm(TCG_COND_EQ, cpu_T[0], 0); tcg_gen_ori_i32(cpu_T[0], cpu_T[0], 0x80); gen_op_stb_T0_T1(ctx); return;