Commit d9bdab86e83c1a8e1ed12fad67e76a2459a9e305
1 parent
c4071c90
Convert mulscc to TCG, add cc_src2
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4075 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
56 additions
and
30 deletions
target-sparc/cpu.h
| ... | ... | @@ -186,7 +186,7 @@ typedef struct CPUSPARCState { |
| 186 | 186 | target_ulong y; /* multiply/divide register */ |
| 187 | 187 | |
| 188 | 188 | /* emulator internal flags handling */ |
| 189 | - target_ulong cc_src; | |
| 189 | + target_ulong cc_src, cc_src2; | |
| 190 | 190 | target_ulong cc_dst; |
| 191 | 191 | |
| 192 | 192 | uint32_t psr; /* processor state register */ | ... | ... |
target-sparc/op.c
| ... | ... | @@ -195,34 +195,6 @@ void OPPROTO op_smul_T1_T0(void) |
| 195 | 195 | env->y = res >> 32; |
| 196 | 196 | } |
| 197 | 197 | |
| 198 | -void OPPROTO op_mulscc_T1_T0(void) | |
| 199 | -{ | |
| 200 | - unsigned int b1, N, V, b2; | |
| 201 | - target_ulong src1; | |
| 202 | - | |
| 203 | - N = FLAG_SET(PSR_NEG); | |
| 204 | - V = FLAG_SET(PSR_OVF); | |
| 205 | - b1 = N ^ V; | |
| 206 | - b2 = T0 & 1; | |
| 207 | - T0 = (b1 << 31) | (T0 >> 1); | |
| 208 | - if (!(env->y & 1)) | |
| 209 | - T1 = 0; | |
| 210 | - /* do addition and update flags */ | |
| 211 | - src1 = T0; | |
| 212 | - T0 += T1; | |
| 213 | - env->psr = 0; | |
| 214 | - if (!T0) | |
| 215 | - env->psr |= PSR_ZERO; | |
| 216 | - if ((int32_t) T0 < 0) | |
| 217 | - env->psr |= PSR_NEG; | |
| 218 | - if (T0 < src1) | |
| 219 | - env->psr |= PSR_CARRY; | |
| 220 | - if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31)) | |
| 221 | - env->psr |= PSR_OVF; | |
| 222 | - env->y = (b2 << 31) | (env->y >> 1); | |
| 223 | - FORCE_RET(); | |
| 224 | -} | |
| 225 | - | |
| 226 | 198 | void OPPROTO op_udiv_T1_T0(void) |
| 227 | 199 | { |
| 228 | 200 | uint64_t x0; | ... | ... |
target-sparc/translate.c
| ... | ... | @@ -46,7 +46,7 @@ |
| 46 | 46 | according to jump_pc[T2] */ |
| 47 | 47 | |
| 48 | 48 | /* global register indexes */ |
| 49 | -static TCGv cpu_env, cpu_T[3], cpu_regwptr, cpu_cc_src, cpu_cc_dst; | |
| 49 | +static TCGv cpu_env, cpu_T[3], cpu_regwptr, cpu_cc_src, cpu_cc_src2, cpu_cc_dst; | |
| 50 | 50 | static TCGv cpu_psr, cpu_fsr, cpu_gregs[8]; |
| 51 | 51 | #ifdef TARGET_SPARC64 |
| 52 | 52 | static TCGv cpu_xcc; |
| ... | ... | @@ -710,6 +710,57 @@ static inline void gen_op_tsub_T1_T0_ccTV(void) |
| 710 | 710 | gen_cc_C_sub(cpu_cc_src, cpu_T[1]); |
| 711 | 711 | } |
| 712 | 712 | |
| 713 | +static inline void gen_op_mulscc_T1_T0(void) | |
| 714 | +{ | |
| 715 | + TCGv r_temp; | |
| 716 | + int l1, l2; | |
| 717 | + | |
| 718 | + l1 = gen_new_label(); | |
| 719 | + l2 = gen_new_label(); | |
| 720 | + r_temp = tcg_temp_new(TCG_TYPE_TL); | |
| 721 | + | |
| 722 | + /* old op: | |
| 723 | + if (!(env->y & 1)) | |
| 724 | + T1 = 0; | |
| 725 | + */ | |
| 726 | + tcg_gen_ld_i32(r_temp, cpu_env, offsetof(CPUSPARCState, y)); | |
| 727 | + tcg_gen_andi_i32(r_temp, r_temp, 0x1); | |
| 728 | + tcg_gen_brcond_i32(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1); | |
| 729 | + tcg_gen_mov_tl(cpu_cc_src2, cpu_T[1]); | |
| 730 | + gen_op_jmp_label(l2); | |
| 731 | + gen_set_label(l1); | |
| 732 | + tcg_gen_movi_tl(cpu_cc_src2, 0); | |
| 733 | + gen_set_label(l2); | |
| 734 | + | |
| 735 | + // b2 = T0 & 1; | |
| 736 | + // env->y = (b2 << 31) | (env->y >> 1); | |
| 737 | + tcg_gen_shli_i32(r_temp, cpu_T[0], 31); | |
| 738 | + tcg_gen_ld_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, y)); | |
| 739 | + tcg_gen_shri_i32(cpu_tmp0, cpu_tmp0, 1); | |
| 740 | + tcg_gen_or_i32(cpu_tmp0, cpu_tmp0, r_temp); | |
| 741 | + tcg_gen_st_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, y)); | |
| 742 | + | |
| 743 | + // b1 = N ^ V; | |
| 744 | + gen_mov_reg_N(cpu_tmp0, cpu_psr); | |
| 745 | + gen_mov_reg_V(r_temp, cpu_psr); | |
| 746 | + tcg_gen_xor_tl(cpu_tmp0, cpu_tmp0, r_temp); | |
| 747 | + | |
| 748 | + // T0 = (b1 << 31) | (T0 >> 1); | |
| 749 | + // src1 = T0; | |
| 750 | + tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, 31); | |
| 751 | + tcg_gen_shri_tl(cpu_cc_src, cpu_T[0], 1); | |
| 752 | + tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0); | |
| 753 | + | |
| 754 | + /* do addition and update flags */ | |
| 755 | + tcg_gen_add_tl(cpu_T[0], cpu_cc_src, cpu_cc_src2); | |
| 756 | + tcg_gen_discard_tl(r_temp); | |
| 757 | + | |
| 758 | + gen_cc_clear(); | |
| 759 | + gen_cc_NZ(cpu_T[0]); | |
| 760 | + gen_cc_V_add(cpu_T[0], cpu_cc_src, cpu_cc_src2); | |
| 761 | + gen_cc_C_add(cpu_T[0], cpu_cc_src); | |
| 762 | +} | |
| 763 | + | |
| 713 | 764 | #ifdef TARGET_SPARC64 |
| 714 | 765 | static inline void gen_trap_ifdivzero_i64(TCGv divisor) |
| 715 | 766 | { |
| ... | ... | @@ -4627,6 +4678,9 @@ CPUSPARCState *cpu_sparc_init(const char *cpu_model) |
| 4627 | 4678 | cpu_cc_src = tcg_global_mem_new(TCG_TYPE_TL, |
| 4628 | 4679 | TCG_AREG0, offsetof(CPUState, cc_src), |
| 4629 | 4680 | "cc_src"); |
| 4681 | + cpu_cc_src2 = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0, | |
| 4682 | + offsetof(CPUState, cc_src2), | |
| 4683 | + "cc_src2"); | |
| 4630 | 4684 | cpu_cc_dst = tcg_global_mem_new(TCG_TYPE_TL, |
| 4631 | 4685 | TCG_AREG0, offsetof(CPUState, cc_dst), |
| 4632 | 4686 | "cc_dst"); | ... | ... |