diff options
-rw-r--r-- | target-sparc/op_helper.c | 77 | ||||
-rw-r--r-- | target-sparc/translate.c | 137 |
2 files changed, 85 insertions, 129 deletions
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c index 0df6bb045a..ddfe152000 100644 --- a/target-sparc/op_helper.c +++ b/target-sparc/op_helper.c @@ -902,6 +902,45 @@ static uint32_t compute_C_addx_xcc(void) } #endif +static inline uint32_t get_V_tag_icc(target_ulong src1, target_ulong src2) +{ + uint32_t ret = 0; + + if ((src1 | src2) & 0x3) + ret |= PSR_OVF; + return ret; +} + +static uint32_t compute_all_tadd(void) +{ + uint32_t ret; + + ret = get_NZ_icc(CC_DST); + ret |= get_C_add_icc(CC_DST, CC_SRC); + ret |= get_V_add_icc(CC_DST, CC_SRC, CC_SRC2); + ret |= get_V_tag_icc(CC_SRC, CC_SRC2); + return ret; +} + +static uint32_t compute_C_tadd(void) +{ + return get_C_add_icc(CC_DST, CC_SRC); +} + +static uint32_t compute_all_taddtv(void) +{ + uint32_t ret; + + ret = get_NZ_icc(CC_DST); + ret |= get_C_add_icc(CC_DST, CC_SRC); + return ret; +} + +static uint32_t compute_C_taddtv(void) +{ + return get_C_add_icc(CC_DST, CC_SRC); +} + static inline uint32_t get_C_sub_icc(target_ulong src1, target_ulong src2) { uint32_t ret = 0; @@ -1014,6 +1053,36 @@ static uint32_t compute_C_subx_xcc(void) } #endif +static uint32_t compute_all_tsub(void) +{ + uint32_t ret; + + ret = get_NZ_icc(CC_DST); + ret |= get_C_sub_icc(CC_DST, CC_SRC); + ret |= get_V_sub_icc(CC_DST, CC_SRC, CC_SRC2); + ret |= get_V_tag_icc(CC_SRC, CC_SRC2); + return ret; +} + +static uint32_t compute_C_tsub(void) +{ + return get_C_sub_icc(CC_DST, CC_SRC); +} + +static uint32_t compute_all_tsubtv(void) +{ + uint32_t ret; + + ret = get_NZ_icc(CC_DST); + ret |= get_C_sub_icc(CC_DST, CC_SRC); + return ret; +} + +static uint32_t compute_C_tsubtv(void) +{ + return get_C_sub_icc(CC_DST, CC_SRC); +} + static uint32_t compute_all_logic(void) { return get_NZ_icc(CC_DST); @@ -1041,8 +1110,12 @@ static const CCTable icc_table[CC_OP_NB] = { [CC_OP_FLAGS] = { compute_all_flags, compute_C_flags }, [CC_OP_ADD] = { compute_all_add, compute_C_add }, [CC_OP_ADDX] = { compute_all_addx, compute_C_addx }, + [CC_OP_TADD] = { compute_all_tadd, compute_C_tadd }, + [CC_OP_TADDTV] = { compute_all_taddtv, compute_C_taddtv }, [CC_OP_SUB] = { compute_all_sub, compute_C_sub }, [CC_OP_SUBX] = { compute_all_subx, compute_C_subx }, + [CC_OP_TSUB] = { compute_all_tsub, compute_C_tsub }, + [CC_OP_TSUBTV] = { compute_all_tsubtv, compute_C_tsubtv }, [CC_OP_LOGIC] = { compute_all_logic, compute_C_logic }, }; @@ -1052,8 +1125,12 @@ static const CCTable xcc_table[CC_OP_NB] = { [CC_OP_FLAGS] = { compute_all_flags_xcc, compute_C_flags_xcc }, [CC_OP_ADD] = { compute_all_add_xcc, compute_C_add_xcc }, [CC_OP_ADDX] = { compute_all_addx_xcc, compute_C_addx_xcc }, + [CC_OP_TADD] = { compute_all_add_xcc, compute_C_add_xcc }, + [CC_OP_TADDTV] = { compute_all_add_xcc, compute_C_add_xcc }, [CC_OP_SUB] = { compute_all_sub_xcc, compute_C_sub_xcc }, [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 f4d3fbed57..91ff604495 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -420,18 +420,6 @@ static inline void gen_add_tv(TCGv dst, TCGv src1, TCGv src2) tcg_temp_free(r_temp); } -static inline void gen_cc_V_tag(TCGv src1, TCGv src2) -{ - int l1; - - l1 = gen_new_label(); - tcg_gen_or_tl(cpu_tmp0, src1, src2); - tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3); - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1); - tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF); - gen_set_label(l1); -} - static inline void gen_tag_tv(TCGv src1, TCGv src2) { int l1; @@ -488,17 +476,6 @@ static inline void gen_op_tadd_cc(TCGv dst, TCGv src1, TCGv src2) tcg_gen_mov_tl(cpu_cc_src, src1); tcg_gen_mov_tl(cpu_cc_src2, src2); tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); - gen_cc_clear_icc(); - gen_cc_NZ_icc(cpu_cc_dst); - gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src); - gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); - gen_cc_V_tag(cpu_cc_src, cpu_cc_src2); -#ifdef TARGET_SPARC64 - gen_cc_clear_xcc(); - gen_cc_NZ_xcc(cpu_cc_dst); - gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src); - gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); -#endif tcg_gen_mov_tl(dst, cpu_cc_dst); } @@ -509,87 +486,9 @@ static inline void gen_op_tadd_ccTV(TCGv dst, TCGv src1, TCGv src2) gen_tag_tv(cpu_cc_src, cpu_cc_src2); tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); gen_add_tv(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); - gen_cc_clear_icc(); - gen_cc_NZ_icc(cpu_cc_dst); - gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src); -#ifdef TARGET_SPARC64 - gen_cc_clear_xcc(); - gen_cc_NZ_xcc(cpu_cc_dst); - gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src); - gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); -#endif tcg_gen_mov_tl(dst, cpu_cc_dst); } -/* old op: - if (src1 < T1) - env->psr |= PSR_CARRY; -*/ -static inline void gen_cc_C_sub_icc(TCGv src1, TCGv src2) -{ - TCGv r_temp1, r_temp2; - int l1; - - l1 = gen_new_label(); - r_temp1 = tcg_temp_new(); - r_temp2 = tcg_temp_new(); - tcg_gen_andi_tl(r_temp1, src1, 0xffffffffULL); - tcg_gen_andi_tl(r_temp2, src2, 0xffffffffULL); - tcg_gen_brcond_tl(TCG_COND_GEU, r_temp1, r_temp2, l1); - tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY); - gen_set_label(l1); - tcg_temp_free(r_temp1); - tcg_temp_free(r_temp2); -} - -#ifdef TARGET_SPARC64 -static inline void gen_cc_C_sub_xcc(TCGv src1, TCGv src2) -{ - int l1; - - l1 = gen_new_label(); - tcg_gen_brcond_tl(TCG_COND_GEU, src1, src2, l1); - tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_CARRY); - gen_set_label(l1); -} -#endif - -/* old op: - if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31)) - env->psr |= PSR_OVF; -*/ -static inline void gen_cc_V_sub_icc(TCGv dst, TCGv src1, TCGv src2) -{ - TCGv r_temp; - - r_temp = tcg_temp_new(); - tcg_gen_xor_tl(r_temp, src1, src2); - tcg_gen_xor_tl(cpu_tmp0, src1, dst); - tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0); - tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31)); - tcg_gen_shri_tl(r_temp, r_temp, 31 - PSR_OVF_SHIFT); - tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp); - tcg_gen_or_i32(cpu_psr, cpu_psr, cpu_tmp32); - tcg_temp_free(r_temp); -} - -#ifdef TARGET_SPARC64 -static inline void gen_cc_V_sub_xcc(TCGv dst, TCGv src1, TCGv src2) -{ - TCGv r_temp; - - r_temp = tcg_temp_new(); - tcg_gen_xor_tl(r_temp, src1, src2); - tcg_gen_xor_tl(cpu_tmp0, src1, dst); - tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0); - tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63)); - tcg_gen_shri_tl(r_temp, r_temp, 63 - PSR_OVF_SHIFT); - tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp); - tcg_gen_or_i32(cpu_xcc, cpu_xcc, cpu_tmp32); - tcg_temp_free(r_temp); -} -#endif - static inline void gen_sub_tv(TCGv dst, TCGv src1, TCGv src2) { TCGv r_temp; @@ -660,17 +559,6 @@ static inline void gen_op_tsub_cc(TCGv dst, TCGv src1, TCGv src2) tcg_gen_mov_tl(cpu_cc_src, src1); tcg_gen_mov_tl(cpu_cc_src2, src2); tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); - gen_cc_clear_icc(); - gen_cc_NZ_icc(cpu_cc_dst); - gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2); - gen_cc_V_sub_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); - gen_cc_V_tag(cpu_cc_src, cpu_cc_src2); -#ifdef TARGET_SPARC64 - gen_cc_clear_xcc(); - gen_cc_NZ_xcc(cpu_cc_dst); - gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2); - gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); -#endif tcg_gen_mov_tl(dst, cpu_cc_dst); } @@ -681,15 +569,6 @@ static inline void gen_op_tsub_ccTV(TCGv dst, TCGv src1, TCGv src2) gen_tag_tv(cpu_cc_src, cpu_cc_src2); tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); gen_sub_tv(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); - gen_cc_clear_icc(); - gen_cc_NZ_icc(cpu_cc_dst); - gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2); -#ifdef TARGET_SPARC64 - gen_cc_clear_xcc(); - gen_cc_NZ_xcc(cpu_cc_dst); - gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2); - gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2); -#endif tcg_gen_mov_tl(dst, cpu_cc_dst); } @@ -3297,28 +3176,28 @@ static void disas_sparc_insn(DisasContext * dc) case 0x20: /* taddcc */ gen_op_tadd_cc(cpu_dst, cpu_src1, cpu_src2); gen_movl_TN_reg(rd, cpu_dst); - tcg_gen_movi_i32(cpu_cc_op, CC_OP_FLAGS); - dc->cc_op = CC_OP_FLAGS; + tcg_gen_movi_i32(cpu_cc_op, CC_OP_TADD); + dc->cc_op = CC_OP_TADD; break; case 0x21: /* tsubcc */ gen_op_tsub_cc(cpu_dst, cpu_src1, cpu_src2); gen_movl_TN_reg(rd, cpu_dst); - tcg_gen_movi_i32(cpu_cc_op, CC_OP_FLAGS); - dc->cc_op = CC_OP_FLAGS; + tcg_gen_movi_i32(cpu_cc_op, CC_OP_TSUB); + dc->cc_op = CC_OP_TSUB; break; case 0x22: /* taddcctv */ save_state(dc, cpu_cond); gen_op_tadd_ccTV(cpu_dst, cpu_src1, cpu_src2); gen_movl_TN_reg(rd, cpu_dst); - tcg_gen_movi_i32(cpu_cc_op, CC_OP_FLAGS); - dc->cc_op = CC_OP_FLAGS; + tcg_gen_movi_i32(cpu_cc_op, CC_OP_TADDTV); + dc->cc_op = CC_OP_TADDTV; break; case 0x23: /* tsubcctv */ save_state(dc, cpu_cond); gen_op_tsub_ccTV(cpu_dst, cpu_src1, cpu_src2); gen_movl_TN_reg(rd, cpu_dst); - tcg_gen_movi_i32(cpu_cc_op, CC_OP_FLAGS); - dc->cc_op = CC_OP_FLAGS; + tcg_gen_movi_i32(cpu_cc_op, CC_OP_TSUBTV); + dc->cc_op = CC_OP_TSUBTV; break; case 0x24: /* mulscc */ gen_helper_compute_psr(); |