Lines Matching +full:- +full:s
2 * New-style TCG opcode generator for i386 instructions
24 * The exact opcode to check depends on 32- vs. 64-bit.
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)
83 AddressParts *mem = &decode->mem;
86 ea = gen_lea_modrm_1(s, *mem, decode->e.vex_class == 12);
87 if (decode->e.special == X86_SPECIAL_BitTest) {
88 MemOp ot = decode->op[1].ot;
90 int opn = decode->op[2].n;
94 assert(decode->op[2].unit == X86_OP_INT && decode->op[2].ot != MO_8);
95 tcg_gen_sextract_tl(ofs, cpu_regs[opn], 3, poslen - 3);
96 tcg_gen_andi_tl(ofs, ofs, -1 << ot);
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);
142 assert(op->unit == X86_OP_MMX || op->unit == X86_OP_SSE);
144 if (op->unit == X86_OP_MMX) {
145 return op->offset - mmx_offset(op->ot);
147 return op->offset - xmm_offset(op->ot);
156 if (op->unit == X86_OP_MMX) {
162 if (op->unit == X86_OP_MMX) {
168 if (op->unit == X86_OP_MMX) {
174 if (op->unit == X86_OP_MMX) {
180 assert(op->unit == X86_OP_SSE);
183 assert(op->unit == X86_OP_SSE);
192 if (!op->has_ea) {
193 op->offset = MMX_OFFSET(op->n) + mmx_offset(op->ot);
195 op->offset = offsetof(CPUX86State, mmx_t0) + mmx_offset(op->ot);
201 if (!op->has_ea) {
202 op->offset = ZMM_OFFSET(op->n) + xmm_offset(op->ot);
204 op->offset = offsetof(CPUX86State, xmm_t0) + xmm_offset(op->ot);
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)
239 switch (decode->e.vex_class) {
242 if ((s->prefix & PREFIX_VEX) ||
243 decode->e.vex_special == X86_VEX_SSEUnaligned) {
256 static void gen_load(DisasContext *s, X86DecodedInsn *decode, int opn, TCGv v)
258 X86DecodedOp *op = &decode->op[opn];
260 switch (op->unit) {
265 offsetof(CPUX86State,segs[op->n].selector));
269 if (op->n == 8) {
270 translator_io_start(&s->base);
273 tcg_gen_ld_tl(v, tcg_env, offsetof(CPUX86State, cr[op->n]));
278 gen_helper_get_dr(v, tcg_env, tcg_constant_i32(op->n));
282 if (op->has_ea) {
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) {
291 tcg_gen_sextract_tl(v, cpu_regs[op->n - 4], 8, 8);
293 tcg_gen_extract_tl(v, cpu_regs[op->n - 4], 8, 8);
296 } else if (op->ot < MO_TL && v == s->T0 &&
297 (decode->e.special == X86_SPECIAL_SExtT0 ||
298 decode->e.special == X86_SPECIAL_ZExtT0)) {
299 if (decode->e.special == X86_SPECIAL_SExtT0) {
300 tcg_gen_ext_tl(v, cpu_regs[op->n], op->ot | MO_SIGN);
302 tcg_gen_ext_tl(v, cpu_regs[op->n], op->ot);
306 tcg_gen_mov_tl(v, cpu_regs[op->n]);
310 tcg_gen_movi_tl(v, op->imm);
320 if (op->has_ea) {
321 bool aligned = sse_needs_alignment(s, decode, op->ot);
322 gen_load_sse(s, v, op->ot, op->offset, aligned);
333 X86DecodedOp *op = &decode->op[opn];
335 assert(op->unit == X86_OP_MMX || op->unit == X86_OP_SSE);
336 if (op->v_ptr) {
337 return op->v_ptr;
339 op->v_ptr = tcg_temp_new_ptr();
342 tcg_gen_addi_ptr(op->v_ptr, tcg_env, vector_reg_offset(op));
343 return op->v_ptr;
350 static void gen_writeback(DisasContext *s, X86DecodedInsn *decode, int opn, TCGv v)
352 X86DecodedOp *op = &decode->op[opn];
353 switch (op->unit) {
358 gen_movl_seg(s, op->n, s->T0);
361 if (op->has_ea) {
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) {
372 offsetof(CPUX86State, xmm_regs[op->n].ZMM_X(1)),
378 if (op->n == 8) {
379 translator_io_start(&s->base);
381 gen_helper_write_crN(tcg_env, tcg_constant_i32(op->n), v);
382 s->base.is_jmp = DISAS_EOB_NEXT;
386 gen_helper_set_dr(tcg_env, tcg_constant_i32(op->n), v);
387 s->base.is_jmp = DISAS_EOB_NEXT;
393 op->unit = X86_OP_SKIP;
396 static inline int vector_len(DisasContext *s, X86DecodedInsn *decode)
398 if (decode->e.special == X86_SPECIAL_MMX &&
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;
408 decode->cc_op = op;
411 static void prepare_update2_cc(X86DecodedInsn *decode, DisasContext *s, CCOp op)
413 decode->cc_src = s->T1;
414 decode->cc_dst = s->T0;
415 decode->cc_op = op;
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)
426 decode->cc_src2 = reg;
427 decode->cc_src = s->T1;
428 decode->cc_dst = s->T0;
429 decode->cc_op = op;
432 /* Set up decode->cc_* to modify CF while keeping other flags unchanged. */
433 static void prepare_update_cf(X86DecodedInsn *decode, DisasContext *s, TCGv cf)
435 switch (s->cc_op) {
438 decode->cc_src2 = cpu_cc_src2;
439 decode->cc_src = cpu_cc_src;
440 decode->cc_op = CC_OP_ADCOX;
445 decode->cc_src = cpu_cc_src;
446 decode->cc_op = CC_OP_ADCX;
450 decode->cc_src = tcg_temp_new();
451 gen_mov_eflags(s, decode->cc_src);
452 decode->cc_op = CC_OP_ADCX;
455 decode->cc_dst = cf;
458 static void gen_store_sse(DisasContext *s, X86DecodedInsn *decode, int src_ofs)
460 MemOp ot = decode->op[0].ot;
461 int vec_len = vector_len(s, decode);
462 bool aligned = sse_needs_alignment(s, decode, ot);
464 if (!decode->op[0].has_ea) {
465 tcg_gen_gvec_mov(MO_64, decode->op[0].offset, src_ofs, vec_len, vec_len);
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)
519 uint8_t b = decode->immediate;
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,
783 TCGv_i32 imm = tcg_constant8u_i32(decode->immediate);
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); \
814 func(__VA_ARGS__, decode->op[0].offset, \
815 decode->op[2].offset, vec_len, vec_len); \
828 static void gen_##uname(DisasContext *s, X86DecodedInsn *decode) \
830 int vec_len = vector_len(s, decode); \
833 decode->op[0].offset, decode->op[1].offset, \
834 decode->op[2].offset, vec_len, vec_len); \
887 static inline void gen_binary_int_sse(DisasContext *s, X86DecodedInsn *decode,
890 assert(!!mmx == !!(decode->e.special == X86_SPECIAL_MMX));
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,
1043 TCGv_i32 imm = tcg_constant8u_i32(decode->immediate);
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,
1070 TCGv_i32 imm = tcg_constant8u_i32(decode->immediate);
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;
1099 /* VEX.W affects whether to operate on 32- or 64-bit elements. */
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;
1120 TCGv_i32 scale = tcg_constant_i32(decode->mem.scale);
1124 tcg_gen_addi_ptr(index, tcg_env, ZMM_OFFSET(decode->mem.index));
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) {
1132 int ymmh_ofs = vector_elem_offset(&decode->op[1], MO_128, 1);
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)
1161 if (decode->immediate == 0) {
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)
1178 MemOp ot = decode->op[1].ot;
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)
1195 MemOp ot = decode->op[0].ot;
1197 TCGv *carry_out = (cc_op == CC_OP_ADCX ? &decode->cc_dst : &decode->cc_src2);
1200 decode->cc_op = cc_op;
1202 if (CC_OP_HAS_EFLAGS(s->cc_op)) {
1203 decode->cc_src = cpu_cc_src;
1205 /* Re-use the carry-out from a previous round? */
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) {
1212 decode->cc_op = CC_OP_ADCOX;
1213 if (carry_out == &decode->cc_dst) {
1214 decode->cc_src2 = cpu_cc_src2;
1216 decode->cc_dst = cpu_cc_dst;
1220 decode->cc_src = tcg_temp_new();
1221 gen_mov_eflags(s, decode->cc_src);
1227 tcg_gen_extract_tl(carry_in, decode->cc_src,
1234 /* If TL is 64-bit just do everything in 64-bit arithmetic. */
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)
1257 MemOp ot = decode->op[1].ot;
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)
1275 MemOp ot = decode->op[1].ot;
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)
1288 MemOp ot = decode->op[0].ot;
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);
1311 decode->cc_src = flags;
1312 decode->cc_op = CC_OP_EFLAGS;
1315 static void gen_BEXTR(DisasContext *s, X86DecodedInsn *decode)
1317 MemOp ot = decode->op[0].ot;
1320 TCGv mone = tcg_constant_tl(-1);
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)
1345 MemOp ot = decode->op[0].ot;
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)
1355 MemOp ot = decode->op[0].ot;
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)
1365 MemOp ot = decode->op[0].ot;
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);
1377 if (decode->op[1].ot == MO_16) {
1378 gen_helper_boundw(tcg_env, s->A0, op);
1380 gen_helper_boundl(tcg_env, s->A0, op);
1384 /* Non-standard convention - on entry T0 is zero-extended input, T1 is the output. */
1385 static void gen_BSF(DisasContext *s, X86DecodedInsn *decode)
1387 MemOp ot = decode->op[0].ot;
1390 decode->cc_dst = tcg_temp_new();
1391 decode->cc_op = CC_OP_LOGICB + ot;
1392 tcg_gen_mov_tl(decode->cc_dst, s->T0);
1400 tcg_gen_ctz_tl(s->T0, s->T0, s->T1);
1403 /* Non-standard convention - on entry T0 is zero-extended input, T1 is the output. */
1404 static void gen_BSR(DisasContext *s, X86DecodedInsn *decode)
1406 MemOp ot = decode->op[0].ot;
1409 decode->cc_dst = tcg_temp_new();
1410 decode->cc_op = CC_OP_LOGICB + ot;
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)
1438 MemOp ot = decode->op[1].ot;
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);
1462 * Z was going to be computed from the non-zero status of CC_DST.
1467 decode->cc_src = tcg_temp_new();
1468 decode->cc_dst = cpu_cc_dst;
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)
1483 MemOp ot = decode->op[0].ot;
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)
1499 MemOp ot = decode->op[0].ot;
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)
1517 MemOp ot = decode->op[0].ot;
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)
1533 MemOp ot = decode->op[0].ot;
1536 TCGv mone = tcg_constant_tl(-1);
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)
1570 MemOp ot = decode->op[1].ot;
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)
1580 MemOp src_ot = decode->op[0].ot - 1;
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)
1631 int jcc_op = (decode->b >> 1) & 7;
1638 [JCC_P] = TCG_COND_TSTEQ, /* even parity - tests low bit of popcount */
1644 if (decode->b & 1) {
1648 ot = decode->op[0].ot;
1652 * Sign-extend values before subtracting for S, P (zero/sign extension
1662 tcg_gen_ext_tl(cmpv, cpu_regs[decode->op[1].n], ot_full);
1666 * - s->T1: addition operand (from decoder)
1667 * - s->A0: dest address (from decoder)
1668 * - s->cc_srcT: memory operand (lhs for comparison)
1669 * - cmpv: rhs 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;
1718 decode->cc_src = cmpv;
1719 decode->cc_op = CC_OP_SUBB + ot;
1722 static void gen_CMPS(DisasContext *s, X86DecodedInsn *decode)
1724 MemOp ot = decode->op[2].ot;
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)
1734 MemOp ot = decode->op[2].ot;
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);
1747 if (decode->op[0].has_ea) {
1755 gen_op_st_v(s, ot, newv, s->A0);
1761 * not zero-extending it on 64-bit processors. So, precompute
1766 dest = gen_op_deposit_reg_v(s, ot, decode->op[0].n, newv, newv);
1769 decode->op[0].unit = X86_OP_SKIP;
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);
1778 decode->cc_dst = cmpv;
1779 decode->cc_src = oldv;
1780 decode->cc_op = CC_OP_SUBB + ot;
1783 static void gen_CMPXCHG16B(DisasContext *s, X86DecodedInsn *decode)
1795 /* Only require atomic with LOCK; non-parallel handled in generator. */
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)
1841 /* Only require atomic with LOCK; non-parallel handled in generator. */
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);
1856 * For 32-bit, we may do this unconditionally, because on success (Z=1),
1859 * registers unchanged on success, and zero-extend the writeback
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)
1888 MemOp ot = decode->op[2].ot;
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)
1926 int shift = 8 << decode->op[0].ot;
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)
1947 MemOp ot = decode->op[1].ot;
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)
1961 MemOp ot = decode->op[1].ot;
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)
1994 TCGv_i32 length = tcg_constant_i32(decode->immediate & 63);
1995 TCGv_i32 index = tcg_constant_i32((decode->immediate >> 8) & 63);
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)
2035 MemOp ot = decode->op[1].ot;
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)
2058 MemOp ot = decode->op[0].ot;
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;
2076 * but it requires a 64-bit multiply even if they are not. Use it
2077 * only if the target has 64-bits registers.
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;
2087 /* Variant that only needs a 32-bit widening multiply. */
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)
2121 MemOp ot = decode->op[1].ot;
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)
2179 MemOp ot = decode->op[0].ot;
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)
2195 MemOp ot = decode->op[1].ot;
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)
2209 MemOp ot = decode->op[1].ot;
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)
2229 TCGv_i32 length = tcg_constant_i32(decode->immediate & 63);
2230 TCGv_i32 index = tcg_constant_i32((decode->immediate >> 8) & 63);
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)
2312 MemOp ot = decode->op[1].ot;
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)
2333 MemOp ot = decode->op[0].ot;
2337 gen_compute_eflags(s);
2338 gen_update_cc_op(s);
2339 gen_helper_lar(result, tcg_env, s->T0);
2342 decode->op[0].unit = X86_OP_SKIP;
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)
2356 MemOp ot = decode->op[0].ot;
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)
2404 MemOp ot = decode->op[1].ot;
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)
2448 MemOp ot = decode->op[0].ot;
2452 gen_compute_eflags(s);
2453 gen_update_cc_op(s);
2454 gen_helper_lsl(result, tcg_env, s->T0);
2457 decode->op[0].unit = X86_OP_SKIP;
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)
2470 MemOp ot = decode->op[0].ot;
2473 decode->cc_src = tcg_temp_new();
2474 decode->cc_dst = s->T0;
2475 decode->cc_op = CC_OP_BMILGB + ot;
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)
2510 MemOp ot = decode->op[0].ot;
2513 if (decode->e.op0 == X86_TYPE_M) {
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)
2522 MemOp ot = decode->op[2].ot;
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)
2540 MemOp ot = decode->op[2].ot;
2541 int vec_len = vector_len(s, decode);
2542 int lo_ofs = vector_elem_offset(&decode->op[0], ot, 0);
2544 tcg_gen_gvec_dup_imm(MO_64, decode->op[0].offset, vec_len, vec_len, 0);
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);
2578 int lo_ofs = vector_elem_offset(&decode->op[0], MO_64, 0);
2580 tcg_gen_ld_i64(s->tmp1_i64, tcg_env, decode->op[2].offset);
2581 if (decode->op[0].has_ea) {
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
2586 * seem to work, but it does not on big-endian platforms; the cleared parts
2587 * are always at higher addresses, but cross-endian emulation inverts the
2592 tcg_gen_gvec_dup_imm(MO_64, decode->op[0].offset, vec_len, vec_len, 0);
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)
2606 MemOp ot = decode->op[2].ot;
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)
2616 MemOp ot = decode->op[1].ot;
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);
2647 decode->cc_dst = cpu_regs[R_EAX];
2648 decode->cc_src = cpu_regs[R_EDX];
2653 tcg_gen_mulu2_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->T0, s->T1);
2654 decode->cc_dst = cpu_regs[R_EAX];
2655 decode->cc_src = cpu_regs[R_EDX];
2662 decode->cc_op = CC_OP_MULB + ot;
2665 static void gen_MULX(DisasContext *s, X86DecodedInsn *decode)
2667 MemOp ot = decode->op[0].ot;
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)
2693 MemOp ot = decode->op[0].ot;
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;
2713 decode->cc_src = oldv;
2714 tcg_gen_movi_tl(s->cc_srcT, 0);
2715 decode->cc_op = CC_OP_SUBB + ot;
2718 static void gen_NOT(DisasContext *s, X86DecodedInsn *decode)
2720 MemOp ot = decode->op[0].ot;
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)
2733 MemOp ot = decode->op[1].ot;
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)
2746 MemOp ot = decode->op[1].ot;
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)
2763 MemOp ot = decode->op[1].ot;
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)
2782 TCGv_i32 imm = tcg_constant8u_i32(decode->immediate);
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);
2798 decode->op[0].offset, decode->op[2].offset,
2799 decode->op[1].offset, vec_len, vec_len);
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)
2812 TCGv_i32 imm = tcg_constant8u_i32(decode->immediate);
2814 assume_cc_op(s, CC_OP_EFLAGS);
2817 static void gen_PCMPESTRM(DisasContext *s, X86DecodedInsn *decode)
2819 TCGv_i32 imm = tcg_constant8u_i32(decode->immediate);
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)
2830 TCGv_i32 imm = tcg_constant8u_i32(decode->immediate);
2832 assume_cc_op(s, CC_OP_EFLAGS);
2835 static void gen_PCMPISTRM(DisasContext *s, X86DecodedInsn *decode)
2837 TCGv_i32 imm = tcg_constant8u_i32(decode->immediate);
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);
2859 int mask = (vec_len >> ot) - 1;
2860 int val = decode->immediate & mask;
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)
2894 MemOp ot = decode->op[0].ot;
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);
2901 int mask = (vec_len >> ot) - 1;
2902 int val = decode->immediate & mask;
2904 if (decode->op[1].offset != decode->op[0].offset) {
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)
2991 MemOp ot = decode->op[2].ot;
2992 int vec_len = vector_len(s, decode);
2995 tcg_gen_gvec_2(offsetof(CPUX86State, xmm_t0) + xmm_offset(ot), decode->op[2].offset,
2997 tcg_gen_ld8u_tl(s->T0, tcg_env, offsetof(CPUX86State, xmm_t0.ZMM_B(vec_len - 1)));
2999 vec_len -= 8;
3007 tcg_gen_ld_tl(t, tcg_env, offsetof(CPUX86State, xmm_t0.ZMM_Q((vec_len - 1) / 8)));
3009 tcg_gen_ld_tl(t, tcg_env, offsetof(CPUX86State, xmm_t0.ZMM_L((vec_len - 1) / 4)));
3012 tcg_gen_extract2_tl(s->T0, t, s->T0, TARGET_LONG_BITS - 8);
3019 tcg_gen_ld8u_tl(t, tcg_env, offsetof(CPUX86State, xmm_t0.ZMM_B(vec_len - 1)));
3020 tcg_gen_deposit_tl(s->T0, t, s->T0, 8, TARGET_LONG_BITS - 8);
3025 static void gen_POP(DisasContext *s, X86DecodedInsn *decode)
3027 X86DecodedOp *op = &decode->op[0];
3028 MemOp ot = gen_pop_T0(s);
3030 assert(ot >= op->ot);
3031 if (op->has_ea || op->unit == X86_OP_SEG) {
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)
3047 decode->cc_dst = tcg_temp_new();
3048 decode->cc_op = CC_OP_POPCNT;
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)
3078 TCGv_i32 imm = tcg_constant8u_i32(decode->immediate);
3082 static void gen_PSRLW_i(DisasContext *s, X86DecodedInsn *decode)
3084 int vec_len = vector_len(s, decode);
3086 if (decode->immediate >= 16) {
3087 tcg_gen_gvec_dup_imm(MO_64, decode->op[0].offset, vec_len, vec_len, 0);
3090 decode->op[0].offset, decode->op[1].offset,
3091 decode->immediate, vec_len, vec_len);
3095 static void gen_PSLLW_i(DisasContext *s, X86DecodedInsn *decode)
3097 int vec_len = vector_len(s, decode);
3099 if (decode->immediate >= 16) {
3100 tcg_gen_gvec_dup_imm(MO_64, decode->op[0].offset, vec_len, vec_len, 0);
3103 decode->op[0].offset, decode->op[1].offset,
3104 decode->immediate, vec_len, vec_len);
3108 static void gen_PSRAW_i(DisasContext *s, X86DecodedInsn *decode)
3110 int vec_len = vector_len(s, decode);
3112 if (decode->immediate >= 16) {
3113 decode->immediate = 15;
3116 decode->op[0].offset, decode->op[1].offset,
3117 decode->immediate, vec_len, vec_len);
3120 static void gen_PSRLD_i(DisasContext *s, X86DecodedInsn *decode)
3122 int vec_len = vector_len(s, decode);
3124 if (decode->immediate >= 32) {
3125 tcg_gen_gvec_dup_imm(MO_64, decode->op[0].offset, vec_len, vec_len, 0);
3128 decode->op[0].offset, decode->op[1].offset,
3129 decode->immediate, vec_len, vec_len);
3133 static void gen_PSLLD_i(DisasContext *s, X86DecodedInsn *decode)
3135 int vec_len = vector_len(s, decode);
3137 if (decode->immediate >= 32) {
3138 tcg_gen_gvec_dup_imm(MO_64, decode->op[0].offset, vec_len, vec_len, 0);
3141 decode->op[0].offset, decode->op[1].offset,
3142 decode->immediate, vec_len, vec_len);
3146 static void gen_PSRAD_i(DisasContext *s, X86DecodedInsn *decode)
3148 int vec_len = vector_len(s, decode);
3150 if (decode->immediate >= 32) {
3151 decode->immediate = 31;
3154 decode->op[0].offset, decode->op[1].offset,
3155 decode->immediate, vec_len, vec_len);
3158 static void gen_PSRLQ_i(DisasContext *s, X86DecodedInsn *decode)
3160 int vec_len = vector_len(s, decode);
3162 if (decode->immediate >= 64) {
3163 tcg_gen_gvec_dup_imm(MO_64, decode->op[0].offset, vec_len, vec_len, 0);
3166 decode->op[0].offset, decode->op[1].offset,
3167 decode->immediate, vec_len, vec_len);
3171 static void gen_PSLLQ_i(DisasContext *s, X86DecodedInsn *decode)
3173 int vec_len = vector_len(s, decode);
3175 if (decode->immediate >= 64) {
3176 tcg_gen_gvec_dup_imm(MO_64, decode->op[0].offset, vec_len, vec_len, 0);
3179 decode->op[0].offset, decode->op[1].offset,
3180 decode->immediate, vec_len, vec_len);
3198 static void gen_PSRLDQ_i(DisasContext *s, X86DecodedInsn *decode)
3200 int vec_len = vector_len(s, decode);
3201 TCGv_ptr imm_vec = make_imm8u_xmm_vec(decode->immediate, vec_len);
3203 if (s->vex_l) {
3210 static void gen_PSLLDQ_i(DisasContext *s, X86DecodedInsn *decode)
3212 int vec_len = vector_len(s, decode);
3213 TCGv_ptr imm_vec = make_imm8u_xmm_vec(decode->immediate, vec_len);
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,
3242 MemOp ot = decode->op[0].ot;
3254 if ((decode->immediate & mask) == 0) {
3259 tcg_gen_movi_tl(*count, decode->immediate & mask);
3275 * Compute existing flags in decode->cc_src, for gen_* functions that wants
3277 * operations to compute the carry in decode->cc_dst and the overflow in
3278 * decode->cc_src2.
3280 * If need_flags is true, decode->cc_dst and decode->cc_src2 are preloaded
3284 * Return true if carry could be made available cheaply as a 1-bit value in
3285 * decode->cc_dst (trying a bit harder if want_carry is true). If false is
3286 * returned, decode->cc_dst is uninitialized and the carry is only available
3287 * as bit 0 of decode->cc_src.
3289 static bool gen_eflags_adcox(DisasContext *s, X86DecodedInsn *decode, bool want_carry, bool need_fl…
3294 decode->cc_dst = tcg_temp_new();
3295 decode->cc_src = tcg_temp_new();
3296 decode->cc_src2 = tcg_temp_new();
3297 decode->cc_op = CC_OP_ADCOX;
3303 switch (s->cc_op) {
3306 tcg_gen_mov_tl(decode->cc_src, cpu_cc_src);
3308 tcg_gen_mov_tl(decode->cc_src2, cpu_cc_src2);
3312 tcg_gen_mov_tl(decode->cc_dst, cpu_cc_dst);
3318 /* CF and OF are zero, do it just because it's easy. */
3319 gen_mov_eflags(s, decode->cc_src);
3321 tcg_gen_movi_tl(decode->cc_src2, 0);
3325 tcg_gen_movi_tl(decode->cc_dst, 0);
3337 tcg_gen_andi_tl(decode->cc_dst, cpu_cc_src, 1);
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);
3350 tcg_gen_shri_tl(decode->cc_dst, cpu_cc_src, (8 << size) - 1);
3353 gen_mov_eflags(s, decode->cc_src);
3357 gen_mov_eflags(s, decode->cc_src);
3364 tcg_gen_extract_tl(decode->cc_src2, decode->cc_src, ctz32(CC_O), 1);
3368 tcg_gen_extract_tl(decode->cc_dst, decode->cc_src, ctz32(CC_C), 1);
3378 MemOp ot = decode->op[0].ot;
3379 TCGv temp = can_be_zero ? tcg_temp_new() : decode->cc_src2;
3382 tcg_gen_extract_tl(temp, temp, (8 << ot) - 1, 1);
3384 tcg_gen_movcond_tl(TCG_COND_EQ, decode->cc_src2, count, tcg_constant_tl(0),
3385 decode->cc_src2, temp);
3390 * RCx operations are invariant modulo 8*operand_size+1. For 8 and 16-bit operands,
3421 * from a right shifted part and a left shifted part of s->T0. The new carry
3422 * is extracted from the right-shifted portion, and the old carry is
3423 * inserted at the end of the left-shifted portion.
3426 * mostly operate on count-1. This also comes in handy when computing
3427 * length - count, because (length-1) - (count-1) can be computed with
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);
3454 if (!have_1bit_cin || TCG_TARGET_deposit_tl_valid(1, TARGET_LONG_BITS - 1)) {
3456 TCGv cin = have_1bit_cin ? decode->cc_dst : decode->cc_src;
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 */
3467 tcg_gen_xori_tl(low_count, count, (8 << ot) - 1); /* LENGTH - 1 - (count - 1) */
3468 tcg_gen_shr_tl(low, s->T0, low_count);
3469 tcg_gen_andi_tl(decode->cc_dst, low, 1);
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);
3506 if (!have_1bit_cin || TCG_TARGET_deposit_tl_valid(1, TARGET_LONG_BITS - 1)) {
3507 TCGv cin = have_1bit_cin ? decode->cc_dst : decode->cc_src;
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);
3518 tcg_gen_andi_tl(decode->cc_dst, low, 1);
3522 tcg_gen_xori_tl(high_count, count, (8 << ot) - 1); /* LENGTH - 1 - (count - 1) */
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)
3581 int16_t adjust = decode->e.op1 == X86_TYPE_I ? decode->immediate : 0;
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)
3592 int16_t adjust = decode->e.op1 == X86_TYPE_I ? decode->immediate : 0;
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;
3617 * Return non-NULL if a 32-bit rotate works, after possibly replicating the input.
3618 * The input has already been zero-extended upon operand decode.
3652 tcg_gen_extract_tl(decode->cc_dst, result, bit, 1);
3656 tcg_gen_movcond_tl(TCG_COND_EQ, decode->cc_dst, count, tcg_constant_tl(0),
3657 decode->cc_dst, temp);
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)
3720 MemOp ot = decode->op[0].ot;
3722 int b = decode->immediate & mask;
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)
3776 decode->cc_op = CC_OP_DYNAMIC;
3777 decode->cc_op_dynamic = tcg_temp_new_i32();
3779 assert(decode->cc_dst == s->T0);
3780 if (cc_op_live(s->cc_op) & USES_CC_DST) {
3781 decode->cc_dst = tcg_temp_new();
3782 tcg_gen_movcond_tl(TCG_COND_EQ, decode->cc_dst, count, tcg_constant_tl(0),
3783 cpu_cc_dst, s->T0);
3786 if (cc_op_live(s->cc_op) & USES_CC_SRC) {
3787 tcg_gen_movcond_tl(TCG_COND_EQ, decode->cc_src, count, tcg_constant_tl(0),
3788 cpu_cc_src, decode->cc_src);
3792 if (s->cc_op == CC_OP_DYNAMIC) {
3795 old_cc_op = tcg_constant_i32(s->cc_op);
3797 tcg_gen_movcond_i32(TCG_COND_EQ, decode->cc_op_dynamic, count32, tcg_constant_i32(0),
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;
3812 decode->cc_src = tcg_temp_new();
3813 tcg_gen_subi_tl(decode->cc_src, count, 1);
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);
3819 decode->cc_op = CC_OP_SARB + ot;
3823 static void gen_SARX(DisasContext *s, X86DecodedInsn *decode)
3825 MemOp ot = decode->op[0].ot;
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)
3835 MemOp ot = decode->op[0].ot;
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)
3857 MemOp ot = decode->op[2].ot;
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)
3892 switch(decode->immediate & 3) {
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;
3940 decode->cc_src = tcg_temp_new();
3941 tcg_gen_subi_tl(decode->cc_src, count, 1);
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);
3947 decode->cc_op = CC_OP_SHLB + ot;
3951 static void gen_SHLD(DisasContext *s, X86DecodedInsn *decode)
3955 int unit = decode->e.op3 == X86_TYPE_I ? X86_OP_IMM : X86_OP_INT;
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);
3968 decode->cc_op = CC_OP_SHLB + ot;
3972 static void gen_SHLX(DisasContext *s, X86DecodedInsn *decode)
3974 MemOp ot = decode->op[0].ot;
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;
3993 decode->cc_src = tcg_temp_new();
3994 tcg_gen_subi_tl(decode->cc_src, count, 1);
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);
4000 decode->cc_op = CC_OP_SARB + ot;
4004 static void gen_SHRD(DisasContext *s, X86DecodedInsn *decode)
4008 int unit = decode->e.op3 == X86_TYPE_I ? X86_OP_IMM : X86_OP_INT;
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);
4021 decode->cc_op = CC_OP_SARB + ot;
4025 static void gen_SHRX(DisasContext *s, X86DecodedInsn *decode)
4027 MemOp ot = decode->op[0].ot;
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)
4043 tcg_gen_st_i32(tcg_constant_i32(-1), tcg_env, offsetof(CPUX86State, df));
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)
4054 TCGv_i32 imm = tcg_constant8u_i32(decode->immediate);
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)
4067 MemOp ot = decode->op[1].ot;
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)
4077 MemOp ot = decode->op[1].ot;
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)
4138 MemOp ot = decode->op[0].ot;
4141 decode->cc_src = tcg_temp_new();
4142 decode->cc_dst = s->T0;
4143 decode->cc_op = CC_OP_BMILGB + ot;
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,
4256 if (decode->op[0].has_ea) {
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);
4276 tcg_gen_gvec_mov(MO_64, decode->op[0].offset, decode->op[1].offset, vec_len, vec_len);
4279 MemOp ot = decode->op[2].ot;
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,
4308 MemOp ot = decode->op[0].ot;
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)
4355 int mask = decode->immediate & 1;
4356 int src_ofs = vector_elem_offset(&decode->op[1], MO_128, mask);
4357 if (decode->op[0].has_ea) {
4358 /* VEX-only instruction, no alignment requirements. */
4359 gen_sto_env_A0(s, src_ofs, false);
4361 tcg_gen_gvec_mov(MO_64, decode->op[0].offset, src_ofs, 16, 16);
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)
4372 int val = decode->immediate;
4377 assert(!s->vex_l);
4381 tcg_gen_gvec_dup_imm(MO_64, decode->op[0].offset, vec_len, vec_len, 0);
4382 } else if (decode->op[1].offset != decode->op[0].offset) {
4383 gen_store_sse(s, decode, decode->op[1].offset);
4387 tcg_gen_st_i32(s->tmp2_i32, tcg_env,
4388 vector_elem_offset(&decode->op[0], MO_32, dest_word));
4397 vector_elem_offset(&decode->op[0], MO_32, i));
4403 static void gen_VINSERTPS_r(DisasContext *s, X86DecodedInsn *decode)
4405 int val = decode->immediate;
4406 tcg_gen_ld_i32(s->tmp2_i32, tcg_env,
4407 vector_elem_offset(&decode->op[2], MO_32, (val >> 6) & 3));
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)
4419 int mask = decode->immediate & 1;
4421 decode->op[0].offset + offsetof(YMMReg, YMM_X(mask)),
4422 decode->op[2].offset + offsetof(YMMReg, YMM_X(0)), 16, 16);
4424 decode->op[0].offset + offsetof(YMMReg, YMM_X(!mask)),
4425 decode->op[1].offset + offsetof(YMMReg, YMM_X(!mask)), 16, 16);
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)));
4451 if (decode->op[0].offset != decode->op[1].offset) {
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)
4464 if (decode->op[0].offset != decode->op[2].offset) {
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)));
4468 if (decode->op[0].offset != decode->op[1].offset) {
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)));
4478 if (decode->op[0].offset != decode->op[1].offset) {
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)));
4488 if (decode->op[0].offset != decode->op[1].offset) {
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)));
4495 * Note that MOVLPx supports 256-bit operation unlike MOVHLPx, MOVLHPx, MOXHPx.
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)));
4504 tcg_gen_gvec_mov(MO_64, decode->op[0].offset, decode->op[1].offset, vec_len, vec_len);
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);
4513 tcg_gen_gvec_mov(MO_64, decode->op[0].offset, decode->op[1].offset, vec_len, vec_len);
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)));
4537 tcg_gen_gvec_mov(MO_64, decode->op[0].offset, decode->op[1].offset, vec_len, vec_len);
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);
4546 tcg_gen_gvec_dup_imm(MO_64, decode->op[0].offset, vec_len, vec_len, 0);
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)
4573 TCGv_i32 imm = tcg_constant8u_i32(decode->immediate);
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)
4586 TCGv_i32 imm = tcg_constant8u_i32(decode->immediate);
4587 assert(!s->vex_l);
4591 static void gen_VROUNDSS(DisasContext *s, X86DecodedInsn *decode)
4593 TCGv_i32 imm = tcg_constant8u_i32(decode->immediate);
4594 assert(!s->vex_l);
4598 static void gen_VSHUF(DisasContext *s, X86DecodedInsn *decode)
4600 TCGv_i32 imm = tcg_constant_i32(decode->immediate);
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)
4669 MemOp ot = decode->op[1].ot;
4671 decode->cc_dst = tcg_temp_new();
4672 decode->cc_src = s->T1;
4673 decode->cc_op = CC_OP_ADDB + ot;
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);
4686 if (decode->op[0].has_ea || decode->op[2].n != decode->op[0].n) {
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)
4716 if (decode->op[1].unit == X86_OP_INT &&
4717 decode->op[2].unit == X86_OP_INT &&
4718 decode->op[1].n == decode->op[2].n) {
4719 tcg_gen_movi_tl(s->T0, 0);
4720 decode->cc_op = CC_OP_EFLAGS;
4721 decode->cc_src = tcg_constant_tl(CC_Z | CC_P);
4723 MemOp ot = decode->op[1].ot;
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);