BSR/BSF TCG conversion
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4477 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
7c6ce4baed
commit
6191b05901
@ -5240,6 +5240,37 @@ void helper_movq(uint64_t *d, uint64_t *s)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* bit operations */
|
||||||
|
target_ulong helper_bsf(target_ulong t0)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
target_ulong res;
|
||||||
|
|
||||||
|
res = t0;
|
||||||
|
count = 0;
|
||||||
|
while ((res & 1) == 0) {
|
||||||
|
count++;
|
||||||
|
res >>= 1;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
target_ulong helper_bsr(target_ulong t0)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
target_ulong res, mask;
|
||||||
|
|
||||||
|
res = t0;
|
||||||
|
count = TARGET_LONG_BITS - 1;
|
||||||
|
mask = (target_ulong)1 << (TARGET_LONG_BITS - 1);
|
||||||
|
while ((res & mask) == 0) {
|
||||||
|
count--;
|
||||||
|
res <<= 1;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int compute_all_eflags(void)
|
static int compute_all_eflags(void)
|
||||||
{
|
{
|
||||||
return CC_SRC;
|
return CC_SRC;
|
||||||
|
@ -187,6 +187,8 @@ void helper_fsave(target_ulong ptr, int data32);
|
|||||||
void helper_frstor(target_ulong ptr, int data32);
|
void helper_frstor(target_ulong ptr, int data32);
|
||||||
void helper_fxsave(target_ulong ptr, int data64);
|
void helper_fxsave(target_ulong ptr, int data64);
|
||||||
void helper_fxrstor(target_ulong ptr, int data64);
|
void helper_fxrstor(target_ulong ptr, int data64);
|
||||||
|
target_ulong helper_bsf(target_ulong t0);
|
||||||
|
target_ulong helper_bsr(target_ulong t0);
|
||||||
|
|
||||||
/* MMX/SSE */
|
/* MMX/SSE */
|
||||||
|
|
||||||
|
@ -200,51 +200,6 @@ void OPPROTO glue(op_setle_T0_sub, SUFFIX)(void)
|
|||||||
T0 = ((DATA_STYPE)src1 <= (DATA_STYPE)src2);
|
T0 = ((DATA_STYPE)src1 <= (DATA_STYPE)src2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* bit operations */
|
|
||||||
#if DATA_BITS >= 16
|
|
||||||
|
|
||||||
void OPPROTO glue(glue(op_bsf, SUFFIX), _T0_cc)(void)
|
|
||||||
{
|
|
||||||
int count;
|
|
||||||
target_long res;
|
|
||||||
|
|
||||||
res = T0 & DATA_MASK;
|
|
||||||
if (res != 0) {
|
|
||||||
count = 0;
|
|
||||||
while ((res & 1) == 0) {
|
|
||||||
count++;
|
|
||||||
res >>= 1;
|
|
||||||
}
|
|
||||||
T1 = count;
|
|
||||||
CC_DST = 1; /* ZF = 0 */
|
|
||||||
} else {
|
|
||||||
CC_DST = 0; /* ZF = 1 */
|
|
||||||
}
|
|
||||||
FORCE_RET();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OPPROTO glue(glue(op_bsr, SUFFIX), _T0_cc)(void)
|
|
||||||
{
|
|
||||||
int count;
|
|
||||||
target_long res;
|
|
||||||
|
|
||||||
res = T0 & DATA_MASK;
|
|
||||||
if (res != 0) {
|
|
||||||
count = DATA_BITS - 1;
|
|
||||||
while ((res & SIGN_MASK) == 0) {
|
|
||||||
count--;
|
|
||||||
res <<= 1;
|
|
||||||
}
|
|
||||||
T1 = count;
|
|
||||||
CC_DST = 1; /* ZF = 0 */
|
|
||||||
} else {
|
|
||||||
CC_DST = 0; /* ZF = 1 */
|
|
||||||
}
|
|
||||||
FORCE_RET();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* string operations */
|
/* string operations */
|
||||||
|
|
||||||
void OPPROTO glue(op_movl_T0_Dshift, SUFFIX)(void)
|
void OPPROTO glue(op_movl_T0_Dshift, SUFFIX)(void)
|
||||||
|
@ -498,23 +498,6 @@ static GenOpFunc *gen_op_cmov_reg_T1_T0[NB_OP_SIZES - 1][CPU_NB_REGS] = {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static GenOpFunc *gen_op_bsx_T0_cc[3][2] = {
|
|
||||||
[0] = {
|
|
||||||
gen_op_bsfw_T0_cc,
|
|
||||||
gen_op_bsrw_T0_cc,
|
|
||||||
},
|
|
||||||
[1] = {
|
|
||||||
gen_op_bsfl_T0_cc,
|
|
||||||
gen_op_bsrl_T0_cc,
|
|
||||||
},
|
|
||||||
#ifdef TARGET_X86_64
|
|
||||||
[2] = {
|
|
||||||
gen_op_bsfq_T0_cc,
|
|
||||||
gen_op_bsrq_T0_cc,
|
|
||||||
},
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline void gen_op_lds_T0_A0(int idx)
|
static inline void gen_op_lds_T0_A0(int idx)
|
||||||
{
|
{
|
||||||
int mem_index = (idx >> 2) - 1;
|
int mem_index = (idx >> 2) - 1;
|
||||||
@ -5837,16 +5820,27 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
|
|||||||
break;
|
break;
|
||||||
case 0x1bc: /* bsf */
|
case 0x1bc: /* bsf */
|
||||||
case 0x1bd: /* bsr */
|
case 0x1bd: /* bsr */
|
||||||
ot = dflag + OT_WORD;
|
{
|
||||||
modrm = ldub_code(s->pc++);
|
int label1;
|
||||||
reg = ((modrm >> 3) & 7) | rex_r;
|
ot = dflag + OT_WORD;
|
||||||
gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
|
modrm = ldub_code(s->pc++);
|
||||||
/* NOTE: in order to handle the 0 case, we must load the
|
reg = ((modrm >> 3) & 7) | rex_r;
|
||||||
result. It could be optimized with a generated jump */
|
gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
|
||||||
gen_op_mov_TN_reg(ot, 1, reg);
|
gen_extu(ot, cpu_T[0]);
|
||||||
gen_op_bsx_T0_cc[ot - OT_WORD][b & 1]();
|
label1 = gen_new_label();
|
||||||
gen_op_mov_reg_T1(ot, reg);
|
tcg_gen_movi_tl(cpu_cc_dst, 0);
|
||||||
s->cc_op = CC_OP_LOGICB + ot;
|
tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[0], tcg_const_tl(0), label1);
|
||||||
|
if (b & 1) {
|
||||||
|
tcg_gen_helper_1_1(helper_bsr, cpu_T[0], cpu_T[0]);
|
||||||
|
} else {
|
||||||
|
tcg_gen_helper_1_1(helper_bsf, cpu_T[0], cpu_T[0]);
|
||||||
|
}
|
||||||
|
gen_op_mov_reg_T0(ot, reg);
|
||||||
|
tcg_gen_movi_tl(cpu_cc_dst, 1);
|
||||||
|
gen_set_label(label1);
|
||||||
|
tcg_gen_discard_tl(cpu_cc_src);
|
||||||
|
s->cc_op = CC_OP_LOGICB + ot;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
/************************/
|
/************************/
|
||||||
/* bcd */
|
/* bcd */
|
||||||
|
Loading…
Reference in New Issue
Block a user