Uses setcond in the many branch condition generators and movcond in the conditional move expanders.
Signed-off-by: Richard Henderson <r...@twiddle.net> --- target-mips/translate.c | 124 +++++++++++++++++++++++++---------------------- 1 files changed, 66 insertions(+), 58 deletions(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index dfea6f6..3c1f630 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -695,18 +695,10 @@ FOP_CONDS(abs, ps, 64) #undef FOP_CONDS /* Tests */ -#define OP_COND(name, cond) \ -static inline void glue(gen_op_, name) (TCGv ret, TCGv t0, TCGv t1) \ -{ \ - int l1 = gen_new_label(); \ - int l2 = gen_new_label(); \ - \ - tcg_gen_brcond_tl(cond, t0, t1, l1); \ - tcg_gen_movi_tl(ret, 0); \ - tcg_gen_br(l2); \ - gen_set_label(l1); \ - tcg_gen_movi_tl(ret, 1); \ - gen_set_label(l2); \ +#define OP_COND(name, cond) \ +static inline void glue(gen_op_, name) (TCGv ret, TCGv t0, TCGv t1) \ +{ \ + tcg_gen_setcond_tl(cond, ret, t0, t1); \ } OP_COND(eq, TCG_COND_EQ); OP_COND(ne, TCG_COND_NE); @@ -716,35 +708,23 @@ OP_COND(lt, TCG_COND_LT); OP_COND(ltu, TCG_COND_LTU); #undef OP_COND -#define OP_CONDI(name, cond) \ +#define OP_CONDI(name, cond) \ static inline void glue(gen_op_, name) (TCGv ret, TCGv t0, target_ulong val) \ -{ \ - int l1 = gen_new_label(); \ - int l2 = gen_new_label(); \ - \ - tcg_gen_brcondi_tl(cond, t0, val, l1); \ - tcg_gen_movi_tl(ret, 0); \ - tcg_gen_br(l2); \ - gen_set_label(l1); \ - tcg_gen_movi_tl(ret, 1); \ - gen_set_label(l2); \ +{ \ + TCGv t1 = tcg_const_tl(val); \ + tcg_gen_setcond_tl(cond, ret, t0, t1); \ + tcg_temp_free(t1); \ } OP_CONDI(lti, TCG_COND_LT); OP_CONDI(ltiu, TCG_COND_LTU); #undef OP_CONDI -#define OP_CONDZ(name, cond) \ -static inline void glue(gen_op_, name) (TCGv ret, TCGv t0) \ -{ \ - int l1 = gen_new_label(); \ - int l2 = gen_new_label(); \ - \ - tcg_gen_brcondi_tl(cond, t0, 0, l1); \ - tcg_gen_movi_tl(ret, 0); \ - tcg_gen_br(l2); \ - gen_set_label(l1); \ - tcg_gen_movi_tl(ret, 1); \ - gen_set_label(l2); \ +#define OP_CONDZ(name, cond) \ +static inline void glue(gen_op_, name) (TCGv ret, TCGv t0) \ +{ \ + TCGv zero = tcg_const_tl(0); \ + tcg_gen_setcond_tl(cond, ret, t0, zero); \ + tcg_temp_free(zero); \ } OP_CONDZ(gez, TCG_COND_GE); OP_CONDZ(gtz, TCG_COND_GT); @@ -1705,36 +1685,45 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, static void gen_cond_move (CPUState *env, uint32_t opc, int rd, int rs, int rt) { const char *opn = "cond move"; - int l1; + TCGv zero, vs; + TCGCond cond; if (rd == 0) { - /* If no destination, treat it as a NOP. - For add & sub, we must generate the overflow exception when needed. */ + /* If no destination, treat it as a NOP. For add & sub, we + must generate the overflow exception when needed. */ MIPS_DEBUG("NOP"); return; } - l1 = gen_new_label(); + zero = tcg_const_tl(0); + if (rs == 0) + vs = zero; + else + vs = cpu_gpr[rs]; + switch (opc) { case OPC_MOVN: - if (likely(rt != 0)) - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1); - else - tcg_gen_br(l1); opn = "movn"; + cond = TCG_COND_EQ; + if (unlikely(rt == 0)) + goto done; break; case OPC_MOVZ: - if (likely(rt != 0)) - tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1); opn = "movz"; + cond = TCG_COND_NE; + if (unlikely(rt == 0)) { + tcg_gen_mov_tl(cpu_gpr[rd], vs); + goto done; + } break; + default: + abort (); } - if (rs != 0) - tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); - else - tcg_gen_movi_tl(cpu_gpr[rd], 0); - gen_set_label(l1); + tcg_gen_movcond_tl(cond, cpu_gpr[rd], cpu_gpr[rt], zero, vs, cpu_gpr[rd]); + + done: + tcg_temp_free(zero); MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]); } @@ -5845,7 +5834,6 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs) static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf) { - int l1; TCGCond cond; TCGv_i32 t0; @@ -5859,17 +5847,37 @@ static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf) else cond = TCG_COND_NE; - l1 = gen_new_label(); t0 = tcg_temp_new_i32(); tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc)); - tcg_gen_brcondi_i32(cond, t0, 0, l1); - tcg_temp_free_i32(t0); - if (rs == 0) { - tcg_gen_movi_tl(cpu_gpr[rd], 0); + + /* ??? There is no movcond with 32-bit comparison and 64-bit data. */ + if (TCG_TARGET_REG_BITS >= TARGET_LONG_BITS) { + TCGv t1, zero, vs; + +#if TARGET_LONG_BITS == 32 + t1 = t0; +#else + t1 = tcg_temp_new(); + tcg_gen_ext_i32_i64(t1, t0); +#endif + zero = tcg_const_tl(0); + vs = (rs == 0 ? zero : cpu_gpr[rs]); + tcg_gen_movcond_tl(cond, cpu_gpr[rd], t1, zero, cpu_gpr[rd], vs); + tcg_temp_free(zero); +#if TARGET_LONG_BITS == 64 + tcg_temp_free(t1); +#endif + tcg_temp_free_i32(t0); } else { - tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); + int l1 = gen_new_label(); + tcg_gen_brcondi_i32(cond, t0, 0, l1); + if (rs == 0) { + tcg_gen_movi_tl(cpu_gpr[rd], 0); + } else { + tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]); + } + gen_set_label(l1); } - gen_set_label(l1); } static inline void gen_movcf_s (int fs, int fd, int cc, int tf) -- 1.6.2.5