Lines Matching full:s

68 static void gen_JMP_m(DisasContext *s, X86DecodedInsn *decode);
69 static void gen_JMP(DisasContext *s, X86DecodedInsn *decode);
76 static void gen_NM_exception(DisasContext *s)
78 gen_exception(s, EXCP07_PREX);
81 static void gen_lea_modrm(DisasContext *s, X86DecodedInsn *decode)
86 ea = gen_lea_modrm_1(s, *mem, decode->e.vex_class == 12);
97 tcg_gen_add_tl(s->A0, ea, ofs);
98 ea = s->A0;
101 gen_lea_v_seg(s, ea, mem->def_seg, s->override);
208 static void gen_load_sse(DisasContext *s, TCGv temp, MemOp ot, int dest_ofs, bool aligned)
212 gen_op_ld_v(s, MO_8, temp, s->A0);
216 gen_op_ld_v(s, MO_16, temp, s->A0);
220 gen_op_ld_v(s, MO_32, temp, s->A0);
224 gen_ldq_env_A0(s, dest_ofs);
227 gen_ldo_env_A0(s, dest_ofs, aligned);
230 gen_ldy_env_A0(s, dest_ofs, aligned);
237 static bool sse_needs_alignment(DisasContext *s, X86DecodedInsn *decode, MemOp ot)
242 if ((s->prefix & PREFIX_VEX) ||
256 static void gen_load(DisasContext *s, X86DecodedInsn *decode, int opn, TCGv v)
270 translator_io_start(&s->base);
283 if (v == s->T0 && decode->e.special == X86_SPECIAL_SExtT0) {
284 gen_op_ld_v(s, op->ot | MO_SIGN, v, s->A0);
286 gen_op_ld_v(s, op->ot, v, s->A0);
289 } else if (op->ot == MO_8 && byte_reg_is_xH(s, op->n)) {
290 if (v == s->T0 && decode->e.special == X86_SPECIAL_SExtT0) {
296 } else if (op->ot < MO_TL && v == s->T0 &&
321 bool aligned = sse_needs_alignment(s, decode, op->ot);
322 gen_load_sse(s, v, op->ot, op->offset, aligned);
350 static void gen_writeback(DisasContext *s, X86DecodedInsn *decode, int opn, TCGv v)
358 gen_movl_seg(s, op->n, s->T0);
362 gen_op_st_v(s, op->ot, v, s->A0);
364 gen_op_mov_reg_v(s, op->ot, op->n, v);
370 if (!op->has_ea && (s->prefix & PREFIX_VEX) && op->ot <= MO_128) {
379 translator_io_start(&s->base);
382 s->base.is_jmp = DISAS_EOB_NEXT;
387 s->base.is_jmp = DISAS_EOB_NEXT;
396 static inline int vector_len(DisasContext *s, X86DecodedInsn *decode)
399 !(s->prefix & (PREFIX_DATA | PREFIX_REPZ | PREFIX_REPNZ))) {
402 return s->vex_l ? 32 : 16;
405 static void prepare_update1_cc(X86DecodedInsn *decode, DisasContext *s, CCOp op)
407 decode->cc_dst = s->T0;
411 static void prepare_update2_cc(X86DecodedInsn *decode, DisasContext *s, CCOp op)
413 decode->cc_src = s->T1;
414 decode->cc_dst = s->T0;
418 static void prepare_update_cc_incdec(X86DecodedInsn *decode, DisasContext *s, CCOp op)
420 gen_compute_eflags_c(s, s->T1);
421 prepare_update2_cc(decode, s, op);
424 static void prepare_update3_cc(X86DecodedInsn *decode, DisasContext *s, CCOp op, TCGv reg)
427 decode->cc_src = s->T1;
428 decode->cc_dst = s->T0;
433 static void prepare_update_cf(X86DecodedInsn *decode, DisasContext *s, TCGv cf)
435 switch (s->cc_op) {
451 gen_mov_eflags(s, decode->cc_src);
458 static void gen_store_sse(DisasContext *s, X86DecodedInsn *decode, int src_ofs)
461 int vec_len = vector_len(s, decode);
462 bool aligned = sse_needs_alignment(s, decode, ot);
471 gen_stq_env_A0(s, src_ofs);
474 gen_sto_env_A0(s, src_ofs, aligned);
477 gen_sty_env_A0(s, src_ofs, aligned);
517 static void gen_3dnow(DisasContext *s, X86DecodedInsn *decode)
523 gen_illegal_opcode(s);
526 if (s->flags & HF_TS_MASK) {
527 gen_NM_exception(s);
530 if (s->flags & HF_EM_MASK) {
531 gen_illegal_opcode(s);
537 tcg_gen_ld_i64(s->tmp1_i64, tcg_env, decode->op[1].offset);
538 tcg_gen_st_i64(s->tmp1_i64, tcg_env, decode->op[0].offset);
550 static inline void gen_unary_fp_sse(DisasContext *s, X86DecodedInsn *decode,
555 if ((s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) != 0) {
556 SSEFunc_0_eppp fn = s->prefix & PREFIX_REPZ ? ss : sd;
558 gen_illegal_opcode(s);
564 ps = s->vex_l ? ps_ymm : ps_xmm;
565 pd = s->vex_l ? pd_ymm : pd_xmm;
566 fn = s->prefix & PREFIX_DATA ? pd : ps;
568 gen_illegal_opcode(s);
575 static void gen_##uname(DisasContext *s, X86DecodedInsn *decode) \
577 gen_unary_fp_sse(s, decode, \
593 static inline void gen_fp_sse(DisasContext *s, X86DecodedInsn *decode,
599 if ((s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) != 0) {
600 fn = s->prefix & PREFIX_REPZ ? ss : sd;
602 ps = s->vex_l ? ps_ymm : ps_xmm;
603 pd = s->vex_l ? pd_ymm : pd_xmm;
604 fn = s->prefix & PREFIX_DATA ? pd : ps;
609 gen_illegal_opcode(s);
614 static void gen_##uname(DisasContext *s, X86DecodedInsn *decode) \
616 gen_fp_sse(s, decode, \
632 static void gen_##uname##Px(DisasContext *s, X86DecodedInsn *decode) \
634 SSEFunc_0_eppppii xmm = s->vex_w ? gen_helper_fma4pd_xmm : gen_helper_fma4ps_xmm; \
635 SSEFunc_0_eppppii ymm = s->vex_w ? gen_helper_fma4pd_ymm : gen_helper_fma4ps_ymm; \
636 SSEFunc_0_eppppii fn = s->vex_l ? ymm : xmm; \
645 static void gen_##uname##Sx(DisasContext *s, X86DecodedInsn *decode) \
647 SSEFunc_0_eppppi fn = s->vex_w ? gen_helper_fma4sd : gen_helper_fma4ss; \
678 static void gen_##uname(DisasContext *s, X86DecodedInsn *decode) \
681 gen_fp_sse(s, decode, \
695 static inline void gen_unary_fp32_sse(DisasContext *s, X86DecodedInsn *decode,
700 if ((s->prefix & (PREFIX_DATA | PREFIX_REPNZ)) != 0) {
702 } else if (s->prefix & PREFIX_REPZ) {
708 SSEFunc_0_epp fn = s->vex_l ? ps_ymm : ps_xmm;
717 gen_illegal_opcode(s);
720 static void gen_##uname(DisasContext *s, X86DecodedInsn *decode) \
722 gen_unary_fp32_sse(s, decode, \
734 static inline void gen_horizontal_fp_sse(DisasContext *s, X86DecodedInsn *decode,
739 ps = s->vex_l ? ps_ymm : ps_xmm;
740 pd = s->vex_l ? pd_ymm : pd_xmm;
741 fn = s->prefix & PREFIX_DATA ? pd : ps;
745 static void gen_##uname(DisasContext *s, X86DecodedInsn *decode) \
747 gen_horizontal_fp_sse(s, decode, \
755 static inline void gen_ternary_sse(DisasContext *s, X86DecodedInsn *decode,
758 SSEFunc_0_epppp fn = s->vex_l ? ymm : xmm;
766 static void gen_##uvname(DisasContext *s, X86DecodedInsn *decode) \
768 gen_ternary_sse(s, decode, (uint8_t)decode->immediate >> 4, \
771 static void gen_##uname(DisasContext *s, X86DecodedInsn *decode) \
773 gen_ternary_sse(s, decode, 0, \
780 static inline void gen_binary_imm_sse(DisasContext *s, X86DecodedInsn *decode,
784 if (!s->vex_l) {
792 static void gen_##uname(DisasContext *s, X86DecodedInsn *decode) \
794 gen_binary_imm_sse(s, decode, \
810 static void gen_##uname(DisasContext *s, X86DecodedInsn *decode) \
812 int vec_len = vector_len(s, decode); \
828 static void gen_##uname(DisasContext *s, X86DecodedInsn *decode) \
830 int vec_len = vector_len(s, decode); \
887 static inline void gen_binary_int_sse(DisasContext *s, X86DecodedInsn *decode,
892 if (mmx && (s->prefix & PREFIX_VEX) && !(s->prefix & PREFIX_DATA)) {
894 gen_illegal_opcode(s);
897 if (!(s->prefix & PREFIX_DATA)) {
899 } else if (!s->vex_l) {
908 static void gen_##uname(DisasContext *s, X86DecodedInsn *decode) \
910 gen_binary_int_sse(s, decode, \
957 static void gen_##uname(DisasContext *s, X86DecodedInsn *decode) \
959 gen_binary_int_sse(s, decode, \
982 static void gen_##uname(DisasContext *s, X86DecodedInsn *decode) \
984 if (!s->vex_l) { \
989 assume_cc_op(s, CC_OP_EFLAGS); \
995 static inline void gen_unary_int_sse(DisasContext *s, X86DecodedInsn *decode,
998 if (!s->vex_l) {
1006 static void gen_##uname(DisasContext *s, X86DecodedInsn *decode) \
1008 gen_unary_int_sse(s, decode, \
1040 static inline void gen_unary_imm_sse(DisasContext *s, X86DecodedInsn *decode,
1044 if (!s->vex_l) {
1052 static void gen_##uname(DisasContext *s, X86DecodedInsn *decode) \
1054 gen_unary_imm_sse(s, decode, \
1067 static inline void gen_unary_imm_fp_sse(DisasContext *s, X86DecodedInsn *decode,
1071 if (!s->vex_l) {
1079 static void gen_##uname(DisasContext *s, X86DecodedInsn *decode) \
1081 gen_unary_imm_fp_sse(s, decode, \
1089 static inline void gen_vexw_avx(DisasContext *s, X86DecodedInsn *decode,
1093 SSEFunc_0_eppp d = s->vex_l ? d_ymm : d_xmm;
1094 SSEFunc_0_eppp q = s->vex_l ? q_ymm : q_xmm;
1095 SSEFunc_0_eppp fn = s->vex_w ? q : d;
1101 static void gen_##uname(DisasContext *s, X86DecodedInsn *decode) \
1103 gen_vexw_avx(s, decode, \
1113 static inline void gen_vsib_avx(DisasContext *s, X86DecodedInsn *decode,
1117 SSEFunc_0_epppti d = s->vex_l ? d_ymm : d_xmm;
1118 SSEFunc_0_epppti q = s->vex_l ? q_ymm : q_xmm;
1119 SSEFunc_0_epppti fn = s->vex_w ? q : d;
1125 fn(tcg_env, OP_PTR0, OP_PTR1, index, s->A0, scale);
1128 * There are two output operands, so zero OP1's high 128 bits
1131 if (!s->vex_l) {
1137 static void gen_##uname(DisasContext *s, X86DecodedInsn *decode) \
1139 gen_vsib_avx(s, decode, \
1146 static void gen_AAA(DisasContext *s, X86DecodedInsn *decode)
1148 gen_update_cc_op(s);
1150 assume_cc_op(s, CC_OP_EFLAGS);
1153 static void gen_AAD(DisasContext *s, X86DecodedInsn *decode)
1155 gen_helper_aad(s->T0, s->T0, s->T1);
1156 prepare_update1_cc(decode, s, CC_OP_LOGICB);
1159 static void gen_AAM(DisasContext *s, X86DecodedInsn *decode)
1162 gen_exception(s, EXCP00_DIVZ);
1164 gen_helper_aam(s->T0, s->T0, s->T1);
1165 prepare_update1_cc(decode, s, CC_OP_LOGICB);
1169 static void gen_AAS(DisasContext *s, X86DecodedInsn *decode)
1171 gen_update_cc_op(s);
1173 assume_cc_op(s, CC_OP_EFLAGS);
1176 static void gen_ADC(DisasContext *s, X86DecodedInsn *decode)
1181 gen_compute_eflags_c(s, c_in);
1182 if (s->prefix & PREFIX_LOCK) {
1183 tcg_gen_add_tl(s->T0, c_in, s->T1);
1184 tcg_gen_atomic_add_fetch_tl(s->T0, s->A0, s->T0,
1185 s->mem_index, ot | MO_LE);
1187 tcg_gen_add_tl(s->T0, s->T0, s->T1);
1188 tcg_gen_add_tl(s->T0, s->T0, c_in);
1190 prepare_update3_cc(decode, s, CC_OP_ADCB + ot, c_in);
1193 static void gen_ADCOX(DisasContext *s, X86DecodedInsn *decode, int cc_op)
1202 if (CC_OP_HAS_EFLAGS(s->cc_op)) {
1206 if (s->cc_op == cc_op || s->cc_op == CC_OP_ADCOX) {
1211 if (s->cc_op != cc_op && s->cc_op != CC_OP_EFLAGS) {
1221 gen_mov_eflags(s, decode->cc_src);
1235 tcg_gen_ext32u_tl(s->T0, s->T0);
1236 tcg_gen_ext32u_tl(s->T1, s->T1);
1237 tcg_gen_add_i64(s->T0, s->T0, s->T1);
1238 tcg_gen_add_i64(s->T0, s->T0, carry_in);
1239 tcg_gen_shri_i64(*carry_out, s->T0, 32);
1244 tcg_gen_add2_tl(s->T0, *carry_out, s->T0, zero, carry_in, zero);
1245 tcg_gen_add2_tl(s->T0, *carry_out, s->T0, *carry_out, s->T1, zero);
1250 static void gen_ADCX(DisasContext *s, X86DecodedInsn *decode)
1252 gen_ADCOX(s, decode, CC_OP_ADCX);
1255 static void gen_ADD(DisasContext *s, X86DecodedInsn *decode)
1259 if (s->prefix & PREFIX_LOCK) {
1260 tcg_gen_atomic_add_fetch_tl(s->T0, s->A0, s->T1,
1261 s->mem_index, ot | MO_LE);
1263 tcg_gen_add_tl(s->T0, s->T0, s->T1);
1265 prepare_update2_cc(decode, s, CC_OP_ADDB + ot);
1268 static void gen_ADOX(DisasContext *s, X86DecodedInsn *decode)
1270 gen_ADCOX(s, decode, CC_OP_ADOX);
1273 static void gen_AND(DisasContext *s, X86DecodedInsn *decode)
1277 if (s->prefix & PREFIX_LOCK) {
1278 tcg_gen_atomic_and_fetch_tl(s->T0, s->A0, s->T1,
1279 s->mem_index, ot | MO_LE);
1281 tcg_gen_and_tl(s->T0, s->T0, s->T1);
1283 prepare_update1_cc(decode, s, CC_OP_LOGICB + ot);
1286 static void gen_ANDN(DisasContext *s, X86DecodedInsn *decode)
1290 tcg_gen_andc_tl(s->T0, s->T1, s->T0);
1291 prepare_update1_cc(decode, s, CC_OP_LOGICB + ot);
1294 static void gen_ARPL(DisasContext *s, X86DecodedInsn *decode)
1299 gen_mov_eflags(s, flags);
1302 tcg_gen_deposit_tl(s->T1, s->T0, s->T1, 0, 2);
1305 tcg_gen_setcond_tl(TCG_COND_LTU, zf, s->T0, s->T1);
1309 tcg_gen_umax_tl(s->T0, s->T0, s->T1);
1315 static void gen_BEXTR(DisasContext *s, X86DecodedInsn *decode)
1326 tcg_gen_ext8u_tl(s->A0, s->T1);
1327 tcg_gen_shr_tl(s->T0, s->T0, s->A0);
1329 tcg_gen_movcond_tl(TCG_COND_LEU, s->T0, s->A0, bound, s->T0, zero);
1335 tcg_gen_extract_tl(s->A0, s->T1, 8, 8);
1336 tcg_gen_shl_tl(s->T1, mone, s->A0);
1337 tcg_gen_movcond_tl(TCG_COND_LEU, s->T1, s->A0, bound, s->T1, zero);
1338 tcg_gen_andc_tl(s->T0, s->T0, s->T1);
1340 prepare_update1_cc(decode, s, CC_OP_LOGICB + ot);
1343 static void gen_BLSI(DisasContext *s, X86DecodedInsn *decode)
1348 tcg_gen_neg_tl(s->T0, s->T1);
1349 tcg_gen_and_tl(s->T0, s->T0, s->T1);
1350 prepare_update2_cc(decode, s, CC_OP_BLSIB + ot);
1353 static void gen_BLSMSK(DisasContext *s, X86DecodedInsn *decode)
1358 tcg_gen_subi_tl(s->T0, s->T1, 1);
1359 tcg_gen_xor_tl(s->T0, s->T0, s->T1);
1360 prepare_update2_cc(decode, s, CC_OP_BMILGB + ot);
1363 static void gen_BLSR(DisasContext *s, X86DecodedInsn *decode)
1368 tcg_gen_subi_tl(s->T0, s->T1, 1);
1369 tcg_gen_and_tl(s->T0, s->T0, s->T1);
1370 prepare_update2_cc(decode, s, CC_OP_BMILGB + ot);
1373 static void gen_BOUND(DisasContext *s, X86DecodedInsn *decode)
1376 tcg_gen_trunc_tl_i32(op, s->T0);
1378 gen_helper_boundw(tcg_env, s->A0, op);
1380 gen_helper_boundl(tcg_env, s->A0, op);
1385 static void gen_BSF(DisasContext *s, X86DecodedInsn *decode)
1392 tcg_gen_mov_tl(decode->cc_dst, s->T0);
1400 tcg_gen_ctz_tl(s->T0, s->T0, s->T1);
1404 static void gen_BSR(DisasContext *s, X86DecodedInsn *decode)
1411 tcg_gen_mov_tl(decode->cc_dst, s->T0);
1420 tcg_gen_xori_tl(s->T1, s->T1, TARGET_LONG_BITS - 1);
1421 tcg_gen_clz_tl(s->T0, s->T0, s->T1);
1422 tcg_gen_xori_tl(s->T0, s->T0, TARGET_LONG_BITS - 1);
1425 static void gen_BSWAP(DisasContext *s, X86DecodedInsn *decode)
1428 if (s->dflag == MO_64) {
1429 tcg_gen_bswap64_i64(s->T0, s->T0);
1433 tcg_gen_bswap32_tl(s->T0, s->T0, TCG_BSWAP_OZ);
1436 static TCGv gen_bt_mask(DisasContext *s, X86DecodedInsn *decode)
1441 tcg_gen_andi_tl(s->T1, s->T1, (8 << ot) - 1);
1442 tcg_gen_shl_tl(mask, tcg_constant_tl(1), s->T1);
1446 /* Expects truncated bit index in s->T1, 1 << s->T1 in MASK. */
1447 static void gen_bt_flags(DisasContext *s, X86DecodedInsn *decode, TCGv src, TCGv mask)
1455 if (s->cc_op == CC_OP_DYNAMIC || CC_OP_HAS_EFLAGS(s->cc_op)) {
1459 prepare_update_cf(decode, s, cf);
1469 decode->cc_op = CC_OP_SARB + cc_op_size(s->cc_op);
1470 tcg_gen_shr_tl(decode->cc_src, src, s->T1);
1474 static void gen_BT(DisasContext *s, X86DecodedInsn *decode)
1476 TCGv mask = gen_bt_mask(s, decode);
1478 gen_bt_flags(s, decode, s->T0, mask);
1481 static void gen_BTC(DisasContext *s, X86DecodedInsn *decode)
1485 TCGv mask = gen_bt_mask(s, decode);
1487 if (s->prefix & PREFIX_LOCK) {
1488 tcg_gen_atomic_fetch_xor_tl(old, s->A0, mask, s->mem_index, ot | MO_LE);
1490 tcg_gen_mov_tl(old, s->T0);
1491 tcg_gen_xor_tl(s->T0, s->T0, mask);
1494 gen_bt_flags(s, decode, old, mask);
1497 static void gen_BTR(DisasContext *s, X86DecodedInsn *decode)
1501 TCGv mask = gen_bt_mask(s, decode);
1503 if (s->prefix & PREFIX_LOCK) {
1506 tcg_gen_atomic_fetch_and_tl(old, s->A0, maskc, s->mem_index, ot | MO_LE);
1508 tcg_gen_mov_tl(old, s->T0);
1509 tcg_gen_andc_tl(s->T0, s->T0, mask);
1512 gen_bt_flags(s, decode, old, mask);
1515 static void gen_BTS(DisasContext *s, X86DecodedInsn *decode)
1519 TCGv mask = gen_bt_mask(s, decode);
1521 if (s->prefix & PREFIX_LOCK) {
1522 tcg_gen_atomic_fetch_or_tl(old, s->A0, mask, s->mem_index, ot | MO_LE);
1524 tcg_gen_mov_tl(old, s->T0);
1525 tcg_gen_or_tl(s->T0, s->T0, mask);
1528 gen_bt_flags(s, decode, old, mask);
1531 static void gen_BZHI(DisasContext *s, X86DecodedInsn *decode)
1538 tcg_gen_ext8u_tl(s->T1, s->T1);
1540 tcg_gen_shl_tl(s->A0, mone, s->T1);
1541 tcg_gen_movcond_tl(TCG_COND_LEU, s->A0, s->T1, bound, s->A0, zero);
1542 tcg_gen_andc_tl(s->T0, s->T0, s->A0);
1547 tcg_gen_setcond_tl(TCG_COND_LEU, s->T1, s->T1, bound);
1548 prepare_update2_cc(decode, s, CC_OP_BMILGB + ot);
1551 static void gen_CALL(DisasContext *s, X86DecodedInsn *decode)
1553 gen_push_v(s, eip_next_tl(s));
1554 gen_JMP(s, decode);
1557 static void gen_CALL_m(DisasContext *s, X86DecodedInsn *decode)
1559 gen_push_v(s, eip_next_tl(s));
1560 gen_JMP_m(s, decode);
1563 static void gen_CALLF(DisasContext *s, X86DecodedInsn *decode)
1565 gen_far_call(s);
1568 static void gen_CALLF_m(DisasContext *s, X86DecodedInsn *decode)
1572 gen_op_ld_v(s, ot, s->T0, s->A0);
1573 gen_add_A0_im(s, 1 << ot);
1574 gen_op_ld_v(s, MO_16, s->T1, s->A0);
1575 gen_far_call(s);
1578 static void gen_CBW(DisasContext *s, X86DecodedInsn *decode)
1582 tcg_gen_ext_tl(s->T0, s->T0, src_ot | MO_SIGN);
1585 static void gen_CLC(DisasContext *s, X86DecodedInsn *decode)
1587 gen_compute_eflags(s);
1591 static void gen_CLD(DisasContext *s, X86DecodedInsn *decode)
1596 static void gen_CLI(DisasContext *s, X86DecodedInsn *decode)
1598 gen_reset_eflags(s, IF_MASK);
1601 static void gen_CLTS(DisasContext *s, X86DecodedInsn *decode)
1605 s->base.is_jmp = DISAS_EOB_NEXT;
1608 static void gen_CMC(DisasContext *s, X86DecodedInsn *decode)
1610 gen_compute_eflags(s);
1614 static void gen_CMOVcc(DisasContext *s, X86DecodedInsn *decode)
1616 gen_cmovcc1(s, decode->b & 0xf, s->T0, s->T1);
1619 static void gen_CMPccXADD(DisasContext *s, X86DecodedInsn *decode)
1652 * Sign-extend values before subtracting for S, P (zero/sign extension
1666 * - s->T1: addition operand (from decoder)
1667 * - s->A0: dest address (from decoder)
1668 * - s->cc_srcT: memory operand (lhs for comparison)
1672 gen_op_ld_v(s, ot_full, s->cc_srcT, s->A0);
1673 tcg_gen_sub_tl(s->T0, s->cc_srcT, cmpv);
1679 tcg_gen_xor_tl(newv, s->cc_srcT, s->T0);
1680 tcg_gen_xor_tl(s->tmp0, s->cc_srcT, cmpv);
1681 tcg_gen_and_tl(s->tmp0, s->tmp0, newv);
1682 tcg_gen_sextract_tl(s->tmp0, s->tmp0, 0, 8 << ot);
1683 cmp_lhs = s->tmp0, cmp_rhs = tcg_constant_tl(0);
1687 tcg_gen_ext8u_tl(s->tmp0, s->T0);
1688 tcg_gen_ctpop_tl(s->tmp0, s->tmp0);
1689 cmp_lhs = s->tmp0, cmp_rhs = tcg_constant_tl(1);
1693 tcg_gen_sextract_tl(s->tmp0, s->T0, 0, 8 << ot);
1694 cmp_lhs = s->tmp0, cmp_rhs = tcg_constant_tl(0);
1698 cmp_lhs = s->cc_srcT, cmp_rhs = cmpv;
1702 /* Compute new value: if condition does not hold, just store back s->cc_srcT */
1703 tcg_gen_add_tl(newv, s->cc_srcT, s->T1);
1704 tcg_gen_movcond_tl(cond, newv, cmp_lhs, cmp_rhs, newv, s->cc_srcT);
1705 tcg_gen_atomic_cmpxchg_tl(oldv, s->A0, s->cc_srcT, newv, s->mem_index, ot_full);
1708 tcg_gen_brcond_tl(TCG_COND_EQ, oldv, s->cc_srcT, label_bottom);
1715 gen_writeback(s, decode, 1, s->cc_srcT);
1717 decode->cc_dst = s->T0;
1722 static void gen_CMPS(DisasContext *s, X86DecodedInsn *decode)
1725 if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
1726 gen_repz_nz(s, ot, gen_cmps);
1728 gen_cmps(s, ot);
1732 static void gen_CMPXCHG(DisasContext *s, X86DecodedInsn *decode)
1741 tcg_gen_ext_tl(newv, s->T1, ot);
1742 if (s->prefix & PREFIX_LOCK) {
1743 tcg_gen_atomic_cmpxchg_tl(oldv, s->A0, cmpv, newv,
1744 s->mem_index, ot | MO_LE);
1746 tcg_gen_ext_tl(oldv, s->T0, ot);
1755 gen_op_st_v(s, ot, newv, s->A0);
1766 dest = gen_op_deposit_reg_v(s, ot, decode->op[0].n, newv, newv);
1773 dest = gen_op_deposit_reg_v(s, ot, R_EAX, s->T0, oldv);
1774 tcg_gen_movcond_tl(TCG_COND_NE, dest, oldv, cmpv, s->T0, dest);
1776 tcg_gen_mov_tl(s->cc_srcT, cmpv);
1783 static void gen_CMPXCHG16B(DisasContext *s, X86DecodedInsn *decode)
1796 if (s->prefix & PREFIX_LOCK) {
1797 tcg_gen_atomic_cmpxchg_i128(val, s->A0, cmp, val, s->mem_index, mop);
1799 tcg_gen_nonatomic_cmpxchg_i128(val, s->A0, cmp, val, s->mem_index, mop);
1802 tcg_gen_extr_i128_i64(s->T0, s->T1, val);
1807 tcg_gen_xor_i64(t0, s->T0, cpu_regs[R_EAX]);
1808 tcg_gen_xor_i64(t1, s->T1, cpu_regs[R_EDX]);
1812 gen_compute_eflags(s);
1821 tcg_gen_mov_i64(cpu_regs[R_EAX], s->T0);
1822 tcg_gen_mov_i64(cpu_regs[R_EDX], s->T1);
1828 static void gen_CMPXCHG8B(DisasContext *s, X86DecodedInsn *decode)
1842 if (s->prefix & PREFIX_LOCK) {
1843 tcg_gen_atomic_cmpxchg_i64(old, s->A0, cmp, val, s->mem_index, MO_TEUQ);
1845 tcg_gen_nonatomic_cmpxchg_i64(old, s->A0, cmp, val,
1846 s->mem_index, MO_TEUQ);
1867 tcg_gen_extr_i64_tl(s->T0, s->T1, old);
1869 s->T0, cpu_regs[R_EAX]);
1871 s->T1, cpu_regs[R_EDX]);
1875 gen_compute_eflags(s);
1879 static void gen_CPUID(DisasContext *s, X86DecodedInsn *decode)
1881 gen_update_cc_op(s);
1882 gen_update_eip_cur(s);
1886 static void gen_CRC32(DisasContext *s, X86DecodedInsn *decode)
1890 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
1891 gen_helper_crc32(s->T0, s->tmp2_i32, s->T1, tcg_constant_i32(8 << ot));
1894 static void gen_CVTPI2Px(DisasContext *s, X86DecodedInsn *decode)
1897 if (s->prefix & PREFIX_DATA) {
1904 static void gen_CVTPx2PI(DisasContext *s, X86DecodedInsn *decode)
1907 if (s->prefix & PREFIX_DATA) {
1914 static void gen_CVTTPx2PI(DisasContext *s, X86DecodedInsn *decode)
1917 if (s->prefix & PREFIX_DATA) {
1924 static void gen_CWD(DisasContext *s, X86DecodedInsn *decode)
1928 tcg_gen_sextract_tl(s->T0, s->T0, shift - 1, 1);
1931 static void gen_DAA(DisasContext *s, X86DecodedInsn *decode)
1933 gen_update_cc_op(s);
1935 assume_cc_op(s, CC_OP_EFLAGS);
1938 static void gen_DAS(DisasContext *s, X86DecodedInsn *decode)
1940 gen_update_cc_op(s);
1942 assume_cc_op(s, CC_OP_EFLAGS);
1945 static void gen_DEC(DisasContext *s, X86DecodedInsn *decode)
1949 tcg_gen_movi_tl(s->T1, -1);
1950 if (s->prefix & PREFIX_LOCK) {
1951 tcg_gen_atomic_add_fetch_tl(s->T0, s->A0, s->T1,
1952 s->mem_index, ot | MO_LE);
1954 tcg_gen_add_tl(s->T0, s->T0, s->T1);
1956 prepare_update_cc_incdec(decode, s, CC_OP_DECB + ot);
1959 static void gen_DIV(DisasContext *s, X86DecodedInsn *decode)
1965 gen_helper_divb_AL(tcg_env, s->T0);
1968 gen_helper_divw_AX(tcg_env, s->T0);
1972 gen_helper_divl_EAX(tcg_env, s->T0);
1976 gen_helper_divq_EAX(tcg_env, s->T0);
1982 static void gen_EMMS(DisasContext *s, X86DecodedInsn *decode)
1987 static void gen_ENTER(DisasContext *s, X86DecodedInsn *decode)
1989 gen_enter(s, decode->op[1].imm, decode->op[2].imm);
1992 static void gen_EXTRQ_i(DisasContext *s, X86DecodedInsn *decode)
2000 static void gen_EXTRQ_r(DisasContext *s, X86DecodedInsn *decode)
2005 static void gen_FXRSTOR(DisasContext *s, X86DecodedInsn *decode)
2007 if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
2008 gen_NM_exception(s);
2010 gen_helper_fxrstor(tcg_env, s->A0);
2014 static void gen_FXSAVE(DisasContext *s, X86DecodedInsn *decode)
2016 if ((s->flags & HF_EM_MASK) || (s->flags & HF_TS_MASK)) {
2017 gen_NM_exception(s);
2019 gen_helper_fxsave(tcg_env, s->A0);
2023 static void gen_HLT(DisasContext *s, X86DecodedInsn *decode)
2026 gen_update_cc_op(s);
2027 gen_update_eip_next(s);
2029 s->base.is_jmp = DISAS_NORETURN;
2033 static void gen_IDIV(DisasContext *s, X86DecodedInsn *decode)
2039 gen_helper_idivb_AL(tcg_env, s->T0);
2042 gen_helper_idivw_AX(tcg_env, s->T0);
2046 gen_helper_idivl_EAX(tcg_env, s->T0);
2050 gen_helper_idivq_EAX(tcg_env, s->T0);
2056 static void gen_IMUL3(DisasContext *s, X86DecodedInsn *decode)
2063 /* s->T0 already sign-extended */
2064 tcg_gen_ext16s_tl(s->T1, s->T1);
2065 tcg_gen_mul_tl(s->T0, s->T0, s->T1);
2067 tcg_gen_ext16s_tl(s->T1, s->T0);
2068 cc_src_rhs = s->T0;
2079 * s->T0 is already sign-extended.
2081 tcg_gen_ext32s_tl(s->T1, s->T1);
2082 tcg_gen_mul_tl(s->T0, s->T0, s->T1);
2084 tcg_gen_ext32s_tl(s->T1, s->T0);
2085 cc_src_rhs = s->T0;
2090 tcg_gen_trunc_tl_i32(lo, s->T0);
2091 tcg_gen_trunc_tl_i32(hi, s->T1);
2093 tcg_gen_extu_i32_tl(s->T0, lo);
2099 tcg_gen_extu_i32_tl(s->T1, lo);
2106 tcg_gen_muls2_tl(s->T0, cc_src_rhs, s->T0, s->T1);
2108 tcg_gen_sari_tl(s->T1, s->T0, TARGET_LONG_BITS - 1);
2115 tcg_gen_sub_tl(s->T1, s->T1, cc_src_rhs);
2116 prepare_update2_cc(decode, s, CC_OP_MULB + ot);
2119 static void gen_IMUL(DisasContext *s, X86DecodedInsn *decode)
2126 /* s->T0 already sign-extended */
2127 tcg_gen_ext8s_tl(s->T1, s->T1);
2128 tcg_gen_mul_tl(s->T0, s->T0, s->T1);
2129 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
2131 tcg_gen_ext8s_tl(s->T1, s->T0);
2132 cc_src_rhs = s->T0;
2136 /* s->T0 already sign-extended */
2137 tcg_gen_ext16s_tl(s->T1, s->T1);
2138 tcg_gen_mul_tl(s->T0, s->T0, s->T1);
2139 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
2140 tcg_gen_shri_tl(s->T1, s->T0, 16);
2141 gen_op_mov_reg_v(s, MO_16, R_EDX, s->T1);
2143 tcg_gen_ext16s_tl(s->T1, s->T0);
2144 cc_src_rhs = s->T0;
2149 /* s->T0 already sign-extended */
2150 tcg_gen_ext32s_tl(s->T1, s->T1);
2151 tcg_gen_mul_tl(s->T0, s->T0, s->T1);
2152 tcg_gen_ext32u_tl(cpu_regs[R_EAX], s->T0);
2153 tcg_gen_shri_tl(cpu_regs[R_EDX], s->T0, 32);
2155 tcg_gen_ext32s_tl(s->T1, s->T0);
2156 cc_src_rhs = s->T0;
2161 tcg_gen_muls2_tl(s->T0, cpu_regs[R_EDX], s->T0, s->T1);
2162 tcg_gen_mov_tl(cpu_regs[R_EAX], s->T0);
2165 tcg_gen_negsetcondi_tl(TCG_COND_LT, s->T1, s->T0, 0);
2173 tcg_gen_sub_tl(s->T1, s->T1, cc_src_rhs);
2174 prepare_update2_cc(decode, s, CC_OP_MULB + ot);
2177 static void gen_IN(DisasContext *s, X86DecodedInsn *decode)
2182 tcg_gen_trunc_tl_i32(port, s->T0);
2184 if (!gen_check_io(s, ot, port, SVM_IOIO_TYPE_MASK)) {
2187 translator_io_start(&s->base);
2188 gen_helper_in_func(ot, s->T0, port);
2189 gen_writeback(s, decode, 0, s->T0);
2190 gen_bpt_io(s, port, ot);
2193 static void gen_INC(DisasContext *s, X86DecodedInsn *decode)
2197 tcg_gen_movi_tl(s->T1, 1);
2198 if (s->prefix & PREFIX_LOCK) {
2199 tcg_gen_atomic_add_fetch_tl(s->T0, s->A0, s->T1,
2200 s->mem_index, ot | MO_LE);
2202 tcg_gen_add_tl(s->T0, s->T0, s->T1);
2204 prepare_update_cc_incdec(decode, s, CC_OP_INCB + ot);
2207 static void gen_INS(DisasContext *s, X86DecodedInsn *decode)
2212 tcg_gen_trunc_tl_i32(port, s->T1);
2214 if (!gen_check_io(s, ot, port,
2219 translator_io_start(&s->base);
2220 if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
2221 gen_repz(s, ot, gen_ins);
2223 gen_ins(s, ot);
2227 static void gen_INSERTQ_i(DisasContext *s, X86DecodedInsn *decode)
2235 static void gen_INSERTQ_r(DisasContext *s, X86DecodedInsn *decode)
2240 static void gen_INT(DisasContext *s, X86DecodedInsn *decode)
2242 gen_interrupt(s, decode->immediate);
2245 static void gen_INT1(DisasContext *s, X86DecodedInsn *decode)
2247 gen_update_cc_op(s);
2248 gen_update_eip_next(s);
2250 s->base.is_jmp = DISAS_NORETURN;
2253 static void gen_INT3(DisasContext *s, X86DecodedInsn *decode)
2255 gen_interrupt(s, EXCP03_INT3);
2258 static void gen_INTO(DisasContext *s, X86DecodedInsn *decode)
2260 gen_update_cc_op(s);
2261 gen_update_eip_cur(s);
2262 gen_helper_into(tcg_env, cur_insn_len_i32(s));
2265 static void gen_IRET(DisasContext *s, X86DecodedInsn *decode)
2267 if (!PE(s) || VM86(s)) {
2268 gen_helper_iret_real(tcg_env, tcg_constant_i32(s->dflag - 1));
2270 gen_helper_iret_protected(tcg_env, tcg_constant_i32(s->dflag - 1),
2271 eip_next_i32(s));
2273 assume_cc_op(s, CC_OP_EFLAGS);
2274 s->base.is_jmp = DISAS_EOB_ONLY;
2277 static void gen_Jcc(DisasContext *s, X86DecodedInsn *decode)
2279 gen_bnd_jmp(s);
2280 gen_jcc(s, decode->b & 0xf, decode->immediate);
2283 static void gen_JCXZ(DisasContext *s, X86DecodedInsn *decode)
2287 gen_update_cc_op(s);
2288 gen_op_jz_ecx(s, taken);
2289 gen_conditional_jump_labels(s, decode->immediate, NULL, taken);
2292 static void gen_JMP(DisasContext *s, X86DecodedInsn *decode)
2294 gen_update_cc_op(s);
2295 gen_jmp_rel(s, s->dflag, decode->immediate, 0);
2298 static void gen_JMP_m(DisasContext *s, X86DecodedInsn *decode)
2300 gen_op_jmp_v(s, s->T0);
2301 gen_bnd_jmp(s);
2302 s->base.is_jmp = DISAS_JUMP;
2305 static void gen_JMPF(DisasContext *s, X86DecodedInsn *decode)
2307 gen_far_jmp(s);
2310 static void gen_JMPF_m(DisasContext *s, X86DecodedInsn *decode)
2314 gen_op_ld_v(s, ot, s->T0, s->A0);
2315 gen_add_A0_im(s, 1 << ot);
2316 gen_op_ld_v(s, MO_16, s->T1, s->A0);
2317 gen_far_jmp(s);
2320 static void gen_LAHF(DisasContext *s, X86DecodedInsn *decode)
2322 if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM)) {
2323 return gen_illegal_opcode(s);
2325 gen_compute_eflags(s);
2327 tcg_gen_ori_tl(s->T0, cpu_cc_src, 0x02);
2328 tcg_gen_deposit_tl(cpu_regs[R_EAX], cpu_regs[R_EAX], s->T0, 8, 8);
2331 static void gen_LAR(DisasContext *s, X86DecodedInsn *decode)
2337 gen_compute_eflags(s);
2338 gen_update_cc_op(s);
2339 gen_helper_lar(result, tcg_env, s->T0);
2343 dest = gen_op_deposit_reg_v(s, ot, decode->op[0].n, result, result);
2348 static void gen_LDMXCSR(DisasContext *s, X86DecodedInsn *decode)
2350 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
2351 gen_helper_ldmxcsr(tcg_env, s->tmp2_i32);
2354 static void gen_lxx_seg(DisasContext *s, X86DecodedInsn *decode, int seg)
2358 /* Offset already in s->T0. */
2359 gen_add_A0_im(s, 1 << ot);
2360 gen_op_ld_v(s, MO_16, s->T1, s->A0);
2363 gen_movl_seg(s, seg, s->T1);
2366 static void gen_LDS(DisasContext *s, X86DecodedInsn *decode)
2368 gen_lxx_seg(s, decode, R_DS);
2371 static void gen_LEA(DisasContext *s, X86DecodedInsn *decode)
2373 TCGv ea = gen_lea_modrm_1(s, decode->mem, false);
2374 gen_lea_v_seg_dest(s, s->aflag, s->T0, ea, -1, -1);
2377 static void gen_LEAVE(DisasContext *s, X86DecodedInsn *decode)
2379 gen_leave(s);
2382 static void gen_LES(DisasContext *s, X86DecodedInsn *decode)
2384 gen_lxx_seg(s, decode, R_ES);
2387 static void gen_LFENCE(DisasContext *s, X86DecodedInsn *decode)
2392 static void gen_LFS(DisasContext *s, X86DecodedInsn *decode)
2394 gen_lxx_seg(s, decode, R_FS);
2397 static void gen_LGS(DisasContext *s, X86DecodedInsn *decode)
2399 gen_lxx_seg(s, decode, R_GS);
2402 static void gen_LODS(DisasContext *s, X86DecodedInsn *decode)
2405 if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
2406 gen_repz(s, ot, gen_lods);
2408 gen_lods(s, ot);
2412 static void gen_LOOP(DisasContext *s, X86DecodedInsn *decode)
2416 gen_update_cc_op(s);
2417 gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
2418 gen_op_jnz_ecx(s, taken);
2419 gen_conditional_jump_labels(s, decode->immediate, NULL, taken);
2422 static void gen_LOOPE(DisasContext *s, X86DecodedInsn *decode)
2427 gen_update_cc_op(s);
2428 gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
2429 gen_op_jz_ecx(s, not_taken);
2430 gen_jcc1(s, (JCC_Z << 1), taken); /* jz taken */
2431 gen_conditional_jump_labels(s, decode->immediate, not_taken, taken);
2434 static void gen_LOOPNE(DisasContext *s, X86DecodedInsn *decode)
2439 gen_update_cc_op(s);
2440 gen_op_add_reg_im(s, s->aflag, R_ECX, -1);
2441 gen_op_jz_ecx(s, not_taken);
2442 gen_jcc1(s, (JCC_Z << 1) | 1, taken); /* jnz taken */
2443 gen_conditional_jump_labels(s, decode->immediate, not_taken, taken);
2446 static void gen_LSL(DisasContext *s, X86DecodedInsn *decode)
2452 gen_compute_eflags(s);
2453 gen_update_cc_op(s);
2454 gen_helper_lsl(result, tcg_env, s->T0);
2458 dest = gen_op_deposit_reg_v(s, ot, decode->op[0].n, result, result);
2463 static void gen_LSS(DisasContext *s, X86DecodedInsn *decode)
2465 gen_lxx_seg(s, decode, R_SS);
2468 static void gen_LZCNT(DisasContext *s, X86DecodedInsn *decode)
2474 decode->cc_dst = s->T0;
2476 tcg_gen_mov_tl(decode->cc_src, s->T0);
2482 tcg_gen_clzi_tl(s->T0, s->T0, TARGET_LONG_BITS);
2483 tcg_gen_subi_tl(s->T0, s->T0, TARGET_LONG_BITS - (8 << ot));
2486 static void gen_MFENCE(DisasContext *s, X86DecodedInsn *decode)
2491 static void gen_MOV(DisasContext *s, X86DecodedInsn *decode)
2497 static void gen_MASKMOV(DisasContext *s, X86DecodedInsn *decode)
2499 gen_lea_v_seg(s, cpu_regs[R_EDI], R_DS, s->override);
2501 if (s->prefix & PREFIX_DATA) {
2502 gen_helper_maskmov_xmm(tcg_env, OP_PTR1, OP_PTR2, s->A0);
2504 gen_helper_maskmov_mmx(tcg_env, OP_PTR1, OP_PTR2, s->A0);
2508 static void gen_MOVBE(DisasContext *s, X86DecodedInsn *decode)
2514 tcg_gen_qemu_st_tl(s->T0, s->A0, s->mem_index, ot | MO_BE);
2516 tcg_gen_qemu_ld_tl(s->T0, s->A0, s->mem_index, ot | MO_BE);
2520 static void gen_MOVD_from(DisasContext *s, X86DecodedInsn *decode)
2527 tcg_gen_ld32u_tl(s->T0, tcg_env, decode->op[2].offset);
2531 tcg_gen_ld_tl(s->T0, tcg_env, decode->op[2].offset);
2538 static void gen_MOVD_to(DisasContext *s, X86DecodedInsn *decode)
2541 int vec_len = vector_len(s, decode);
2549 tcg_gen_st32_tl(s->T1, tcg_env, lo_ofs);
2553 tcg_gen_st_tl(s->T1, tcg_env, lo_ofs);
2560 static void gen_MOVDQ(DisasContext *s, X86DecodedInsn *decode)
2562 gen_store_sse(s, decode, decode->op[2].offset);
2565 static void gen_MOVMSK(DisasContext *s, X86DecodedInsn *decode)
2568 ps = s->vex_l ? gen_helper_movmskps_ymm : gen_helper_movmskps_xmm;
2569 pd = s->vex_l ? gen_helper_movmskpd_ymm : gen_helper_movmskpd_xmm;
2570 fn = s->prefix & PREFIX_DATA ? pd : ps;
2571 fn(s->tmp2_i32, tcg_env, OP_PTR2);
2572 tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32);
2575 static void gen_MOVQ(DisasContext *s, X86DecodedInsn *decode)
2577 int vec_len = vector_len(s, decode);
2580 tcg_gen_ld_i64(s->tmp1_i64, tcg_env, decode->op[2].offset);
2582 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ);
2585 * tcg_gen_gvec_dup_i64(MO_64, op0.offset, 8, vec_len, s->tmp1_64) would
2593 tcg_gen_st_i64(s->tmp1_i64, tcg_env, lo_ofs);
2597 static void gen_MOVq_dq(DisasContext *s, X86DecodedInsn *decode)
2601 return gen_MOVQ(s, decode);
2604 static void gen_MOVS(DisasContext *s, X86DecodedInsn *decode)
2607 if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
2608 gen_repz(s, ot, gen_movs);
2610 gen_movs(s, ot);
2614 static void gen_MUL(DisasContext *s, X86DecodedInsn *decode)
2620 /* s->T0 already zero-extended */
2621 tcg_gen_ext8u_tl(s->T1, s->T1);
2622 tcg_gen_mul_tl(s->T0, s->T0, s->T1);
2623 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
2624 tcg_gen_andi_tl(s->T1, s->T0, 0xff00);
2625 decode->cc_dst = s->T0;
2626 decode->cc_src = s->T1;
2630 /* s->T0 already zero-extended */
2631 tcg_gen_ext16u_tl(s->T1, s->T1);
2632 tcg_gen_mul_tl(s->T0, s->T0, s->T1);
2633 gen_op_mov_reg_v(s, MO_16, R_EAX, s->T0);
2634 tcg_gen_shri_tl(s->T1, s->T0, 16);
2635 gen_op_mov_reg_v(s, MO_16, R_EDX, s->T1);
2636 decode->cc_dst = s->T0;
2637 decode->cc_src = s->T1;
2642 /* s->T0 already zero-extended */
2643 tcg_gen_ext32u_tl(s->T1, s->T1);
2644 tcg_gen_mul_tl(s->T0, s->T0, s->T1);
2645 tcg_gen_ext32u_tl(cpu_regs[R_EAX], s->T0);
2646 tcg_gen_shri_tl(cpu_regs[R_EDX], s->T0, 32);
2653 tcg_gen_mulu2_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->T0, s->T1);
2665 static void gen_MULX(DisasContext *s, X86DecodedInsn *decode)
2673 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
2674 tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
2675 tcg_gen_mulu2_i32(s->tmp2_i32, s->tmp3_i32,
2676 s->tmp2_i32, s->tmp3_i32);
2677 tcg_gen_extu_i32_tl(cpu_regs[s->vex_v], s->tmp2_i32);
2678 tcg_gen_extu_i32_tl(s->T0, s->tmp3_i32);
2683 tcg_gen_mulu2_tl(cpu_regs[s->vex_v], s->T0, s->T0, s->T1);
2691 static void gen_NEG(DisasContext *s, X86DecodedInsn *decode)
2696 if (s->prefix & PREFIX_LOCK) {
2702 gen_op_ld_v(s, ot, oldv, s->A0);
2704 tcg_gen_atomic_cmpxchg_tl(cmpv, s->A0, oldv, newv,
2705 s->mem_index, ot | MO_LE);
2708 tcg_gen_mov_tl(oldv, s->T0);
2710 tcg_gen_neg_tl(s->T0, oldv);
2712 decode->cc_dst = s->T0;
2714 tcg_gen_movi_tl(s->cc_srcT, 0);
2718 static void gen_NOT(DisasContext *s, X86DecodedInsn *decode)
2722 if (s->prefix & PREFIX_LOCK) {
2723 tcg_gen_movi_tl(s->T0, ~0);
2724 tcg_gen_atomic_xor_fetch_tl(s->T0, s->A0, s->T0,
2725 s->mem_index, ot | MO_LE);
2727 tcg_gen_not_tl(s->T0, s->T0);
2731 static void gen_OR(DisasContext *s, X86DecodedInsn *decode)
2735 if (s->prefix & PREFIX_LOCK) {
2736 tcg_gen_atomic_or_fetch_tl(s->T0, s->A0, s->T1,
2737 s->mem_index, ot | MO_LE);
2739 tcg_gen_or_tl(s->T0, s->T0, s->T1);
2741 prepare_update1_cc(decode, s, CC_OP_LOGICB + ot);
2744 static void gen_OUT(DisasContext *s, X86DecodedInsn *decode)
2750 tcg_gen_trunc_tl_i32(port, s->T1);
2752 if (!gen_check_io(s, ot, port, 0)) {
2755 tcg_gen_trunc_tl_i32(value, s->T0);
2756 translator_io_start(&s->base);
2758 gen_bpt_io(s, port, ot);
2761 static void gen_OUTS(DisasContext *s, X86DecodedInsn *decode)
2766 tcg_gen_trunc_tl_i32(port, s->T1);
2768 if (!gen_check_io(s, ot, port, SVM_IOIO_STR_MASK)) {
2772 translator_io_start(&s->base);
2773 if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
2774 gen_repz(s, ot, gen_outs);
2776 gen_outs(s, ot);
2780 static void gen_PALIGNR(DisasContext *s, X86DecodedInsn *decode)
2783 if (!(s->prefix & PREFIX_DATA)) {
2785 } else if (!s->vex_l) {
2792 static void gen_PANDN(DisasContext *s, X86DecodedInsn *decode)
2794 int vec_len = vector_len(s, decode);
2802 static void gen_PAUSE(DisasContext *s, X86DecodedInsn *decode)
2804 gen_update_cc_op(s);
2805 gen_update_eip_next(s);
2807 s->base.is_jmp = DISAS_NORETURN;
2810 static void gen_PCMPESTRI(DisasContext *s, X86DecodedInsn *decode)
2814 assume_cc_op(s, CC_OP_EFLAGS);
2817 static void gen_PCMPESTRM(DisasContext *s, X86DecodedInsn *decode)
2821 assume_cc_op(s, CC_OP_EFLAGS);
2822 if ((s->prefix & PREFIX_VEX) && !s->vex_l) {
2828 static void gen_PCMPISTRI(DisasContext *s, X86DecodedInsn *decode)
2832 assume_cc_op(s, CC_OP_EFLAGS);
2835 static void gen_PCMPISTRM(DisasContext *s, X86DecodedInsn *decode)
2839 assume_cc_op(s, CC_OP_EFLAGS);
2840 if ((s->prefix & PREFIX_VEX) && !s->vex_l) {
2846 static void gen_PDEP(DisasContext *s, X86DecodedInsn *decode)
2848 gen_helper_pdep(s->T0, s->T0, s->T1);
2851 static void gen_PEXT(DisasContext *s, X86DecodedInsn *decode)
2853 gen_helper_pext(s->T0, s->T0, s->T1);
2856 static inline void gen_pextr(DisasContext *s, X86DecodedInsn *decode, MemOp ot)
2858 int vec_len = vector_len(s, decode);
2864 tcg_gen_ld8u_tl(s->T0, tcg_env, vector_elem_offset(&decode->op[1], ot, val));
2867 tcg_gen_ld16u_tl(s->T0, tcg_env, vector_elem_offset(&decode->op[1], ot, val));
2871 tcg_gen_ld32u_tl(s->T0, tcg_env, vector_elem_offset(&decode->op[1], ot, val));
2875 tcg_gen_ld_tl(s->T0, tcg_env, vector_elem_offset(&decode->op[1], ot, val));
2882 static void gen_PEXTRB(DisasContext *s, X86DecodedInsn *decode)
2884 gen_pextr(s, decode, MO_8);
2887 static void gen_PEXTRW(DisasContext *s, X86DecodedInsn *decode)
2889 gen_pextr(s, decode, MO_16);
2892 static void gen_PEXTR(DisasContext *s, X86DecodedInsn *decode)
2895 gen_pextr(s, decode, ot);
2898 static inline void gen_pinsr(DisasContext *s, X86DecodedInsn *decode, MemOp ot)
2900 int vec_len = vector_len(s, decode);
2906 gen_store_sse(s, decode, decode->op[1].offset);
2911 tcg_gen_st8_tl(s->T1, tcg_env, vector_elem_offset(&decode->op[0], ot, val));
2914 tcg_gen_st16_tl(s->T1, tcg_env, vector_elem_offset(&decode->op[0], ot, val));
2918 tcg_gen_st32_tl(s->T1, tcg_env, vector_elem_offset(&decode->op[0], ot, val));
2922 tcg_gen_st_tl(s->T1, tcg_env, vector_elem_offset(&decode->op[0], ot, val));
2929 static void gen_PINSRB(DisasContext *s, X86DecodedInsn *decode)
2931 gen_pinsr(s, decode, MO_8);
2934 static void gen_PINSRW(DisasContext *s, X86DecodedInsn *decode)
2936 gen_pinsr(s, decode, MO_16);
2939 static void gen_PINSR(DisasContext *s, X86DecodedInsn *decode)
2941 gen_pinsr(s, decode, decode->op[2].ot);
2944 static void gen_pmovmskb_i64(TCGv_i64 d, TCGv_i64 s)
2948 tcg_gen_andi_i64(d, s, 0x8080808080808080ull);
2966 static void gen_pmovmskb_vec(unsigned vece, TCGv_vec d, TCGv_vec s)
2972 tcg_gen_and_vec(vece, d, s, m);
2981 static void gen_PMOVMSKB(DisasContext *s, X86DecodedInsn *decode)
2992 int vec_len = vector_len(s, decode);
2997 tcg_gen_ld8u_tl(s->T0, tcg_env, offsetof(CPUX86State, xmm_t0.ZMM_B(vec_len - 1)));
3012 tcg_gen_extract2_tl(s->T0, t, s->T0, TARGET_LONG_BITS - 8);
3020 tcg_gen_deposit_tl(s->T0, t, s->T0, 8, TARGET_LONG_BITS - 8);
3025 static void gen_POP(DisasContext *s, X86DecodedInsn *decode)
3028 MemOp ot = gen_pop_T0(s);
3033 gen_writeback(s, decode, 0, s->T0);
3037 gen_pop_update(s, ot);
3040 static void gen_POPA(DisasContext *s, X86DecodedInsn *decode)
3042 gen_popa(s);
3045 static void gen_POPCNT(DisasContext *s, X86DecodedInsn *decode)
3050 tcg_gen_mov_tl(decode->cc_dst, s->T0);
3051 tcg_gen_ctpop_tl(s->T0, s->T0);
3054 static void gen_POPF(DisasContext *s, X86DecodedInsn *decode)
3059 if (CPL(s) == 0) {
3061 } else if (CPL(s) <= IOPL(s)) {
3064 if (s->dflag == MO_16) {
3068 ot = gen_pop_T0(s);
3069 gen_helper_write_eflags(tcg_env, s->T0, tcg_constant_i32(mask));
3070 gen_pop_update(s, ot);
3071 set_cc_op(s, CC_OP_EFLAGS);
3073 s->base.is_jmp = DISAS_EOB_NEXT;
3076 static void gen_PSHUFW(DisasContext *s, X86DecodedInsn *decode)
3082 static void gen_PSRLW_i(DisasContext *s, X86DecodedInsn *decode)
3084 int vec_len = vector_len(s, decode);
3095 static void gen_PSLLW_i(DisasContext *s, X86DecodedInsn *decode)
3097 int vec_len = vector_len(s, decode);
3108 static void gen_PSRAW_i(DisasContext *s, X86DecodedInsn *decode)
3110 int vec_len = vector_len(s, decode);
3120 static void gen_PSRLD_i(DisasContext *s, X86DecodedInsn *decode)
3122 int vec_len = vector_len(s, decode);
3133 static void gen_PSLLD_i(DisasContext *s, X86DecodedInsn *decode)
3135 int vec_len = vector_len(s, decode);
3146 static void gen_PSRAD_i(DisasContext *s, X86DecodedInsn *decode)
3148 int vec_len = vector_len(s, decode);
3158 static void gen_PSRLQ_i(DisasContext *s, X86DecodedInsn *decode)
3160 int vec_len = vector_len(s, decode);
3171 static void gen_PSLLQ_i(DisasContext *s, X86DecodedInsn *decode)
3173 int vec_len = vector_len(s, decode);
3198 static void gen_PSRLDQ_i(DisasContext *s, X86DecodedInsn *decode)
3200 int vec_len = vector_len(s, decode);
3203 if (s->vex_l) {
3210 static void gen_PSLLDQ_i(DisasContext *s, X86DecodedInsn *decode)
3212 int vec_len = vector_len(s, decode);
3215 if (s->vex_l) {
3222 static void gen_PUSH(DisasContext *s, X86DecodedInsn *decode)
3224 gen_push_v(s, s->T0);
3227 static void gen_PUSHA(DisasContext *s, X86DecodedInsn *decode)
3229 gen_pusha(s);
3232 static void gen_PUSHF(DisasContext *s, X86DecodedInsn *decode)
3234 gen_update_cc_op(s);
3235 gen_helper_read_eflags(s->T0, tcg_env);
3236 gen_push_v(s, s->T0);
3239 static MemOp gen_shift_count(DisasContext *s, X86DecodedInsn *decode,
3289 static bool gen_eflags_adcox(DisasContext *s, X86DecodedInsn *decode, bool want_carry, bool need_fl…
3303 switch (s->cc_op) {
3318 /* CF and OF are zero, do it just because it's easy. */
3319 gen_mov_eflags(s, decode->cc_src);
3340 gen_mov_eflags(s, decode->cc_src);
3348 if (want_carry && (!need_flags || s->cc_op == CC_OP_SHLB + MO_TL)) {
3349 MemOp size = cc_op_size(s->cc_op);
3353 gen_mov_eflags(s, decode->cc_src);
3357 gen_mov_eflags(s, decode->cc_src);
3421 * from a right shifted part and a left shifted part of s->T0. The new carry
3430 static void gen_RCL(DisasContext *s, X86DecodedInsn *decode)
3435 MemOp ot = gen_shift_count(s, decode, &can_be_zero, &count, decode->op[2].unit);
3447 have_1bit_cin = gen_eflags_adcox(s, decode, true, can_be_zero);
3457 tcg_gen_deposit_tl(high, cin, s->T0, 1, TARGET_LONG_BITS - 1);
3460 tcg_gen_add_tl(high, s->T0, decode->cc_dst);
3461 tcg_gen_add_tl(high, high, s->T0);
3466 /* Compute low part and outgoing carry, incoming s->T0 is zero extended */
3468 tcg_gen_shr_tl(low, s->T0, low_count);
3473 tcg_gen_mov_tl(decode->cc_src2, s->T0);
3474 tcg_gen_or_tl(s->T0, low, high);
3475 gen_rot_overflow(decode, s->T0, decode->cc_src2, false, NULL);
3482 static void gen_RCR(DisasContext *s, X86DecodedInsn *decode)
3487 MemOp ot = gen_shift_count(s, decode, &can_be_zero, &count, decode->op[2].unit);
3499 have_1bit_cin = gen_eflags_adcox(s, decode, true, can_be_zero);
3508 tcg_gen_deposit_tl(high, cin, s->T0, 1, TARGET_LONG_BITS - 1);
3511 tcg_gen_add_tl(high, s->T0, decode->cc_dst);
3512 tcg_gen_add_tl(high, high, s->T0);
3515 /* Compute low part and outgoing carry, incoming s->T0 is zero extended */
3517 tcg_gen_shr_tl(low, s->T0, count);
3526 tcg_gen_mov_tl(decode->cc_src2, s->T0);
3527 tcg_gen_or_tl(s->T0, low, high);
3528 gen_rot_overflow(decode, s->T0, decode->cc_src2, false, NULL);
3536 static void gen_unreachable(DisasContext *s, X86DecodedInsn *decode)
3543 static void gen_RDMSR(DisasContext *s, X86DecodedInsn *decode)
3545 gen_update_cc_op(s);
3546 gen_update_eip_cur(s);
3553 static void gen_RDPMC(DisasContext *s, X86DecodedInsn *decode)
3555 gen_update_cc_op(s);
3556 gen_update_eip_cur(s);
3557 translator_io_start(&s->base);
3559 s->base.is_jmp = DISAS_NORETURN;
3562 static void gen_RDTSC(DisasContext *s, X86DecodedInsn *decode)
3564 gen_update_cc_op(s);
3565 gen_update_eip_cur(s);
3566 translator_io_start(&s->base);
3570 static void gen_RDxxBASE(DisasContext *s, X86DecodedInsn *decode)
3572 TCGv base = cpu_seg_base[s->modrm & 8 ? R_GS : R_FS];
3576 tcg_gen_mov_tl(s->T0, base);
3579 static void gen_RET(DisasContext *s, X86DecodedInsn *decode)
3583 MemOp ot = gen_pop_T0(s);
3584 gen_stack_update(s, adjust + (1 << ot));
3585 gen_op_jmp_v(s, s->T0);
3586 gen_bnd_jmp(s);
3587 s->base.is_jmp = DISAS_JUMP;
3590 static void gen_RETF(DisasContext *s, X86DecodedInsn *decode)
3594 if (!PE(s) || VM86(s)) {
3595 gen_lea_ss_ofs(s, s->A0, cpu_regs[R_ESP], 0);
3597 gen_op_ld_v(s, s->dflag, s->T0, s->A0);
3600 gen_op_jmp_v(s, s->T0);
3602 gen_add_A0_im(s, 1 << s->dflag);
3603 gen_op_ld_v(s, s->dflag, s->T0, s->A0);
3604 gen_op_movl_seg_real(s, R_CS, s->T0);
3606 gen_stack_update(s, adjust + (2 << s->dflag));
3608 gen_update_cc_op(s);
3609 gen_update_eip_cur(s);
3610 gen_helper_lret_protected(tcg_env, tcg_constant_i32(s->dflag - 1),
3613 s->base.is_jmp = DISAS_EOB_ONLY;
3661 static void gen_ROL(DisasContext *s, X86DecodedInsn *decode)
3665 MemOp ot = gen_shift_count(s, decode, &can_be_zero, &count, decode->op[2].unit);
3673 gen_eflags_adcox(s, decode, false, can_be_zero);
3674 tcg_gen_mov_tl(old, s->T0);
3675 temp32 = gen_rot_replicate(ot, s->T0);
3681 tcg_gen_extu_i32_tl(s->T0, temp32);
3683 tcg_gen_rotl_tl(s->T0, s->T0, count);
3685 gen_rot_carry(decode, s->T0, can_be_zero, count, 0);
3686 gen_rot_overflow(decode, s->T0, old, can_be_zero, count);
3689 static void gen_ROR(DisasContext *s, X86DecodedInsn *decode)
3693 MemOp ot = gen_shift_count(s, decode, &can_be_zero, &count, decode->op[2].unit);
3701 gen_eflags_adcox(s, decode, false, can_be_zero);
3702 tcg_gen_mov_tl(old, s->T0);
3703 temp32 = gen_rot_replicate(ot, s->T0);
3709 tcg_gen_extu_i32_tl(s->T0, temp32);
3710 gen_rot_carry(decode, s->T0, can_be_zero, count, 31);
3712 tcg_gen_rotr_tl(s->T0, s->T0, count);
3713 gen_rot_carry(decode, s->T0, can_be_zero, count, TARGET_LONG_BITS - 1);
3715 gen_rot_overflow(decode, s->T0, old, can_be_zero, count);
3718 static void gen_RORX(DisasContext *s, X86DecodedInsn *decode)
3727 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
3728 tcg_gen_rotri_i32(s->tmp2_i32, s->tmp2_i32, b);
3729 tcg_gen_extu_i32_tl(s->T0, s->tmp2_i32);
3734 tcg_gen_rotri_tl(s->T0, s->T0, b);
3743 static void gen_RSM(DisasContext *s, X86DecodedInsn *decode)
3746 assume_cc_op(s, CC_OP_EFLAGS);
3747 s->base.is_jmp = DISAS_EOB_ONLY;
3753 static void gen_SAHF(DisasContext *s, X86DecodedInsn *decode)
3755 if (CODE64(s) && !(s->cpuid_ext3_features & CPUID_EXT3_LAHF_LM)) {
3756 return gen_illegal_opcode(s);
3758 tcg_gen_shri_tl(s->T0, cpu_regs[R_EAX], 8);
3759 gen_compute_eflags(s);
3761 tcg_gen_andi_tl(s->T0, s->T0, CC_S | CC_Z | CC_A | CC_P | CC_C);
3762 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, s->T0);
3765 static void gen_SALC(DisasContext *s, X86DecodedInsn *decode)
3767 gen_compute_eflags_c(s, s->T0);
3768 tcg_gen_neg_tl(s->T0, s->T0);
3771 static void gen_shift_dynamic_flags(DisasContext *s, X86DecodedInsn *decode, TCGv count, CCOp cc_op)
3779 assert(decode->cc_dst == s->T0);
3780 if (cc_op_live(s->cc_op) & USES_CC_DST) {
3783 cpu_cc_dst, s->T0);
3786 if (cc_op_live(s->cc_op) & USES_CC_SRC) {
3792 if (s->cc_op == CC_OP_DYNAMIC) {
3795 old_cc_op = tcg_constant_i32(s->cc_op);
3801 static void gen_SAR(DisasContext *s, X86DecodedInsn *decode)
3805 MemOp ot = gen_shift_count(s, decode, &can_be_zero, &count, decode->op[2].unit);
3811 decode->cc_dst = s->T0;
3814 tcg_gen_sar_tl(decode->cc_src, s->T0, decode->cc_src);
3815 tcg_gen_sar_tl(s->T0, s->T0, count);
3817 gen_shift_dynamic_flags(s, decode, count, CC_OP_SARB + ot);
3823 static void gen_SARX(DisasContext *s, X86DecodedInsn *decode)
3829 tcg_gen_andi_tl(s->T1, s->T1, mask);
3830 tcg_gen_sar_tl(s->T0, s->T0, s->T1);
3833 static void gen_SBB(DisasContext *s, X86DecodedInsn *decode)
3838 gen_compute_eflags_c(s, c_in);
3839 if (s->prefix & PREFIX_LOCK) {
3840 tcg_gen_add_tl(s->T0, s->T1, c_in);
3841 tcg_gen_neg_tl(s->T0, s->T0);
3842 tcg_gen_atomic_add_fetch_tl(s->T0, s->A0, s->T0,
3843 s->mem_index, ot | MO_LE);
3849 tcg_gen_sub_tl(s->T0, s->T0, s->T1);
3850 tcg_gen_sub_tl(s->T0, s->T0, c_in);
3852 prepare_update3_cc(decode, s, CC_OP_SBBB + ot, c_in);
3855 static void gen_SCAS(DisasContext *s, X86DecodedInsn *decode)
3858 if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
3859 gen_repz_nz(s, ot, gen_scas);
3861 gen_scas(s, ot);
3865 static void gen_SETcc(DisasContext *s, X86DecodedInsn *decode)
3867 gen_setcc1(s, decode->b & 0xf, s->T0);
3870 static void gen_SFENCE(DisasContext *s, X86DecodedInsn *decode)
3875 static void gen_SHA1NEXTE(DisasContext *s, X86DecodedInsn *decode)
3880 static void gen_SHA1MSG1(DisasContext *s, X86DecodedInsn *decode)
3885 static void gen_SHA1MSG2(DisasContext *s, X86DecodedInsn *decode)
3890 static void gen_SHA1RNDS4(DisasContext *s, X86DecodedInsn *decode)
3908 static void gen_SHA256MSG1(DisasContext *s, X86DecodedInsn *decode)
3913 static void gen_SHA256MSG2(DisasContext *s, X86DecodedInsn *decode)
3918 static void gen_SHA256RNDS2(DisasContext *s, X86DecodedInsn *decode)
3929 static void gen_SHL(DisasContext *s, X86DecodedInsn *decode)
3933 MemOp ot = gen_shift_count(s, decode, &can_be_zero, &count, decode->op[2].unit);
3939 decode->cc_dst = s->T0;
3942 tcg_gen_shl_tl(decode->cc_src, s->T0, decode->cc_src);
3943 tcg_gen_shl_tl(s->T0, s->T0, count);
3945 gen_shift_dynamic_flags(s, decode, count, CC_OP_SHLB + ot);
3951 static void gen_SHLD(DisasContext *s, X86DecodedInsn *decode)
3956 MemOp ot = gen_shift_count(s, decode, &can_be_zero, &count, unit);
3962 decode->cc_dst = s->T0;
3963 decode->cc_src = s->tmp0;
3964 gen_shiftd_rm_T1(s, ot, false, count);
3966 gen_shift_dynamic_flags(s, decode, count, CC_OP_SHLB + ot);
3972 static void gen_SHLX(DisasContext *s, X86DecodedInsn *decode)
3978 tcg_gen_andi_tl(s->T1, s->T1, mask);
3979 tcg_gen_shl_tl(s->T0, s->T0, s->T1);
3982 static void gen_SHR(DisasContext *s, X86DecodedInsn *decode)
3986 MemOp ot = gen_shift_count(s, decode, &can_be_zero, &count, decode->op[2].unit);
3992 decode->cc_dst = s->T0;
3995 tcg_gen_shr_tl(decode->cc_src, s->T0, decode->cc_src);
3996 tcg_gen_shr_tl(s->T0, s->T0, count);
3998 gen_shift_dynamic_flags(s, decode, count, CC_OP_SARB + ot);
4004 static void gen_SHRD(DisasContext *s, X86DecodedInsn *decode)
4009 MemOp ot = gen_shift_count(s, decode, &can_be_zero, &count, unit);
4015 decode->cc_dst = s->T0;
4016 decode->cc_src = s->tmp0;
4017 gen_shiftd_rm_T1(s, ot, true, count);
4019 gen_shift_dynamic_flags(s, decode, count, CC_OP_SARB + ot);
4025 static void gen_SHRX(DisasContext *s, X86DecodedInsn *decode)
4031 tcg_gen_andi_tl(s->T1, s->T1, mask);
4032 tcg_gen_shr_tl(s->T0, s->T0, s->T1);
4035 static void gen_STC(DisasContext *s, X86DecodedInsn *decode)
4037 gen_compute_eflags(s);
4041 static void gen_STD(DisasContext *s, X86DecodedInsn *decode)
4046 static void gen_STI(DisasContext *s, X86DecodedInsn *decode)
4048 gen_set_eflags(s, IF_MASK);
4049 s->base.is_jmp = DISAS_EOB_INHIBIT_IRQ;
4052 static void gen_VAESKEYGEN(DisasContext *s, X86DecodedInsn *decode)
4055 assert(!s->vex_l);
4059 static void gen_STMXCSR(DisasContext *s, X86DecodedInsn *decode)
4062 tcg_gen_ld32u_tl(s->T0, tcg_env, offsetof(CPUX86State, mxcsr));
4065 static void gen_STOS(DisasContext *s, X86DecodedInsn *decode)
4068 if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
4069 gen_repz(s, ot, gen_stos);
4071 gen_stos(s, ot);
4075 static void gen_SUB(DisasContext *s, X86DecodedInsn *decode)
4079 if (s->prefix & PREFIX_LOCK) {
4080 tcg_gen_neg_tl(s->T0, s->T1);
4081 tcg_gen_atomic_fetch_add_tl(s->cc_srcT, s->A0, s->T0,
4082 s->mem_index, ot | MO_LE);
4083 tcg_gen_sub_tl(s->T0, s->cc_srcT, s->T1);
4085 tcg_gen_mov_tl(s->cc_srcT, s->T0);
4086 tcg_gen_sub_tl(s->T0, s->T0, s->T1);
4088 prepare_update2_cc(decode, s, CC_OP_SUBB + ot);
4091 static void gen_SYSCALL(DisasContext *s, X86DecodedInsn *decode)
4093 gen_update_cc_op(s);
4094 gen_update_eip_cur(s);
4095 gen_helper_syscall(tcg_env, cur_insn_len_i32(s));
4096 if (LMA(s)) {
4097 assume_cc_op(s, CC_OP_EFLAGS);
4105 s->base.is_jmp = DISAS_EOB_RECHECK_TF;
4108 static void gen_SYSENTER(DisasContext *s, X86DecodedInsn *decode)
4111 s->base.is_jmp = DISAS_EOB_ONLY;
4114 static void gen_SYSEXIT(DisasContext *s, X86DecodedInsn *decode)
4116 gen_helper_sysexit(tcg_env, tcg_constant_i32(s->dflag - 1));
4117 s->base.is_jmp = DISAS_EOB_ONLY;
4120 static void gen_SYSRET(DisasContext *s, X86DecodedInsn *decode)
4122 gen_helper_sysret(tcg_env, tcg_constant_i32(s->dflag - 1));
4123 if (LMA(s)) {
4124 assume_cc_op(s, CC_OP_EFLAGS);
4133 s->base.is_jmp = DISAS_EOB_RECHECK_TF;
4136 static void gen_TZCNT(DisasContext *s, X86DecodedInsn *decode)
4142 decode->cc_dst = s->T0;
4144 tcg_gen_mov_tl(decode->cc_src, s->T0);
4147 tcg_gen_ctzi_tl(s->T0, s->T0, 8 << ot);
4150 static void gen_UD(DisasContext *s, X86DecodedInsn *decode)
4152 gen_illegal_opcode(s);
4155 static void gen_VAESIMC(DisasContext *s, X86DecodedInsn *decode)
4157 assert(!s->vex_l);
4210 static void gen_VCMP(DisasContext *s, X86DecodedInsn *decode)
4212 int index = decode->immediate & (s->prefix & PREFIX_VEX ? 31 : 7);
4214 s->prefix & PREFIX_REPZ ? 2 /* ss */ :
4215 s->prefix & PREFIX_REPNZ ? 3 /* sd */ :
4216 !!(s->prefix & PREFIX_DATA) /* pd */ + (s->vex_l << 2);
4221 static void gen_VCOMI(DisasContext *s, X86DecodedInsn *decode)
4224 fn = s->prefix & PREFIX_DATA ? gen_helper_comisd : gen_helper_comiss;
4226 assume_cc_op(s, CC_OP_EFLAGS);
4229 static void gen_VCVTPD2PS(DisasContext *s, X86DecodedInsn *decode)
4231 if (s->vex_l) {
4238 static void gen_VCVTPS2PD(DisasContext *s, X86DecodedInsn *decode)
4240 if (s->vex_l) {
4247 static void gen_VCVTPS2PH(DisasContext *s, X86DecodedInsn *decode)
4249 gen_unary_imm_fp_sse(s, decode,
4257 gen_store_sse(s, decode, decode->op[0].offset);
4261 static void gen_VCVTSD2SS(DisasContext *s, X86DecodedInsn *decode)
4266 static void gen_VCVTSS2SD(DisasContext *s, X86DecodedInsn *decode)
4271 static void gen_VCVTSI2Sx(DisasContext *s, X86DecodedInsn *decode)
4273 int vec_len = vector_len(s, decode);
4281 if (s->prefix & PREFIX_REPNZ) {
4282 gen_helper_cvtsq2sd(tcg_env, OP_PTR0, s->T1);
4284 gen_helper_cvtsq2ss(tcg_env, OP_PTR0, s->T1);
4288 in = s->tmp2_i32;
4289 tcg_gen_trunc_tl_i32(in, s->T1);
4291 in = s->T1;
4294 if (s->prefix & PREFIX_REPNZ) {
4301 static inline void gen_VCVTtSx2SI(DisasContext *s, X86DecodedInsn *decode,
4310 if (s->prefix & PREFIX_REPNZ) {
4311 sd2sq(s->T0, tcg_env, OP_PTR2);
4313 ss2sq(s->T0, tcg_env, OP_PTR2);
4318 out = s->tmp2_i32;
4320 out = s->T0;
4322 if (s->prefix & PREFIX_REPNZ) {
4328 tcg_gen_extu_i32_tl(s->T0, out);
4339 static void gen_VCVTSx2SI(DisasContext *s, X86DecodedInsn *decode)
4341 gen_VCVTtSx2SI(s, decode,
4346 static void gen_VCVTTSx2SI(DisasContext *s, X86DecodedInsn *decode)
4348 gen_VCVTtSx2SI(s, decode,
4353 static void gen_VEXTRACTx128(DisasContext *s, X86DecodedInsn *decode)
4359 gen_sto_env_A0(s, src_ofs, false);
4365 static void gen_VEXTRACTPS(DisasContext *s, X86DecodedInsn *decode)
4367 gen_pextr(s, decode, MO_32);
4370 static void gen_vinsertps(DisasContext *s, X86DecodedInsn *decode)
4377 assert(!s->vex_l);
4383 gen_store_sse(s, decode, decode->op[1].offset);
4387 tcg_gen_st_i32(s->tmp2_i32, tcg_env,
4403 static void gen_VINSERTPS_r(DisasContext *s, X86DecodedInsn *decode)
4406 tcg_gen_ld_i32(s->tmp2_i32, tcg_env,
4408 gen_vinsertps(s, decode);
4411 static void gen_VINSERTPS_m(DisasContext *s, X86DecodedInsn *decode)
4413 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, s->mem_index, MO_LEUL);
4414 gen_vinsertps(s, decode);
4417 static void gen_VINSERTx128(DisasContext *s, X86DecodedInsn *decode)
4428 static inline void gen_maskmov(DisasContext *s, X86DecodedInsn *decode,
4431 if (!s->vex_l) {
4432 xmm(tcg_env, OP_PTR2, OP_PTR1, s->A0);
4434 ymm(tcg_env, OP_PTR2, OP_PTR1, s->A0);
4438 static void gen_VMASKMOVPD_st(DisasContext *s, X86DecodedInsn *decode)
4440 gen_maskmov(s, decode, gen_helper_vpmaskmovq_st_xmm, gen_helper_vpmaskmovq_st_ymm);
4443 static void gen_VMASKMOVPS_st(DisasContext *s, X86DecodedInsn *decode)
4445 gen_maskmov(s, decode, gen_helper_vpmaskmovd_st_xmm, gen_helper_vpmaskmovd_st_ymm);
4448 static void gen_VMOVHPx_ld(DisasContext *s, X86DecodedInsn *decode)
4450 gen_ldq_env_A0(s, decode->op[0].offset + offsetof(XMMReg, XMM_Q(1)));
4452 tcg_gen_ld_i64(s->tmp1_i64, tcg_env, decode->op[1].offset + offsetof(XMMReg, XMM_Q(0)));
4453 tcg_gen_st_i64(s->tmp1_i64, tcg_env, decode->op[0].offset + offsetof(XMMReg, XMM_Q(0)));
4457 static void gen_VMOVHPx_st(DisasContext *s, X86DecodedInsn *decode)
4459 gen_stq_env_A0(s, decode->op[2].offset + offsetof(XMMReg, XMM_Q(1)));
4462 static void gen_VMOVHPx(DisasContext *s, X86DecodedInsn *decode)
4465 tcg_gen_ld_i64(s->tmp1_i64, tcg_env, decode->op[2].offset + offsetof(XMMReg, XMM_Q(1)));
4466 tcg_gen_st_i64(s->tmp1_i64, tcg_env, decode->op[0].offset + offsetof(XMMReg, XMM_Q(1)));
4469 tcg_gen_ld_i64(s->tmp1_i64, tcg_env, decode->op[1].offset + offsetof(XMMReg, XMM_Q(0)));
4470 tcg_gen_st_i64(s->tmp1_i64, tcg_env, decode->op[0].offset + offsetof(XMMReg, XMM_Q(0)));
4474 static void gen_VMOVHLPS(DisasContext *s, X86DecodedInsn *decode)
4476 tcg_gen_ld_i64(s->tmp1_i64, tcg_env, decode->op[2].offset + offsetof(XMMReg, XMM_Q(1)));
4477 tcg_gen_st_i64(s->tmp1_i64, tcg_env, decode->op[0].offset + offsetof(XMMReg, XMM_Q(0)));
4479 tcg_gen_ld_i64(s->tmp1_i64, tcg_env, decode->op[1].offset + offsetof(XMMReg, XMM_Q(1)));
4480 tcg_gen_st_i64(s->tmp1_i64, tcg_env, decode->op[0].offset + offsetof(XMMReg, XMM_Q(1)));
4484 static void gen_VMOVLHPS(DisasContext *s, X86DecodedInsn *decode)
4486 tcg_gen_ld_i64(s->tmp1_i64, tcg_env, decode->op[2].offset);
4487 tcg_gen_st_i64(s->tmp1_i64, tcg_env, decode->op[0].offset + offsetof(XMMReg, XMM_Q(1)));
4489 tcg_gen_ld_i64(s->tmp1_i64, tcg_env, decode->op[1].offset + offsetof(XMMReg, XMM_Q(0)));
4490 tcg_gen_st_i64(s->tmp1_i64, tcg_env, decode->op[0].offset + offsetof(XMMReg, XMM_Q(0)));
4499 static void gen_VMOVLPx(DisasContext *s, X86DecodedInsn *decode)
4501 int vec_len = vector_len(s, decode);
4503 tcg_gen_ld_i64(s->tmp1_i64, tcg_env, decode->op[2].offset + offsetof(XMMReg, XMM_Q(0)));
4505 tcg_gen_st_i64(s->tmp1_i64, tcg_env, decode->op[0].offset + offsetof(XMMReg, XMM_Q(0)));
4508 static void gen_VMOVLPx_ld(DisasContext *s, X86DecodedInsn *decode)
4510 int vec_len = vector_len(s, decode);
4512 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ);
4514 tcg_gen_st_i64(s->tmp1_i64, OP_PTR0, offsetof(ZMMReg, ZMM_Q(0)));
4517 static void gen_VMOVLPx_st(DisasContext *s, X86DecodedInsn *decode)
4519 tcg_gen_ld_i64(s->tmp1_i64, OP_PTR2, offsetof(ZMMReg, ZMM_Q(0)));
4520 tcg_gen_qemu_st_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ);
4523 static void gen_VMOVSD_ld(DisasContext *s, X86DecodedInsn *decode)
4527 tcg_gen_qemu_ld_i64(s->tmp1_i64, s->A0, s->mem_index, MO_LEUQ);
4529 tcg_gen_st_i64(s->tmp1_i64, OP_PTR0, offsetof(ZMMReg, ZMM_Q(0)));
4532 static void gen_VMOVSS(DisasContext *s, X86DecodedInsn *decode)
4534 int vec_len = vector_len(s, decode);
4536 tcg_gen_ld_i32(s->tmp2_i32, OP_PTR2, offsetof(ZMMReg, ZMM_L(0)));
4538 tcg_gen_st_i32(s->tmp2_i32, OP_PTR0, offsetof(ZMMReg, ZMM_L(0)));
4541 static void gen_VMOVSS_ld(DisasContext *s, X86DecodedInsn *decode)
4543 int vec_len = vector_len(s, decode);
4545 tcg_gen_qemu_ld_i32(s->tmp2_i32, s->A0, s->mem_index, MO_LEUL);
4547 tcg_gen_st_i32(s->tmp2_i32, OP_PTR0, offsetof(ZMMReg, ZMM_L(0)));
4550 static void gen_VMOVSS_st(DisasContext *s, X86DecodedInsn *decode)
4552 tcg_gen_ld_i32(s->tmp2_i32, OP_PTR2, offsetof(ZMMReg, ZMM_L(0)));
4553 tcg_gen_qemu_st_i32(s->tmp2_i32, s->A0, s->mem_index, MO_LEUL);
4556 static void gen_VPMASKMOV_st(DisasContext *s, X86DecodedInsn *decode)
4558 if (s->vex_w) {
4559 gen_VMASKMOVPD_st(s, decode);
4561 gen_VMASKMOVPS_st(s, decode);
4565 static void gen_VPERMD(DisasContext *s, X86DecodedInsn *decode)
4567 assert(s->vex_l);
4571 static void gen_VPERM2x128(DisasContext *s, X86DecodedInsn *decode)
4574 assert(s->vex_l);
4578 static void gen_VPHMINPOSUW(DisasContext *s, X86DecodedInsn *decode)
4580 assert(!s->vex_l);
4584 static void gen_VROUNDSD(DisasContext *s, X86DecodedInsn *decode)
4587 assert(!s->vex_l);
4591 static void gen_VROUNDSS(DisasContext *s, X86DecodedInsn *decode)
4594 assert(!s->vex_l);
4598 static void gen_VSHUF(DisasContext *s, X86DecodedInsn *decode)
4602 ps = s->vex_l ? gen_helper_shufps_ymm : gen_helper_shufps_xmm;
4603 pd = s->vex_l ? gen_helper_shufpd_ymm : gen_helper_shufpd_xmm;
4604 fn = s->prefix & PREFIX_DATA ? pd : ps;
4608 static void gen_VUCOMI(DisasContext *s, X86DecodedInsn *decode)
4611 fn = s->prefix & PREFIX_DATA ? gen_helper_ucomisd : gen_helper_ucomiss;
4613 assume_cc_op(s, CC_OP_EFLAGS);
4616 static void gen_VZEROALL(DisasContext *s, X86DecodedInsn *decode)
4625 static void gen_VZEROUPPER(DisasContext *s, X86DecodedInsn *decode)
4635 static void gen_WAIT(DisasContext *s, X86DecodedInsn *decode)
4637 if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) == (HF_MP_MASK | HF_TS_MASK)) {
4638 gen_NM_exception(s);
4641 translator_io_start(&s->base);
4647 static void gen_WRMSR(DisasContext *s, X86DecodedInsn *decode)
4649 gen_update_cc_op(s);
4650 gen_update_eip_cur(s);
4652 s->base.is_jmp = DISAS_EOB_NEXT;
4658 static void gen_WRxxBASE(DisasContext *s, X86DecodedInsn *decode)
4660 TCGv base = cpu_seg_base[s->modrm & 8 ? R_GS : R_FS];
4664 tcg_gen_mov_tl(base, s->T0);
4667 static void gen_XADD(DisasContext *s, X86DecodedInsn *decode)
4672 decode->cc_src = s->T1;
4675 if (s->prefix & PREFIX_LOCK) {
4676 tcg_gen_atomic_fetch_add_tl(s->T0, s->A0, s->T1, s->mem_index, ot | MO_LE);
4677 tcg_gen_add_tl(decode->cc_dst, s->T0, s->T1);
4679 tcg_gen_add_tl(decode->cc_dst, s->T0, s->T1);
4684 gen_writeback(s, decode, 0, decode->cc_dst);
4687 gen_writeback(s, decode, 2, s->T0);
4691 static void gen_XCHG(DisasContext *s, X86DecodedInsn *decode)
4693 if (s->prefix & PREFIX_LOCK) {
4694 tcg_gen_atomic_xchg_tl(s->T0, s->A0, s->T1,
4695 s->mem_index, decode->op[0].ot | MO_LE);
4697 gen_op_mov_reg_v(s, decode->op[2].ot, decode->op[2].n, s->T0);
4700 gen_op_mov_reg_v(s, decode->op[2].ot, decode->op[2].n, s->T0);
4701 tcg_gen_mov_tl(s->T0, s->T1);
4705 static void gen_XLAT(DisasContext *s, X86DecodedInsn *decode)
4707 /* AL is already zero-extended into s->T0. */
4708 tcg_gen_add_tl(s->A0, cpu_regs[R_EBX], s->T0);
4709 gen_lea_v_seg(s, s->A0, R_DS, s->override);
4710 gen_op_ld_v(s, MO_8, s->T0, s->A0);
4713 static void gen_XOR(DisasContext *s, X86DecodedInsn *decode)
4719 tcg_gen_movi_tl(s->T0, 0);
4725 if (s->prefix & PREFIX_LOCK) {
4726 tcg_gen_atomic_xor_fetch_tl(s->T0, s->A0, s->T1,
4727 s->mem_index, ot | MO_LE);
4729 tcg_gen_xor_tl(s->T0, s->T0, s->T1);
4731 prepare_update1_cc(decode, s, CC_OP_LOGICB + ot);
4735 static void gen_XRSTOR(DisasContext *s, X86DecodedInsn *decode)
4740 gen_helper_xrstor(tcg_env, s->A0, features);
4741 if (s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_MPX) {
4746 s->base.is_jmp = DISAS_EOB_NEXT;
4750 static void gen_XSAVE(DisasContext *s, X86DecodedInsn *decode)
4755 gen_helper_xsave(tcg_env, s->A0, features);
4758 static void gen_XSAVEOPT(DisasContext *s, X86DecodedInsn *decode)
4763 gen_helper_xsave(tcg_env, s->A0, features);