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,7 +186,7 @@ typedef struct CPUSPARCState { | ||
186 | target_ulong y; /* multiply/divide register */ | 186 | target_ulong y; /* multiply/divide register */ |
187 | 187 | ||
188 | /* emulator internal flags handling */ | 188 | /* emulator internal flags handling */ |
189 | - target_ulong cc_src; | 189 | + target_ulong cc_src, cc_src2; |
190 | target_ulong cc_dst; | 190 | target_ulong cc_dst; |
191 | 191 | ||
192 | uint32_t psr; /* processor state register */ | 192 | uint32_t psr; /* processor state register */ |
target-sparc/op.c
@@ -195,34 +195,6 @@ void OPPROTO op_smul_T1_T0(void) | @@ -195,34 +195,6 @@ void OPPROTO op_smul_T1_T0(void) | ||
195 | env->y = res >> 32; | 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 | void OPPROTO op_udiv_T1_T0(void) | 198 | void OPPROTO op_udiv_T1_T0(void) |
227 | { | 199 | { |
228 | uint64_t x0; | 200 | uint64_t x0; |
target-sparc/translate.c
@@ -46,7 +46,7 @@ | @@ -46,7 +46,7 @@ | ||
46 | according to jump_pc[T2] */ | 46 | according to jump_pc[T2] */ |
47 | 47 | ||
48 | /* global register indexes */ | 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 | static TCGv cpu_psr, cpu_fsr, cpu_gregs[8]; | 50 | static TCGv cpu_psr, cpu_fsr, cpu_gregs[8]; |
51 | #ifdef TARGET_SPARC64 | 51 | #ifdef TARGET_SPARC64 |
52 | static TCGv cpu_xcc; | 52 | static TCGv cpu_xcc; |
@@ -710,6 +710,57 @@ static inline void gen_op_tsub_T1_T0_ccTV(void) | @@ -710,6 +710,57 @@ static inline void gen_op_tsub_T1_T0_ccTV(void) | ||
710 | gen_cc_C_sub(cpu_cc_src, cpu_T[1]); | 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 | #ifdef TARGET_SPARC64 | 764 | #ifdef TARGET_SPARC64 |
714 | static inline void gen_trap_ifdivzero_i64(TCGv divisor) | 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,6 +4678,9 @@ CPUSPARCState *cpu_sparc_init(const char *cpu_model) | ||
4627 | cpu_cc_src = tcg_global_mem_new(TCG_TYPE_TL, | 4678 | cpu_cc_src = tcg_global_mem_new(TCG_TYPE_TL, |
4628 | TCG_AREG0, offsetof(CPUState, cc_src), | 4679 | TCG_AREG0, offsetof(CPUState, cc_src), |
4629 | "cc_src"); | 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 | cpu_cc_dst = tcg_global_mem_new(TCG_TYPE_TL, | 4684 | cpu_cc_dst = tcg_global_mem_new(TCG_TYPE_TL, |
4631 | TCG_AREG0, offsetof(CPUState, cc_dst), | 4685 | TCG_AREG0, offsetof(CPUState, cc_dst), |
4632 | "cc_dst"); | 4686 | "cc_dst"); |