Signed-off-by: Richard Henderson <r...@twiddle.net> --- target-arm/translate-a64.c | 60 +++++++++++++++++++--------------------------- 1 file changed, 24 insertions(+), 36 deletions(-)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index d139b2d..7549267 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -3703,7 +3703,8 @@ static void disas_cc(DisasContext *s, uint32_t insn) static void disas_cond_select(DisasContext *s, uint32_t insn) { unsigned int sf, else_inv, rm, cond, else_inc, rn, rd; - TCGv_i64 tcg_rd, tcg_src; + TCGv_i64 tcg_rd, zero; + DisasCompare c; if (extract32(insn, 29, 1) || extract32(insn, 11, 1)) { /* S == 1 or op2<1> == 1 */ @@ -3718,48 +3719,35 @@ static void disas_cond_select(DisasContext *s, uint32_t insn) rn = extract32(insn, 5, 5); rd = extract32(insn, 0, 5); - if (rd == 31) { - /* silly no-op write; until we use movcond we must special-case - * this to avoid a dead temporary across basic blocks. - */ - return; - } - tcg_rd = cpu_reg(s, rd); - if (cond >= 0x0e) { /* condition "always" */ - tcg_src = read_cpu_reg(s, rn, sf); - tcg_gen_mov_i64(tcg_rd, tcg_src); - } else { - /* OPTME: we could use movcond here, at the cost of duplicating - * a lot of the arm_gen_test_cc() logic. - */ - TCGLabel *label_match = gen_new_label(); - TCGLabel *label_continue = gen_new_label(); - - arm_gen_test_cc(cond, label_match); - /* nomatch: */ - tcg_src = cpu_reg(s, rm); + arm_test_cc(&c, cond); + zero = tcg_const_i64(0); + if (rn == 31 && rm == 31 && (else_inc ^ else_inv)) { + /* CSET & CSETM. */ + tcg_gen_setcond_i64(tcg_invert_cond(c.cond), tcg_rd, c.value, zero); + if (else_inv) { + tcg_gen_neg_i64(tcg_rd, tcg_rd); + } + } else { + TCGv_i64 t_true = cpu_reg(s, rn); + TCGv_i64 t_false = read_cpu_reg(s, rm, 1); if (else_inv && else_inc) { - tcg_gen_neg_i64(tcg_rd, tcg_src); + tcg_gen_neg_i64(t_false, t_false); } else if (else_inv) { - tcg_gen_not_i64(tcg_rd, tcg_src); + tcg_gen_not_i64(t_false, t_false); } else if (else_inc) { - tcg_gen_addi_i64(tcg_rd, tcg_src, 1); - } else { - tcg_gen_mov_i64(tcg_rd, tcg_src); - } - if (!sf) { - tcg_gen_ext32u_i64(tcg_rd, tcg_rd); + tcg_gen_addi_i64(t_false, t_false, 1); } - tcg_gen_br(label_continue); - /* match: */ - gen_set_label(label_match); - tcg_src = read_cpu_reg(s, rn, sf); - tcg_gen_mov_i64(tcg_rd, tcg_src); - /* continue: */ - gen_set_label(label_continue); + tcg_gen_movcond_i64(c.cond, tcg_rd, c.value, zero, t_true, t_false); + } + + tcg_temp_free_i64(zero); + arm_free_cc(&c); + + if (!sf) { + tcg_gen_ext32u_i64(tcg_rd, tcg_rd); } } -- 2.1.0