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"); | ... | ... |