Signed-off-by: Richard Henderson <richard.hender...@linaro.org> --- target/sparc/cpu.h | 1 - target/sparc/cc_helper.c | 19 -------- target/sparc/translate.c | 97 +++++++++++++++++----------------------- 3 files changed, 40 insertions(+), 77 deletions(-)
diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h index df49d8423a..48e549f7cb 100644 --- a/target/sparc/cpu.h +++ b/target/sparc/cpu.h @@ -158,7 +158,6 @@ enum { CC_OP_SUBX, /* modify all flags, CC_DST = res, CC_SRC = src1 */ CC_OP_TSUB, /* modify all flags, CC_DST = res, CC_SRC = src1 */ CC_OP_TSUBTV, /* modify all flags except V, CC_DST = res, CC_SRC = src1 */ - CC_OP_LOGIC, /* modify N and Z, C = V = 0, CC_DST = res */ CC_OP_NB, }; diff --git a/target/sparc/cc_helper.c b/target/sparc/cc_helper.c index a6d1a4b9ae..a88399d74a 100644 --- a/target/sparc/cc_helper.c +++ b/target/sparc/cc_helper.c @@ -354,23 +354,6 @@ static uint32_t compute_all_tsubtv(CPUSPARCState *env) return ret; } -static uint32_t compute_all_logic(CPUSPARCState *env) -{ - return get_NZ_icc(CC_DST); -} - -static uint32_t compute_C_logic(CPUSPARCState *env) -{ - return 0; -} - -#ifdef TARGET_SPARC64 -static uint32_t compute_all_logic_xcc(CPUSPARCState *env) -{ - return get_NZ_xcc(CC_DST); -} -#endif - typedef struct CCTable { uint32_t (*compute_all)(CPUSPARCState *env); /* return all the flags */ uint32_t (*compute_c)(CPUSPARCState *env); /* return the C flag */ @@ -386,7 +369,6 @@ static const CCTable icc_table[CC_OP_NB] = { [CC_OP_SUBX] = { compute_all_subx, compute_C_subx }, [CC_OP_TSUB] = { compute_all_tsub, compute_C_sub }, [CC_OP_TSUBTV] = { compute_all_tsubtv, compute_C_sub }, - [CC_OP_LOGIC] = { compute_all_logic, compute_C_logic }, }; #ifdef TARGET_SPARC64 @@ -400,7 +382,6 @@ static const CCTable xcc_table[CC_OP_NB] = { [CC_OP_SUBX] = { compute_all_subx_xcc, compute_C_subx_xcc }, [CC_OP_TSUB] = { compute_all_sub_xcc, compute_C_sub_xcc }, [CC_OP_TSUBTV] = { compute_all_sub_xcc, compute_C_sub_xcc }, - [CC_OP_LOGIC] = { compute_all_logic_xcc, compute_C_logic }, }; #endif diff --git a/target/sparc/translate.c b/target/sparc/translate.c index 2ca20ba110..989275b17d 100644 --- a/target/sparc/translate.c +++ b/target/sparc/translate.c @@ -437,15 +437,6 @@ static void gen_op_addx_int(DisasContext *dc, TCGv dst, TCGv src1, TCGv carry; switch (dc->cc_op) { - case CC_OP_LOGIC: - /* Carry is known to be zero. Fall back to plain ADD. */ - if (update_cc) { - gen_op_add_cc(dst, src1, src2); - } else { - tcg_gen_add_tl(dst, src1, src2); - } - return; - case CC_OP_ADD: case CC_OP_TADD: case CC_OP_TADDTV: @@ -509,15 +500,6 @@ static void gen_op_subx_int(DisasContext *dc, TCGv dst, TCGv src1, TCGv carry; switch (dc->cc_op) { - case CC_OP_LOGIC: - /* Carry is known to be zero. Fall back to plain SUB. */ - if (update_cc) { - gen_op_sub_cc(dst, src1, src2); - } else { - tcg_gen_sub_tl(dst, src1, src2); - } - return; - case CC_OP_ADD: case CC_OP_TADD: case CC_OP_TADDTV: @@ -1069,48 +1051,25 @@ static void gen_compare(DisasCompare *cmp, bool xcc, unsigned int cond, -1, /* no overflow */ }; - static int logic_cond[16] = { - TCG_COND_NEVER, - TCG_COND_EQ, /* eq: Z */ - TCG_COND_LE, /* le: Z | (N ^ V) -> Z | N */ - TCG_COND_LT, /* lt: N ^ V -> N */ - TCG_COND_EQ, /* leu: C | Z -> Z */ - TCG_COND_NEVER, /* ltu: C -> 0 */ - TCG_COND_LT, /* neg: N */ - TCG_COND_NEVER, /* vs: V -> 0 */ - TCG_COND_ALWAYS, - TCG_COND_NE, /* ne: !Z */ - TCG_COND_GT, /* gt: !(Z | (N ^ V)) -> !(Z | N) */ - TCG_COND_GE, /* ge: !(N ^ V) -> !N */ - TCG_COND_NE, /* gtu: !(C | Z) -> !Z */ - TCG_COND_ALWAYS, /* geu: !C -> 1 */ - TCG_COND_GE, /* pos: !N */ - TCG_COND_ALWAYS, /* vc: !V -> 1 */ - }; - TCGv t1, t2; cmp->is_bool = false; switch (dc->cc_op) { - case CC_OP_LOGIC: - cmp->cond = logic_cond[cond]; - do_compare_dst_0: - cmp->c2 = tcg_constant_tl(0); - if (TARGET_LONG_BITS == 32 || xcc) { - cmp->c1 = cpu_cc_dst; - } else { - cmp->c1 = t1 = tcg_temp_new(); - tcg_gen_ext32s_tl(t1, cpu_cc_dst); - } - return; case CC_OP_SUB: switch (cond) { case 6: /* neg */ case 14: /* pos */ cmp->cond = (cond == 6 ? TCG_COND_LT : TCG_COND_GE); - goto do_compare_dst_0; + cmp->c2 = tcg_constant_tl(0); + if (TARGET_LONG_BITS == 32 || xcc) { + cmp->c1 = cpu_cc_dst; + } else { + cmp->c1 = t1 = tcg_temp_new(); + tcg_gen_ext32s_tl(t1, cpu_cc_dst); + } + return; case 7: /* overflow */ case 15: /* !overflow */ @@ -3726,6 +3685,8 @@ static bool do_cc_arith(DisasContext *dc, arg_r_r_ri *a, int cc_op, if (cc_op < 0) { dst = gen_dest_gpr(dc, a->rd); + } else if (cc_op == CC_OP_FLAGS) { + dst = cpu_cc_N; } else { dst = cpu_cc_dst; tcg_gen_movi_i32(cpu_cc_op, cc_op); @@ -3742,6 +3703,21 @@ static bool do_cc_arith(DisasContext *dc, arg_r_r_ri *a, int cc_op, } else { func(dst, src1, cpu_regs[a->rs2_or_imm]); } + + /* Logic insn; to be cleaned up later. */ + if (cc_op == CC_OP_FLAGS) { + tcg_gen_movi_tl(cpu_cc_V, 0); + tcg_gen_movi_tl(cpu_icc_C, 0); +#ifdef TARGET_SPARC64 + tcg_gen_movi_tl(cpu_xcc_C, 0); + tcg_gen_mov_tl(cpu_xcc_Z, dst); +#endif + tcg_gen_mov_tl(cpu_icc_Z, dst); + + tcg_gen_movi_i32(cpu_cc_op, CC_OP_FLAGS); + dc->cc_op = CC_OP_FLAGS; + } + gen_store_gpr(dc, a->rd, dst); return advance_pc(dc); } @@ -3764,6 +3740,13 @@ static bool do_flags_arith(DisasContext *dc, arg_r_r_ri *a, int cc_op, return false; } +static bool do_logic_cc(DisasContext *dc, arg_r_r_ri *a, + void (*func)(TCGv, TCGv, TCGv), + void (*funci)(TCGv, TCGv, target_long)) +{ + return do_cc_arith(dc, a, CC_OP_FLAGS, func, funci); +} + static bool trans_OR(DisasContext *dc, arg_r_r_ri *a) { /* For simplicity, we under-decoded the rs2 form. */ @@ -3805,15 +3788,15 @@ TRANS(SDIV, DIV, do_arith, a, gen_op_sdiv, NULL) TRANS(POPC, 64, do_arith, a, gen_op_popc, NULL) TRANS(ADDcc, ALL, do_cc_arith, a, CC_OP_ADD, gen_op_add_cc, NULL) -TRANS(ANDcc, ALL, do_cc_arith, a, CC_OP_LOGIC, tcg_gen_and_tl, tcg_gen_andi_tl) -TRANS(ORcc, ALL, do_cc_arith, a, CC_OP_LOGIC, tcg_gen_or_tl, tcg_gen_ori_tl) -TRANS(XORcc, ALL, do_cc_arith, a, CC_OP_LOGIC, tcg_gen_xor_tl, tcg_gen_xori_tl) +TRANS(ANDcc, ALL, do_logic_cc, a, tcg_gen_and_tl, tcg_gen_andi_tl) +TRANS(ORcc, ALL, do_logic_cc, a, tcg_gen_or_tl, tcg_gen_ori_tl) +TRANS(XORcc, ALL, do_logic_cc, a, tcg_gen_xor_tl, tcg_gen_xori_tl) TRANS(SUBcc, ALL, do_cc_arith, a, CC_OP_SUB, gen_op_sub_cc, NULL) -TRANS(ANDNcc, ALL, do_cc_arith, a, CC_OP_LOGIC, tcg_gen_andc_tl, NULL) -TRANS(ORNcc, ALL, do_cc_arith, a, CC_OP_LOGIC, tcg_gen_orc_tl, NULL) -TRANS(XORNcc, ALL, do_cc_arith, a, CC_OP_LOGIC, tcg_gen_eqv_tl, NULL) -TRANS(UMULcc, MUL, do_cc_arith, a, CC_OP_LOGIC, gen_op_umul, NULL) -TRANS(SMULcc, MUL, do_cc_arith, a, CC_OP_LOGIC, gen_op_smul, NULL) +TRANS(ANDNcc, ALL, do_logic_cc, a, tcg_gen_andc_tl, NULL) +TRANS(ORNcc, ALL, do_logic_cc, a, tcg_gen_orc_tl, NULL) +TRANS(XORNcc, ALL, do_logic_cc, a, tcg_gen_eqv_tl, NULL) +TRANS(UMULcc, MUL, do_logic_cc, a, gen_op_umul, NULL) +TRANS(SMULcc, MUL, do_logic_cc, a, gen_op_smul, NULL) TRANS(UDIVcc, DIV, do_flags_arith, a, CC_OP_FLAGS, gen_op_udivcc) TRANS(SDIVcc, DIV, do_flags_arith, a, CC_OP_FLAGS, gen_op_sdivcc) TRANS(TADDcc, ALL, do_cc_arith, a, CC_OP_TADD, gen_op_add_cc, NULL) -- 2.34.1