Revision 6191b059
b/target-i386/helper.c | ||
---|---|---|
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; |
b/target-i386/helper.h | ||
---|---|---|
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 |
|
b/target-i386/ops_template.h | ||
---|---|---|
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) |
b/target-i386/translate.c | ||
---|---|---|
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 | 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 */ |
Also available in: Unified diff