From d18badecf00b26b1f0829fad439d81a4c16cb71f Mon Sep 17 00:00:00 2001 From: ths Date: Wed, 21 May 2008 02:04:15 +0000 Subject: [PATCH] Switch MIPS clo/clz and the condition tests to TCG. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4507 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-mips/helper.h | 5 ++++ target-mips/op.c | 68 ---------------------------------------------- target-mips/op_helper.c | 10 +++++++ target-mips/translate.c | 71 ++++++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 80 insertions(+), 74 deletions(-) diff --git a/target-mips/helper.h b/target-mips/helper.h index ef6b9f9..98a97c9 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -1,3 +1,8 @@ void do_raise_exception_err(int excp, int err); void do_raise_exception(int excp); void do_interrupt_restart (void); + +void do_clo (void); +void do_clz (void); +void do_dclo (void); +void do_dclz (void); diff --git a/target-mips/op.c b/target-mips/op.c index 80ea364..69d3191 100644 --- a/target-mips/op.c +++ b/target-mips/op.c @@ -167,51 +167,6 @@ #undef MEMSUFFIX #endif -/* Logical */ -void op_clo (void) -{ - T0 = clo32(T0); - FORCE_RET(); -} - -void op_clz (void) -{ - T0 = clz32(T0); - FORCE_RET(); -} - -#if defined(TARGET_MIPS64) - -#if TARGET_LONG_BITS > HOST_LONG_BITS -/* Those might call libgcc functions. */ -void op_dclo (void) -{ - CALL_FROM_TB0(do_dclo); - FORCE_RET(); -} - -void op_dclz (void) -{ - CALL_FROM_TB0(do_dclz); - FORCE_RET(); -} - -#else /* TARGET_LONG_BITS > HOST_LONG_BITS */ - -void op_dclo (void) -{ - T0 = clo64(T0); - FORCE_RET(); -} - -void op_dclz (void) -{ - T0 = clz64(T0); - FORCE_RET(); -} -#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */ -#endif /* TARGET_MIPS64 */ - /* 64 bits arithmetic */ #if TARGET_LONG_BITS > HOST_LONG_BITS void op_mult (void) @@ -524,29 +479,6 @@ void op_movt (void) FORCE_RET(); } -/* Tests */ -#define OP_COND(name, cond) \ -void glue(op_, name) (void) \ -{ \ - if (cond) { \ - T0 = 1; \ - } else { \ - T0 = 0; \ - } \ - FORCE_RET(); \ -} - -OP_COND(eq, T0 == T1); -OP_COND(ne, T0 != T1); -OP_COND(ge, (target_long)T0 >= (target_long)T1); -OP_COND(geu, T0 >= T1); -OP_COND(lt, (target_long)T0 < (target_long)T1); -OP_COND(ltu, T0 < T1); -OP_COND(gez, (target_long)T0 >= 0); -OP_COND(gtz, (target_long)T0 > 0); -OP_COND(lez, (target_long)T0 <= 0); -OP_COND(ltz, (target_long)T0 < 0); - /* Branches */ /* Branch to register */ void op_save_breg_target (void) diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 3bb8095..50f353a 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -71,6 +71,16 @@ void do_restore_state (void *pc_ptr) } } +void do_clo (void) +{ + T0 = clo32(T0); +} + +void do_clz (void) +{ + T0 = clz32(T0); +} + #if defined(TARGET_MIPS64) #if TARGET_LONG_BITS > HOST_LONG_BITS /* Those might call libgcc functions. */ diff --git a/target-mips/translate.c b/target-mips/translate.c index 53fec05..fc72a93 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -655,6 +655,65 @@ FOP_CONDS(abs, s) FOP_CONDS(, ps) FOP_CONDS(abs, ps) +/* Tests */ +#define OP_COND(name, cond) \ +void glue(gen_op_, name) (void) \ +{ \ + int l1 = gen_new_label(); \ + int l2 = gen_new_label(); \ + \ + tcg_gen_brcond_tl(cond, cpu_T[0], cpu_T[1], l1); \ + gen_op_set_T0(0); \ + tcg_gen_br(l2); \ + gen_set_label(l1); \ + gen_op_set_T0(1); \ + gen_set_label(l2); \ +} +OP_COND(eq, TCG_COND_EQ); +OP_COND(ne, TCG_COND_NE); +OP_COND(ge, TCG_COND_GE); +OP_COND(geu, TCG_COND_GEU); +OP_COND(lt, TCG_COND_LT); +OP_COND(ltu, TCG_COND_LTU); +#undef OP_COND + +#define OP_CONDI(name, cond) \ +void glue(gen_op_, name) (target_ulong val) \ +{ \ + int l1 = gen_new_label(); \ + int l2 = gen_new_label(); \ + \ + tcg_gen_brcond_tl(cond, cpu_T[0], tcg_const_tl(val), l1); \ + gen_op_set_T0(0); \ + tcg_gen_br(l2); \ + gen_set_label(l1); \ + gen_op_set_T0(1); \ + gen_set_label(l2); \ +} +OP_CONDI(lti, TCG_COND_LT); +OP_CONDI(ltiu, TCG_COND_LTU); +#undef OP_CONDI + +#define OP_CONDZ(name, cond) \ +void glue(gen_op_, name) (void) \ +{ \ + int l1 = gen_new_label(); \ + int l2 = gen_new_label(); \ + \ + tcg_gen_brcond_tl(cond, cpu_T[0], tcg_const_tl(0), l1); \ + gen_op_set_T0(0); \ + tcg_gen_br(l2); \ + gen_set_label(l1); \ + gen_op_set_T0(1); \ + gen_set_label(l2); \ +} +OP_CONDZ(gez, TCG_COND_GE); +OP_CONDZ(gtz, TCG_COND_GT); +OP_CONDZ(lez, TCG_COND_LE); +OP_CONDZ(ltz, TCG_COND_LT); +#undef OP_CONDZ + + typedef struct DisasContext { struct TranslationBlock *tb; target_ulong pc, saved_pc; @@ -1375,11 +1434,11 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, break; #endif case OPC_SLTI: - gen_op_lt(); + gen_op_lti(uimm); opn = "slti"; break; case OPC_SLTIU: - gen_op_ltu(); + gen_op_ltiu(uimm); opn = "sltiu"; break; case OPC_ANDI: @@ -2160,20 +2219,20 @@ static void gen_cl (DisasContext *ctx, uint32_t opc, GEN_LOAD_REG_T0(rs); switch (opc) { case OPC_CLO: - gen_op_clo(); + tcg_gen_helper_0_0(do_clo); opn = "clo"; break; case OPC_CLZ: - gen_op_clz(); + tcg_gen_helper_0_0(do_clz); opn = "clz"; break; #if defined(TARGET_MIPS64) case OPC_DCLO: - gen_op_dclo(); + tcg_gen_helper_0_0(do_dclo); opn = "dclo"; break; case OPC_DCLZ: - gen_op_dclz(); + tcg_gen_helper_0_0(do_dclz); opn = "dclz"; break; #endif -- 2.7.4