Revision f484d386 target-i386/translate.c
b/target-i386/translate.c | ||
---|---|---|
498 | 498 |
#endif |
499 | 499 |
}; |
500 | 500 |
|
501 |
static GenOpFunc *gen_op_btx_T0_T1_cc[3][4] = { |
|
502 |
[0] = { |
|
503 |
gen_op_btw_T0_T1_cc, |
|
504 |
gen_op_btsw_T0_T1_cc, |
|
505 |
gen_op_btrw_T0_T1_cc, |
|
506 |
gen_op_btcw_T0_T1_cc, |
|
507 |
}, |
|
508 |
[1] = { |
|
509 |
gen_op_btl_T0_T1_cc, |
|
510 |
gen_op_btsl_T0_T1_cc, |
|
511 |
gen_op_btrl_T0_T1_cc, |
|
512 |
gen_op_btcl_T0_T1_cc, |
|
513 |
}, |
|
514 |
#ifdef TARGET_X86_64 |
|
515 |
[2] = { |
|
516 |
gen_op_btq_T0_T1_cc, |
|
517 |
gen_op_btsq_T0_T1_cc, |
|
518 |
gen_op_btrq_T0_T1_cc, |
|
519 |
gen_op_btcq_T0_T1_cc, |
|
520 |
}, |
|
521 |
#endif |
|
522 |
}; |
|
523 |
|
|
524 |
static GenOpFunc *gen_op_add_bit_A0_T1[3] = { |
|
525 |
gen_op_add_bitw_A0_T1, |
|
526 |
gen_op_add_bitl_A0_T1, |
|
527 |
X86_64_ONLY(gen_op_add_bitq_A0_T1), |
|
528 |
}; |
|
529 |
|
|
530 | 501 |
static GenOpFunc *gen_op_bsx_T0_cc[3][2] = { |
531 | 502 |
[0] = { |
532 | 503 |
gen_op_bsfw_T0_cc, |
... | ... | |
1379 | 1350 |
} |
1380 | 1351 |
} |
1381 | 1352 |
|
1353 |
static void gen_exts(int ot, TCGv reg) |
|
1354 |
{ |
|
1355 |
switch(ot) { |
|
1356 |
case OT_BYTE: |
|
1357 |
tcg_gen_ext8s_tl(reg, reg); |
|
1358 |
break; |
|
1359 |
case OT_WORD: |
|
1360 |
tcg_gen_ext16s_tl(reg, reg); |
|
1361 |
break; |
|
1362 |
case OT_LONG: |
|
1363 |
tcg_gen_ext32s_tl(reg, reg); |
|
1364 |
break; |
|
1365 |
default: |
|
1366 |
break; |
|
1367 |
} |
|
1368 |
} |
|
1369 |
|
|
1382 | 1370 |
/* XXX: add faster immediate case */ |
1383 | 1371 |
static void gen_shift_rm_T1(DisasContext *s, int ot, int op1, |
1384 | 1372 |
int is_right, int is_arith) |
... | ... | |
1403 | 1391 |
|
1404 | 1392 |
if (is_right) { |
1405 | 1393 |
if (is_arith) { |
1406 |
switch(ot) { |
|
1407 |
case OT_BYTE: |
|
1408 |
tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]); |
|
1409 |
break; |
|
1410 |
case OT_WORD: |
|
1411 |
tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]); |
|
1412 |
break; |
|
1413 |
case OT_LONG: |
|
1414 |
tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]); |
|
1415 |
break; |
|
1416 |
default: |
|
1417 |
break; |
|
1418 |
} |
|
1394 |
gen_exts(ot, cpu_T[0]); |
|
1419 | 1395 |
tcg_gen_sar_tl(cpu_T3, cpu_T[0], cpu_tmp5); |
1420 | 1396 |
tcg_gen_sar_tl(cpu_T[0], cpu_T[0], cpu_T[1]); |
1421 | 1397 |
} else { |
... | ... | |
5791 | 5767 |
if (op < 4) |
5792 | 5768 |
goto illegal_op; |
5793 | 5769 |
op -= 4; |
5794 |
gen_op_btx_T0_T1_cc[ot - OT_WORD][op](); |
|
5795 |
s->cc_op = CC_OP_SARB + ot; |
|
5796 |
if (op != 0) { |
|
5797 |
if (mod != 3) |
|
5798 |
gen_op_st_T0_A0(ot + s->mem_index); |
|
5799 |
else |
|
5800 |
gen_op_mov_reg_T0(ot, rm); |
|
5801 |
gen_op_update_bt_cc(); |
|
5802 |
} |
|
5803 |
break; |
|
5770 |
goto bt_op; |
|
5804 | 5771 |
case 0x1a3: /* bt Gv, Ev */ |
5805 | 5772 |
op = 0; |
5806 | 5773 |
goto do_btx; |
... | ... | |
5822 | 5789 |
if (mod != 3) { |
5823 | 5790 |
gen_lea_modrm(s, modrm, ®_addr, &offset_addr); |
5824 | 5791 |
/* specific case: we need to add a displacement */ |
5825 |
gen_op_add_bit_A0_T1[ot - OT_WORD](); |
|
5792 |
gen_exts(ot, cpu_T[1]); |
|
5793 |
tcg_gen_sari_tl(cpu_tmp0, cpu_T[1], 3 + ot); |
|
5794 |
tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, ot); |
|
5795 |
tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0); |
|
5826 | 5796 |
gen_op_ld_T0_A0(ot + s->mem_index); |
5827 | 5797 |
} else { |
5828 | 5798 |
gen_op_mov_TN_reg(ot, 0, rm); |
5829 | 5799 |
} |
5830 |
gen_op_btx_T0_T1_cc[ot - OT_WORD][op](); |
|
5800 |
bt_op: |
|
5801 |
tcg_gen_andi_tl(cpu_T[1], cpu_T[1], (1 << (3 + ot)) - 1); |
|
5802 |
switch(op) { |
|
5803 |
case 0: |
|
5804 |
tcg_gen_shr_tl(cpu_cc_src, cpu_T[0], cpu_T[1]); |
|
5805 |
tcg_gen_movi_tl(cpu_cc_dst, 0); |
|
5806 |
break; |
|
5807 |
case 1: |
|
5808 |
tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]); |
|
5809 |
tcg_gen_movi_tl(cpu_tmp0, 1); |
|
5810 |
tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]); |
|
5811 |
tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_tmp0); |
|
5812 |
break; |
|
5813 |
case 2: |
|
5814 |
tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]); |
|
5815 |
tcg_gen_movi_tl(cpu_tmp0, 1); |
|
5816 |
tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]); |
|
5817 |
tcg_gen_not_tl(cpu_tmp0, cpu_tmp0); |
|
5818 |
tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_tmp0); |
|
5819 |
break; |
|
5820 |
default: |
|
5821 |
case 3: |
|
5822 |
tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]); |
|
5823 |
tcg_gen_movi_tl(cpu_tmp0, 1); |
|
5824 |
tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]); |
|
5825 |
tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_tmp0); |
|
5826 |
break; |
|
5827 |
} |
|
5831 | 5828 |
s->cc_op = CC_OP_SARB + ot; |
5832 | 5829 |
if (op != 0) { |
5833 | 5830 |
if (mod != 3) |
5834 | 5831 |
gen_op_st_T0_A0(ot + s->mem_index); |
5835 | 5832 |
else |
5836 | 5833 |
gen_op_mov_reg_T0(ot, rm); |
5837 |
gen_op_update_bt_cc(); |
|
5834 |
tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4); |
|
5835 |
tcg_gen_movi_tl(cpu_cc_dst, 0); |
|
5838 | 5836 |
} |
5839 | 5837 |
break; |
5840 | 5838 |
case 0x1bc: /* bsf */ |
Also available in: Unified diff