Commit 6191b05901ef1a85c64383e34406024daa4eda12
1 parent
7c6ce4ba
BSR/BSF TCG conversion
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4477 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
54 additions
and
72 deletions
target-i386/helper.c
| ... | ... | @@ -5240,6 +5240,37 @@ void helper_movq(uint64_t *d, uint64_t *s) |
| 5240 | 5240 | |
| 5241 | 5241 | #endif |
| 5242 | 5242 | |
| 5243 | +/* bit operations */ | |
| 5244 | +target_ulong helper_bsf(target_ulong t0) | |
| 5245 | +{ | |
| 5246 | + int count; | |
| 5247 | + target_ulong res; | |
| 5248 | + | |
| 5249 | + res = t0; | |
| 5250 | + count = 0; | |
| 5251 | + while ((res & 1) == 0) { | |
| 5252 | + count++; | |
| 5253 | + res >>= 1; | |
| 5254 | + } | |
| 5255 | + return count; | |
| 5256 | +} | |
| 5257 | + | |
| 5258 | +target_ulong helper_bsr(target_ulong t0) | |
| 5259 | +{ | |
| 5260 | + int count; | |
| 5261 | + target_ulong res, mask; | |
| 5262 | + | |
| 5263 | + res = t0; | |
| 5264 | + count = TARGET_LONG_BITS - 1; | |
| 5265 | + mask = (target_ulong)1 << (TARGET_LONG_BITS - 1); | |
| 5266 | + while ((res & mask) == 0) { | |
| 5267 | + count--; | |
| 5268 | + res <<= 1; | |
| 5269 | + } | |
| 5270 | + return count; | |
| 5271 | +} | |
| 5272 | + | |
| 5273 | + | |
| 5243 | 5274 | static int compute_all_eflags(void) |
| 5244 | 5275 | { |
| 5245 | 5276 | return CC_SRC; | ... | ... |
target-i386/helper.h
| ... | ... | @@ -187,6 +187,8 @@ void helper_fsave(target_ulong ptr, int data32); |
| 187 | 187 | void helper_frstor(target_ulong ptr, int data32); |
| 188 | 188 | void helper_fxsave(target_ulong ptr, int data64); |
| 189 | 189 | void helper_fxrstor(target_ulong ptr, int data64); |
| 190 | +target_ulong helper_bsf(target_ulong t0); | |
| 191 | +target_ulong helper_bsr(target_ulong t0); | |
| 190 | 192 | |
| 191 | 193 | /* MMX/SSE */ |
| 192 | 194 | ... | ... |
target-i386/ops_template.h
| ... | ... | @@ -200,51 +200,6 @@ void OPPROTO glue(op_setle_T0_sub, SUFFIX)(void) |
| 200 | 200 | T0 = ((DATA_STYPE)src1 <= (DATA_STYPE)src2); |
| 201 | 201 | } |
| 202 | 202 | |
| 203 | -/* bit operations */ | |
| 204 | -#if DATA_BITS >= 16 | |
| 205 | - | |
| 206 | -void OPPROTO glue(glue(op_bsf, SUFFIX), _T0_cc)(void) | |
| 207 | -{ | |
| 208 | - int count; | |
| 209 | - target_long res; | |
| 210 | - | |
| 211 | - res = T0 & DATA_MASK; | |
| 212 | - if (res != 0) { | |
| 213 | - count = 0; | |
| 214 | - while ((res & 1) == 0) { | |
| 215 | - count++; | |
| 216 | - res >>= 1; | |
| 217 | - } | |
| 218 | - T1 = count; | |
| 219 | - CC_DST = 1; /* ZF = 0 */ | |
| 220 | - } else { | |
| 221 | - CC_DST = 0; /* ZF = 1 */ | |
| 222 | - } | |
| 223 | - FORCE_RET(); | |
| 224 | -} | |
| 225 | - | |
| 226 | -void OPPROTO glue(glue(op_bsr, SUFFIX), _T0_cc)(void) | |
| 227 | -{ | |
| 228 | - int count; | |
| 229 | - target_long res; | |
| 230 | - | |
| 231 | - res = T0 & DATA_MASK; | |
| 232 | - if (res != 0) { | |
| 233 | - count = DATA_BITS - 1; | |
| 234 | - while ((res & SIGN_MASK) == 0) { | |
| 235 | - count--; | |
| 236 | - res <<= 1; | |
| 237 | - } | |
| 238 | - T1 = count; | |
| 239 | - CC_DST = 1; /* ZF = 0 */ | |
| 240 | - } else { | |
| 241 | - CC_DST = 0; /* ZF = 1 */ | |
| 242 | - } | |
| 243 | - FORCE_RET(); | |
| 244 | -} | |
| 245 | - | |
| 246 | -#endif | |
| 247 | - | |
| 248 | 203 | /* string operations */ |
| 249 | 204 | |
| 250 | 205 | void OPPROTO glue(op_movl_T0_Dshift, SUFFIX)(void) | ... | ... |
target-i386/translate.c
| ... | ... | @@ -498,23 +498,6 @@ static GenOpFunc *gen_op_cmov_reg_T1_T0[NB_OP_SIZES - 1][CPU_NB_REGS] = { |
| 498 | 498 | #endif |
| 499 | 499 | }; |
| 500 | 500 | |
| 501 | -static GenOpFunc *gen_op_bsx_T0_cc[3][2] = { | |
| 502 | - [0] = { | |
| 503 | - gen_op_bsfw_T0_cc, | |
| 504 | - gen_op_bsrw_T0_cc, | |
| 505 | - }, | |
| 506 | - [1] = { | |
| 507 | - gen_op_bsfl_T0_cc, | |
| 508 | - gen_op_bsrl_T0_cc, | |
| 509 | - }, | |
| 510 | -#ifdef TARGET_X86_64 | |
| 511 | - [2] = { | |
| 512 | - gen_op_bsfq_T0_cc, | |
| 513 | - gen_op_bsrq_T0_cc, | |
| 514 | - }, | |
| 515 | -#endif | |
| 516 | -}; | |
| 517 | - | |
| 518 | 501 | static inline void gen_op_lds_T0_A0(int idx) |
| 519 | 502 | { |
| 520 | 503 | int mem_index = (idx >> 2) - 1; |
| ... | ... | @@ -5837,16 +5820,27 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
| 5837 | 5820 | break; |
| 5838 | 5821 | case 0x1bc: /* bsf */ |
| 5839 | 5822 | case 0x1bd: /* bsr */ |
| 5840 | - ot = dflag + OT_WORD; | |
| 5841 | - modrm = ldub_code(s->pc++); | |
| 5842 | - reg = ((modrm >> 3) & 7) | rex_r; | |
| 5843 | - gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0); | |
| 5844 | - /* NOTE: in order to handle the 0 case, we must load the | |
| 5845 | - result. It could be optimized with a generated jump */ | |
| 5846 | - gen_op_mov_TN_reg(ot, 1, reg); | |
| 5847 | - gen_op_bsx_T0_cc[ot - OT_WORD][b & 1](); | |
| 5848 | - gen_op_mov_reg_T1(ot, reg); | |
| 5849 | - s->cc_op = CC_OP_LOGICB + ot; | |
| 5823 | + { | |
| 5824 | + int label1; | |
| 5825 | + ot = dflag + OT_WORD; | |
| 5826 | + modrm = ldub_code(s->pc++); | |
| 5827 | + reg = ((modrm >> 3) & 7) | rex_r; | |
| 5828 | + gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0); | |
| 5829 | + gen_extu(ot, cpu_T[0]); | |
| 5830 | + label1 = gen_new_label(); | |
| 5831 | + tcg_gen_movi_tl(cpu_cc_dst, 0); | |
| 5832 | + tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[0], tcg_const_tl(0), label1); | |
| 5833 | + if (b & 1) { | |
| 5834 | + tcg_gen_helper_1_1(helper_bsr, cpu_T[0], cpu_T[0]); | |
| 5835 | + } else { | |
| 5836 | + tcg_gen_helper_1_1(helper_bsf, cpu_T[0], cpu_T[0]); | |
| 5837 | + } | |
| 5838 | + gen_op_mov_reg_T0(ot, reg); | |
| 5839 | + tcg_gen_movi_tl(cpu_cc_dst, 1); | |
| 5840 | + gen_set_label(label1); | |
| 5841 | + tcg_gen_discard_tl(cpu_cc_src); | |
| 5842 | + s->cc_op = CC_OP_LOGICB + ot; | |
| 5843 | + } | |
| 5850 | 5844 | break; |
| 5851 | 5845 | /************************/ |
| 5852 | 5846 | /* bcd */ | ... | ... |