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 */
|